Move branches/martin/0.12 to trunk

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@3848 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2009-11-13 19:28:13 +00:00
commit 2005bc2e92
144 changed files with 2120 additions and 6011 deletions

9
NEWS
View File

@ -6,15 +6,8 @@ http://www.opensc-project.org/opensc/wiki/WhatsNew
Also see the svn changelog using svn command
or doc/nonpersistent/ChangeLog.
New in 0.11.11-rc2; 2009-10-24; Andreas Jellinghaus
* Now again compatible with OpenSSL 0.9.7 and OpenSSL 1.0.0
* A few warnings and minor bugs were fixed
* Updated myeid driver by Aventra
New in 0.11.10; 2009-10-20; Andreas Jellinghaus
New in 0.??.==; 200?-??-??; ??
* New westcos driver by François Leblanc
* Initial support for MyEid card (Aventra)
* GOST algorithm supported by Rutoken driver (Aleksey Samsonov)
New in 0.11.9; 2009-07-29; Andreas Jellinghaus
* New rutoken_ecp driver by Aktiv Co. / Aleksey Samsonov

View File

@ -3,8 +3,8 @@ dnl -*- mode: m4; -*-
AC_PREREQ(2.60)
define([PACKAGE_VERSION_MAJOR], [0])
define([PACKAGE_VERSION_MINOR], [11])
define([PACKAGE_VERSION_FIX], [11])
define([PACKAGE_VERSION_MINOR], [12])
define([PACKAGE_VERSION_FIX], [0])
define([PACKAGE_SUFFIX], [-svn])
AC_INIT([opensc],[PACKAGE_VERSION_MAJOR.PACKAGE_VERSION_MINOR.PACKAGE_VERSION_FIX[]PACKAGE_SUFFIX])
@ -158,13 +158,6 @@ AC_ARG_ENABLE(
[enable_pcsc="yes"]
)
AC_ARG_ENABLE(
[nsplugin],
[AS_HELP_STRING([--enable-nsplugin],[enable nsplugin (signer) @<:@disabled@:>@])],
,
[enable_nsplugin="no"]
)
AC_ARG_ENABLE(
[man],
[AS_HELP_STRING([--disable-man],[disable installation of manuals @<:@enabled for none Windows@:>@])],
@ -206,13 +199,6 @@ AC_ARG_WITH(
[with_pcsc_provider="detect"]
)
AC_ARG_WITH(
[pinentry],
[AS_HELP_STRING([--with-pinentry=PROG],[run PROG as PIN-entry for OpenSC Signer @<:/usr/bin/gpinentry:>@])],
,
[with_pinentry="/usr/bin/gpinentry"]
)
dnl Checks for programs.
AC_PROG_CPP
AC_PROG_INSTALL
@ -300,7 +286,7 @@ AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([ \
errno.h fcntl.h malloc.h stdlib.h \
inttypes.h string.h strings.h \
sys/time.h unistd.h locale.h getopt.h
sys/time.h unistd.h locale.h getopt.h sys/mman.h
])
dnl Checks for typedefs, structures, and compiler characteristics.
@ -597,21 +583,6 @@ if test "${enable_pcsc}" = "yes"; then
AC_DEFINE([ENABLE_PCSC], [1], [Define if PC/SC is to be enabled])
fi
dnl AM_PATH_LIBASSUAN([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libassuan and define LIBASSUAN_CFLAGS and LIBASSUAN_LIBS
AM_PATH_LIBASSUAN(
,
[have_assuan="yes"],
[have_assuan="no"]
)
if test "${enable_nsplugin}" = "yes"; then
if test "x${have_assuan}" != "xyes" -o "x${have_openssl}" != "xyes"; then
AC_MSG_ERROR([nsplugin requires assuan and openssl])
fi
fi
OPENSC_FEATURES=""
if test "${enable_zlib}" = "yes"; then
OPENSC_FEATURES="${OPENSC_FEATURES} zlib"
@ -642,12 +613,10 @@ if test "${enable_pcsc}" = "yes"; then
OPENSC_FEATURES="${OPENSC_FEATURES} pcsc(${DEFAULT_PCSC_PROVIDER})"
OPTIONAL_PCSC_CFLAGS="${PCSC_CFLAGS}"
fi
test "${enable_nsplugin}" = "yes" && OPENSC_FEATURES="${OPENSC_FEATURES} nsplugin"
AC_DEFINE_UNQUOTED([OPENSC_VERSION_MAJOR], [${OPENSC_VERSION_MAJOR}], [OpenSC version major component])
AC_DEFINE_UNQUOTED([OPENSC_VERSION_MINOR], [${OPENSC_VERSION_MINOR}], [OpenSC version minor component])
AC_DEFINE_UNQUOTED([OPENSC_VERSION_FIX], [${OPENSC_VERSION_FIX}], [OpenSC version fix component])
test "${with_pinentry}" != "no" && AC_DEFINE_UNQUOTED([PIN_ENTRY], ["${with_pinentry}"], [PIN-entry program for OpenSC Signer])
AC_DEFINE_UNQUOTED([OPENSC_FEATURES], ["${OPENSC_FEATURES}"], [Enabled OpenSC features])
openscincludedir="\$(includedir)/opensc"
@ -687,7 +656,6 @@ AM_CONDITIONAL([ENABLE_READLINE], [test "${enable_readline}" = "yes"])
AM_CONDITIONAL([ENABLE_ICONV], [test "${enable_iconv}" = "yes"])
AM_CONDITIONAL([ENABLE_OPENSSL], [test "${enable_openssl}" = "yes"])
AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"])
AM_CONDITIONAL([ENABLE_NSPLUGIN], [test "${enable_nsplugin}" = "yes"])
AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"])
AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"])
@ -723,8 +691,6 @@ AC_CONFIG_FILES([
src/pkcs11/Makefile
src/pkcs15init/Makefile
src/scconf/Makefile
src/signer/Makefile
src/signer/npinclude/Makefile
src/tests/Makefile
src/tests/regression/Makefile
src/tools/Makefile
@ -751,10 +717,8 @@ iconv support: ${enable_iconv}
OpenSSL support: ${enable_openssl}
PC/SC support: ${enable_pcsc}
OpenCT support: ${enable_openct}
NSPlugin support: ${enable_nsplugin}
PC/SC default provider: ${DEFAULT_PCSC_PROVIDER}
pinentry: ${with_pinentry}
Host: ${host}
Compiler: ${CC}
@ -776,8 +740,6 @@ OPENSSL_LIBS: ${OPENSSL_LIBS}
OPENCT_CFLAGS: ${OPENCT_CFLAGS}
OPENCT_LIBS: ${OPENCT_LIBS}
PCSC_CFLAGS: ${PCSC_CFLAGS}
LIBASSUAN_CFLAGS: ${LIBASSUAN_CFLAGS}
LIBASSUAN_LIBS: ${LIBASSUAN_LIBS}
EOF

View File

@ -58,6 +58,10 @@
auto-detected.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--wait, -w</option></term>
<listitem><para>Wait for a card to be inserted</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--verbose, -v</option></term>
<listitem><para>
@ -152,18 +156,6 @@
and <varname>size</varname> is the size of the new file.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>pksign</option></term>
<listitem><para>create a public key signature. NOTE: This command is currently not implemented.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>pkdecrypt</option></term>
<listitem><para>perform a public key decryption. NOTE: This command is currently not implemented.
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>erase</option></term>
<listitem><para>erase the card, if the card supports it.</para></listitem>

View File

@ -31,11 +31,20 @@
<title>Options</title>
<para>
<variablelist>
<varlistentry>
<term><option>--info, -i</option></term>
<listitem><para>Print information about OpenSC, such as version and enabled components</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--atr, -a</option></term>
<listitem><para>Print the Answer To Reset (ATR) of the card,
output is in hex byte format</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--name, -n</option></term>
<listitem><para>Print the name of the inserted card (driver)</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--serial</option></term>
<listitem><para>Print the card serial number (normally the ICCSN), output is in hex byte
@ -70,6 +79,10 @@ in the system.</para></listitem>
<term><option>--card-driver</option> driver, <option>-c</option> driver</term>
<listitem><para>Use the given card driver. The default is auto-detected.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--wait, -w</option></term>
<listitem><para>Wait for a card to be inserted</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--verbose, -v</option></term>
<listitem><para>Causes <command>opensc-tool</command> to be more verbose. Specify this flag several times

View File

@ -341,6 +341,17 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>--use-default-transport-keys</option>,
<option>-T</option></term>
<listitem>
<para>
Tells <command>pkcs15-init</command> to not ask for the transport
keys and use default keys, as known by the card driver.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--so-pin, --so-puk, --pin, --puk</option></term>
<listitem>

View File

@ -16,20 +16,12 @@ app default {
# The file to which debug output will be written
#
# A special value of 'stdout' is recognized.
# Default: stdout
# Special values 'stdout' and 'stderr' are recognized.
# Default: stderr
#
# debug_file = /tmp/opensc-debug.log;
# debug_file = "C:\Documents and Settings\All Users\Documents\opensc-debug.log";
# The file to which errors will be written
#
# A special value of 'stderr' is recognized.
# Default: stderr
#
# error_file = /tmp/opensc-errors.log;
# error_file = "C:\Documents and Settings\All Users\Documents\opensc-errors.log";
# PKCS#15 initialization / personalization
# profiles directory for pkcs15-init.
# Default: @pkgdatadir@
@ -86,8 +78,8 @@ app default {
# transaction_reset = true;
#
# Enable pinpad if detected (PC/SC v2.0.2 Part 10)
# Default: false
# enable_pinpad = true;
# Default: true
# enable_pinpad = false;
#
# Use specific pcsc provider.
# Default: @DEFAULT_PCSC_PROVIDER@
@ -256,14 +248,25 @@ app default {
# WARNING: Caching shouldn't be used in setuid root
# applications.
# Default: false
# use_file_caching = true;
#
# Use PIN caching?
# Default: true
# use_pin_caching = false;
#
# How many times to use a PIN from cache before re-authenticating it?
# Default: 10
# pin_cache_counter = 3;
#
use_caching = true;
# Enable pkcs15 emulation.
# Default: yes
# enable_pkcs15_emulation = no;
#
# Prefer pkcs15 emulation code before
# the normal pkcs15 processing.
# Some cards (like esteid and pteid) work in emu-only mode,
# and do not depend on this option.
#
# Default: no
# try_emulation_first = yes;
#
@ -293,7 +296,7 @@ app default {
# so you can turn it off, if it misbehaves.
# this option only affects cardos cards right now.
# Default: yes
# enable_sign_with_decrypt_workaround = yes;
# enable_sign_with_decrypt_workaround = no;
}
}
@ -353,19 +356,7 @@ app opensc-pkcs11 {
#
# Default: true
# lock_login = false;
# Normally, the pkcs11 module will not cache PINs
# presented via C_Login. However, some cards
# may not work properly with OpenSC; for instance
# when you have two keys on your card that get
# stored in two different directories.
#
# In this case, you can turn on PIN caching by setting
# cache_pins = true
#
# Default: true
# cache_pins = false;
# Set this value to true if you want to allow off-card
# keypair generation (in software on your pc)
#

View File

@ -92,7 +92,6 @@ f none usr/include/opensc/rsaref/win32.h 0644 root bin
f none usr/include/opensc/scconf.h 0644 root bin
f none usr/include/opensc/opensc.h 0644 root bin
f none usr/include/opensc/pkcs15.h 0644 root bin
f none usr/include/opensc/emv.h 0644 root bin
f none usr/include/opensc/cardctl.h 0644 root bin
f none usr/include/opensc/asn1.h 0644 root bin
f none usr/include/opensc/log.h 0644 root bin

View File

@ -3,4 +3,4 @@ EXTRA_DIST = Makefile.mak
# Order IS important
SUBDIRS = common include scconf libopensc pkcs15init pkcs11 \
tests tools openssh signer
tests tools openssh

View File

@ -6,7 +6,6 @@ all-local:
@$(LN_S) $(top_srcdir)/src/libopensc/asn1.h asn1.h
@$(LN_S) $(top_srcdir)/src/libopensc/cardctl.h cardctl.h
@$(LN_S) $(top_srcdir)/src/libopensc/cards.h cards.h
@$(LN_S) $(top_srcdir)/src/libopensc/emv.h emv.h
@$(LN_S) $(top_srcdir)/src/libopensc/errors.h errors.h
@$(LN_S) $(top_srcdir)/src/libopensc/log.h log.h
@$(LN_S) $(top_srcdir)/src/libopensc/opensc.h opensc.h

View File

@ -8,7 +8,7 @@ EXTRA_DIST = Makefile.mak
bin_SCRIPTS = opensc-config
lib_LTLIBRARIES = libopensc.la
openscinclude_HEADERS = \
opensc.h pkcs15.h emv.h \
opensc.h pkcs15.h \
cardctl.h asn1.h log.h ui.h \
errors.h types.h compression.h
noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \
@ -30,7 +30,7 @@ libopensc_la_SOURCES = \
pkcs15-wrap.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \
pkcs15-gemsafeV1.c \
\
emv.c muscle.c muscle-filesystem.c \
muscle.c muscle-filesystem.c \
\
ctbcs.c reader-ctapi.c reader-pcsc.c reader-openct.c \
\
@ -40,12 +40,12 @@ libopensc_la_SOURCES = \
card-oberthur.c card-belpic.c card-atrust-acos.c card-entersafe.c \
card-incrypto34.c card-piv.c card-muscle.c card-acos5.c \
card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \
card-rtecp.c card-westcos.c card-myeid.c \
card-rtecp.c card-westcos.c card-myeid.c card-ias.c\
\
pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \
pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \
pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \
pkcs15-esinit.c p15emu-westcos.c \
pkcs15-esinit.c p15emu-westcos.c pkcs15-pteid.c \
compression.c p15card-helper.c \
\
libopensc.exports

View File

@ -4,7 +4,7 @@ TOPDIR = ..\..
TARGET = opensc.dll opensc_a.lib
HEADERS = \
asn1.h cardctl.h cards.h emv.h errors.h \
asn1.h cardctl.h cards.h errors.h \
log.h opensc.h pkcs15.h types.h ui.h
HEADERSDIR = $(TOPDIR)\src\include\opensc
@ -18,7 +18,7 @@ OBJECTS = \
pkcs15-wrap.obj pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \
pkcs15-gemsafeV1.obj \
\
emv.obj muscle.obj muscle-filesystem.obj \
muscle.obj muscle-filesystem.obj \
\
ctbcs.obj reader-ctapi.obj reader-pcsc.obj reader-openct.obj \
\
@ -28,13 +28,13 @@ OBJECTS = \
card-oberthur.obj card-belpic.obj card-atrust-acos.obj card-entersafe.obj \
card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \
card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \
card-rtecp.obj card-westcos.obj card-myeid.obj \
card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \
\
p15emu-westcos.obj \
pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \
pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \
pkcs15-esinit.obj \
pkcs15-esinit.obj pkcs15-pteid.c \
compression.obj p15card-helper.obj \
versioninfo.res

View File

@ -122,7 +122,7 @@ static int sc_apdu2bytes(sc_context_t *ctx, const sc_apdu_t *apdu,
if (apdu->lc > 255) {
/* ... so if Lc is greater than 255 bytes
* an error has occurred on a higher level */
sc_error(ctx, "invalid Lc length for CASE 3 "
sc_debug(ctx, "invalid Lc length for CASE 3 "
"extended APDU (need ENVELOPE)");
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -215,7 +215,7 @@ int sc_apdu_set_resp(sc_context_t *ctx, sc_apdu_t *apdu, const u8 *buf,
{
if (len < 2) {
/* no SW1 SW2 ... something went terrible wrong */
sc_error(ctx, "invalid response: SW1 SW2 missing");
sc_debug(ctx, "invalid response: SW1 SW2 missing");
return SC_ERROR_INTERNAL;
}
/* set the SW1 and SW2 status bytes (the last two bytes of
@ -273,7 +273,7 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
} else if ((apdu->cse & SC_APDU_EXT) != 0) {
/* check if the card support extended APDUs */
if ((card->caps & SC_CARD_CAP_APDU_EXT) == 0) {
sc_error(card->ctx, "card doesn't support extended APDUs");
sc_debug(card->ctx, "card doesn't support extended APDUs");
goto error;
}
/* length check for extended APDU */
@ -284,12 +284,12 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
switch (apdu->cse & SC_APDU_SHORT_MASK) {
case SC_APDU_CASE_1:
/* no data is send or received */
/* no data is sent or received */
if (apdu->datalen != 0 || apdu->lc != 0 || apdu->le != 0)
goto error;
break;
case SC_APDU_CASE_2_SHORT:
/* no data is send */
/* no data is sent */
if (apdu->datalen != 0 || apdu->lc != 0)
goto error;
/* data is expected */
@ -300,7 +300,7 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
goto error;
break;
case SC_APDU_CASE_3_SHORT:
/* data is send */
/* data is sent */
if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
goto error;
/* no data is expected */
@ -311,7 +311,7 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
goto error;
break;
case SC_APDU_CASE_4_SHORT:
/* data is send */
/* data is sent */
if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
goto error;
/* data is expected */
@ -325,12 +325,12 @@ static int sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
goto error;
break;
default:
sc_error(card->ctx, "Invalid APDU case %d\n", apdu->cse);
sc_debug(card->ctx, "Invalid APDU case %d\n", apdu->cse);
return SC_ERROR_INVALID_ARGUMENTS;
}
return SC_SUCCESS;
error:
sc_error(card->ctx, "Invalid Case %d %s APDU:\n"
sc_debug(card->ctx, "Invalid Case %d %s APDU:\n"
"cse=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%lu le=%lu\n"
"resp=%p resplen=%lu data=%p datalen=%lu",
apdu->cse & SC_APDU_SHORT_MASK,
@ -366,7 +366,7 @@ static void sc_detect_apdu_cse(const sc_card_t *card, sc_apdu_t *apdu)
/** Sends a single APDU to the card reader and calls
* GET RESPONSE to get the return data if necessary.
* @param card sc_card_t object for the smartcard
* @param apdu APDU to be send
* @param apdu APDU to be sent
* @return SC_SUCCESS on success and an error value otherwise
*/
static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu)
@ -391,7 +391,7 @@ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu)
return SC_ERROR_NOT_SUPPORTED;
r = card->reader->ops->transmit(card->reader, card->slot, apdu);
if (r != 0) {
sc_error(ctx, "unable to transmit APDU");
sc_debug(ctx, "unable to transmit APDU");
return r;
}
/* ok, the APDU was successfully transmitted. Now we have two
@ -416,7 +416,7 @@ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu)
/* re-transmit the APDU with new Le length */
r = card->reader->ops->transmit(card->reader, card->slot, apdu);
if (r != SC_SUCCESS) {
sc_error(ctx, "unable to transmit APDU");
sc_debug(ctx, "unable to transmit APDU");
return r;
}
} else {
@ -451,7 +451,7 @@ static int do_single_transmit(sc_card_t *card, sc_apdu_t *apdu)
if (card->ops->get_response == NULL) {
/* this should _never_ happen */
sc_error(ctx, "no GET RESPONSE command\n");
sc_debug(ctx, "no GET RESPONSE command\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -525,7 +525,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
r = sc_lock(card); /* acquire card lock*/
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to acquire lock");
sc_debug(card->ctx, "unable to acquire lock");
return r;
}
@ -566,7 +566,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
r = sc_check_apdu(card, &tapdu);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "inconsistent APDU while chaining");
sc_debug(card->ctx, "inconsistent APDU while chaining");
break;
}
@ -593,7 +593,7 @@ int sc_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu)
r = do_single_transmit(card, apdu);
/* all done => release lock */
if (sc_unlock(card) != SC_SUCCESS)
sc_error(card->ctx, "sc_unlock failed");
sc_debug(card->ctx, "sc_unlock failed");
return r;
}

View File

@ -307,7 +307,7 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf,
if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS)
return NULL;
if (left < (size_t)(p - buf)) {
sc_error(ctx, "invalid TLV object\n");
sc_debug(ctx, "invalid TLV object\n");
return NULL;
}
left -= (p - buf);
@ -327,7 +327,7 @@ const u8 *sc_asn1_find_tag(sc_context_t *ctx, const u8 * buf,
}
/* otherwise continue reading tags */
if (left < taglen) {
sc_error(ctx, "invalid TLV object\n");
sc_debug(ctx, "invalid TLV object\n");
return NULL;
}
left -= taglen;
@ -373,7 +373,7 @@ const u8 *sc_asn1_skip_tag(sc_context_t *ctx, const u8 ** buf, size_t *buflen,
return NULL;
len -= (p - *buf); /* header size */
if (taglen > len) {
sc_error(ctx, "too long ASN.1 object (size %d while only %d available)\n",
sc_debug(ctx, "too long ASN.1 object (size %d while only %d available)\n",
taglen, len);
return NULL;
}
@ -723,7 +723,7 @@ static int asn1_write_element(sc_context_t *ctx, unsigned int tag,
t = tag & 0x1F;
if (t != (tag & SC_ASN1_TAG_MASK)) {
sc_error(ctx, "Long tags not supported\n");
sc_debug(ctx, "Long tags not supported\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
switch (tag & SC_ASN1_CLASS_MASK) {
@ -989,7 +989,7 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
case SC_ASN1_BOOLEAN:
if (parm != NULL) {
if (objlen != 1) {
sc_error(ctx, "invalid ASN.1 object length: %d\n", objlen);
sc_debug(ctx, "invalid ASN.1 object length: %d\n", objlen);
r = SC_ERROR_INVALID_ASN1_OBJECT;
} else
*((int *) parm) = obj[0] ? 1 : 0;
@ -1133,11 +1133,11 @@ static int asn1_decode_entry(sc_context_t *ctx,struct sc_asn1_entry *entry,
r = callback_func(ctx, entry->arg, obj, objlen, depth);
break;
default:
sc_error(ctx, "invalid ASN.1 type: %d\n", entry->type);
sc_debug(ctx, "invalid ASN.1 type: %d\n", entry->type);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
if (r) {
sc_error(ctx, "decoding of ASN.1 object '%s' failed: %s\n", entry->name,
sc_debug(ctx, "decoding of ASN.1 object '%s' failed: %s\n", entry->name,
sc_strerror(r));
return r;
}
@ -1167,7 +1167,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
* to complain about */
if (asn1->name == NULL)
return 0;
sc_error(ctx, "End of ASN.1 stream, "
sc_debug(ctx, "End of ASN.1 stream, "
"non-optional field \"%s\" not found\n",
asn1->name);
return SC_ERROR_ASN1_OBJECT_NOT_FOUND;
@ -1204,7 +1204,7 @@ static int asn1_decode(sc_context_t *ctx, struct sc_asn1_entry *asn1,
continue;
if (entry->flags & SC_ASN1_OPTIONAL)
continue;
sc_error(ctx, "mandatory ASN.1 object '%s' not found\n", entry->name);
sc_debug(ctx, "mandatory ASN.1 object '%s' not found\n", entry->name);
if (ctx->debug && left) {
u8 line[128], *linep = line;
size_t i;
@ -1281,7 +1281,7 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr
while (list->name != NULL) {
if (list->flags & SC_ASN1_PRESENT) {
if (choice) {
sc_error(ctx,
sc_debug(ctx,
"ASN.1 problem: more than "
"one CHOICE when encoding %s: "
"%s and %s both present\n",
@ -1300,7 +1300,7 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr
}
if (entry->type != SC_ASN1_NULL && parm == NULL) {
sc_error(ctx, "unexpected parm == NULL\n");
sc_debug(ctx, "unexpected parm == NULL\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
@ -1396,11 +1396,11 @@ static int asn1_encode_entry(sc_context_t *ctx, const struct sc_asn1_entry *entr
r = callback_func(ctx, entry->arg, &buf, &buflen, depth);
break;
default:
sc_error(ctx, "invalid ASN.1 type: %d\n", entry->type);
sc_debug(ctx, "invalid ASN.1 type: %d\n", entry->type);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
if (r) {
sc_error(ctx, "encoding of ASN.1 object '%s' failed: %s\n", entry->name,
sc_debug(ctx, "encoding of ASN.1 object '%s' failed: %s\n", entry->name,
sc_strerror(r));
if (buf)
free(buf);
@ -1430,13 +1430,13 @@ no_object:
r = asn1_write_element(ctx, entry->tag,
buf, buflen, obj, objlen);
if (r)
sc_error(ctx, "error writing ASN.1 tag and length: %s\n",
sc_debug(ctx, "error writing ASN.1 tag and length: %s\n",
sc_strerror(r));
} else if (!(entry->flags & SC_ASN1_PRESENT)) {
sc_error(ctx, "cannot encode non-optional ASN.1 object: not given by caller\n");
sc_debug(ctx, "cannot encode non-optional ASN.1 object: not given by caller\n");
r = SC_ERROR_INVALID_ASN1_OBJECT;
} else {
sc_error(ctx, "cannot encode empty non-optional ASN.1 object\n");
sc_debug(ctx, "cannot encode empty non-optional ASN.1 object\n");
r = SC_ERROR_INVALID_ASN1_OBJECT;
}
if (buf)

View File

@ -54,11 +54,6 @@ static int acos5_init(sc_card_t * card)
return SC_SUCCESS;
}
static int acos5_finish(sc_card_t * card)
{
return SC_SUCCESS;
}
static int acos5_select_file_by_path(sc_card_t * card,
const sc_path_t * in_path,
sc_file_t ** file_out)
@ -225,7 +220,6 @@ static struct sc_card_driver *sc_get_driver(void)
acos5_ops.match_card = acos5_match_card;
acos5_ops.init = acos5_init;
acos5_ops.finish = acos5_finish;
acos5_ops.select_file = acos5_select_file;
acos5_ops.card_ctl = acos5_card_ctl;
acos5_ops.list_files = acos5_list_files;

View File

@ -168,7 +168,7 @@ akis_list_files(sc_card_t *card, u8 *buf, size_t buflen)
while (left > 19) {
if (p[0] != 0x2f && p[0] != 0x3d) {
sc_error(card->ctx, "Malformatted list reply %02x", p[0]);
sc_debug(card->ctx, "Malformatted list reply %02x", p[0]);
return SC_ERROR_INTERNAL;
}
if (buflen >= 2) {
@ -202,7 +202,7 @@ akis_process_fci(sc_card_t *card, sc_file_t *file,
*/
p = sc_asn1_find_tag(card->ctx, buf, buflen, 0x90, &len);
if (p == NULL) {
sc_error(card->ctx, "Security tag missing");
sc_debug(card->ctx, "Security tag missing");
return SC_ERROR_INTERNAL;
}
perms = p[0];
@ -272,7 +272,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file)
type = 0x45;
break;
default:
sc_error(card->ctx, "This EF structure is not supported yet");
sc_debug(card->ctx, "This EF structure is not supported yet");
return SC_ERROR_NOT_SUPPORTED;
}
apdu.p1 = type;
@ -284,7 +284,7 @@ akis_create_file(sc_card_t *card, sc_file_t *file)
} else if (file->type == SC_FILE_TYPE_DF) {
apdu.ins = 0x10;
} else {
sc_error(card->ctx, "Unknown file type");
sc_debug(card->ctx, "Unknown file type");
return SC_ERROR_NOT_SUPPORTED;
}
@ -317,7 +317,7 @@ akis_delete_file(sc_card_t *card, const sc_path_t *path)
type = 0x08;
break;
default:
sc_error(card->ctx, "File type has to be FID or PATH");
sc_debug(card->ctx, "File type has to be FID or PATH");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x16, type, 0x00);
@ -354,7 +354,6 @@ akis_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left
p1 = 1;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, p1, p2);
apdu.sensitive = 1;
buf[0] = data->pin1.len;
memcpy(buf+1, data->pin1.data, data->pin1.len);
@ -372,7 +371,7 @@ akis_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data, int *tries_left
return r;
}
sc_error(card->ctx, "Other pin cmds not supported yet");
sc_debug(card->ctx, "Other pin cmds not supported yet");
return SC_ERROR_NOT_SUPPORTED;
}

View File

@ -39,11 +39,6 @@ static struct sc_atr_table asepcos_atrs[] = {
{ NULL, NULL, NULL, 0, 0, NULL }
};
static int asepcos_finish(sc_card_t *card)
{
return SC_SUCCESS;
}
static int asepcos_match_card(sc_card_t *card)
{
int i = _sc_match_atr(card, asepcos_atrs, &card->type);
@ -64,7 +59,7 @@ static int asepcos_select_asepcos_applet(sc_card_t *card)
r = sc_select_file(card, &tpath, NULL);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to select ASEPCOS applet");
sc_debug(card->ctx, "unable to select ASEPCOS applet");
return r;
}
@ -165,7 +160,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu
while (len != 0) {
unsigned int amode, tlen = 3;
if (len < 5 && p[0] != 0x80 && p[1] != 0x01) {
sc_error(card->ctx, "invalid access mode encoding");
sc_debug(card->ctx, "invalid access mode encoding");
return SC_ERROR_INTERNAL;
}
amode = p[2];
@ -192,7 +187,7 @@ static int asepcos_parse_sec_attr(sc_card_t *card, sc_file_t *file, const u8 *bu
return r;
tlen += 2 + p[4]; /* FIXME */
} else {
sc_error(card->ctx, "invalid security condition");
sc_debug(card->ctx, "invalid security condition");
return SC_ERROR_INTERNAL;
}
p += tlen;
@ -306,7 +301,7 @@ static int asepcos_select_file(sc_card_t *card, const sc_path_t *in_path,
if (r == SC_SUCCESS && file != NULL) {
r = asepcos_parse_sec_attr(card, *file, (*file)->sec_attr, (*file)->sec_attr_len);
if (r != SC_SUCCESS)
sc_error(card->ctx, "error parsing security attributes");
sc_debug(card->ctx, "error parsing security attributes");
}
SC_FUNC_RETURN(card->ctx, 1, r);
}
@ -482,7 +477,7 @@ static int asepcos_set_security_attributes(sc_card_t *card, sc_file_t *file)
*p++ = (st.fileid >> 8 ) & 0xff;
*p++ = st.fileid & 0xff;
} else {
sc_error(card->ctx, "unknow auth method: '%d'", ent->method);
sc_debug(card->ctx, "unknow auth method: '%d'", ent->method);
return SC_ERROR_INTERNAL;
}
}
@ -509,7 +504,6 @@ static int asepcos_decipher(sc_card_t *card, const u8 * crgram, size_t crgram_le
* to tell the card the we want everything available (note: we
* always have Le <= crgram_len) */
apdu.le = (outlen >= 256 && crgram_len < 256) ? 256 : outlen;
apdu.sensitive = 1;
apdu.data = crgram;
apdu.lc = crgram_len;
@ -550,7 +544,7 @@ static int asepcos_compute_signature(sc_card_t *card, const u8 *data, size_t dat
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) {
sc_error(card->ctx, "error creating signature");
sc_debug(card->ctx, "error creating signature");
return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
@ -628,7 +622,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file)
/* set security attributes */
r = asepcos_set_security_attributes(card, file);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to set security attributes");
sc_debug(card->ctx, "unable to set security attributes");
return r;
}
return SC_SUCCESS;
@ -674,7 +668,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file)
/* set security attributes */
r = asepcos_set_security_attributes(card, file);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to set security attributes");
sc_debug(card->ctx, "unable to set security attributes");
return r;
}
return asepcos_activate_file(card, file->id, 1);
@ -701,7 +695,7 @@ static int asepcos_create_file(sc_card_t *card, sc_file_t *file)
/* set security attributes */
r = asepcos_set_security_attributes(card, file);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to set security attributes");
sc_debug(card->ctx, "unable to set security attributes");
return r;
}
return asepcos_activate_file(card, file->id, 1);
@ -735,7 +729,7 @@ static int asepcos_list_files(sc_card_t *card, u8 *buf, size_t blen)
return r;
if (tfile->prop_attr_len != 6 || tfile->prop_attr == NULL) {
sc_file_free(tfile);
sc_error(card->ctx, "unable to parse proprietary FCI attributes");
sc_debug(card->ctx, "unable to parse proprietary FCI attributes");
return SC_ERROR_INTERNAL;
}
dfFID = (tfile->prop_attr[2] << 8) | tfile->prop_attr[3];
@ -990,9 +984,6 @@ static int asepcos_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu,
default:
return SC_ERROR_NOT_SUPPORTED;
}
/* all PIN related APDUs are sensitive */
apdu->sensitive = 1;
return SC_SUCCESS;
}
@ -1013,7 +1004,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata,
return SC_ERROR_INVALID_ARGUMENTS;
/* check PIN length */
if (pdata->pin1.len < 4 || pdata->pin1.len > 16) {
sc_error(card->ctx, "invalid PIN1 length");
sc_debug(card->ctx, "invalid PIN1 length");
return SC_ERROR_INVALID_PIN_LENGTH;
}
@ -1025,11 +1016,11 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata,
break;
r = sc_transmit_apdu(card, &apdu);
if (r != SC_SUCCESS)
sc_error(card->ctx, "APDU transmit failed");
sc_debug(card->ctx, "APDU transmit failed");
break;
case SC_PIN_CMD_CHANGE:
if (pdata->pin2.len < 4 || pdata->pin2.len > 16) {
sc_error(card->ctx, "invalid PIN2 length");
sc_debug(card->ctx, "invalid PIN2 length");
return SC_ERROR_INVALID_PIN_LENGTH;
}
/* 1. step: verify the old pin */
@ -1038,7 +1029,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata,
break;
r = sc_transmit_apdu(card, &apdu);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "APDU transmit failed");
sc_debug(card->ctx, "APDU transmit failed");
break;
}
if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) {
@ -1052,12 +1043,12 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata,
break;
r = sc_transmit_apdu(card, &apdu);
if (r != SC_SUCCESS)
sc_error(card->ctx, "APDU transmit failed");
sc_debug(card->ctx, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
break;
case SC_PIN_CMD_UNBLOCK:
if (pdata->pin2.len < 4 || pdata->pin2.len > 16) {
sc_error(card->ctx, "invalid PIN2 length");
sc_debug(card->ctx, "invalid PIN2 length");
return SC_ERROR_INVALID_PIN_LENGTH;
}
/* 1. step: verify the puk */
@ -1066,7 +1057,7 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata,
break;
r = sc_transmit_apdu(card, &apdu);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "APDU transmit failed");
sc_debug(card->ctx, "APDU transmit failed");
break;
}
/* 2, step: unblock and change the pin */
@ -1075,13 +1066,13 @@ static int asepcos_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *pdata,
break;
r = sc_transmit_apdu(card, &apdu);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "APDU transmit failed");
sc_debug(card->ctx, "APDU transmit failed");
break;
}
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
break;
default:
sc_error(card->ctx, "error: unknow cmd type");
sc_debug(card->ctx, "error: unknow cmd type");
return SC_ERROR_INTERNAL;
}
/* Clear the buffer - it may contain pins */
@ -1102,7 +1093,6 @@ static struct sc_card_driver * sc_get_driver(void)
asepcos_ops = *iso_ops;
asepcos_ops.match_card = asepcos_match_card;
asepcos_ops.init = asepcos_init;
asepcos_ops.finish = asepcos_finish;
asepcos_ops.select_file = asepcos_select_file;
asepcos_ops.set_security_env = asepcos_set_security_env;
asepcos_ops.decipher = asepcos_decipher;

View File

@ -624,11 +624,9 @@ static int atrust_acos_set_security_env(struct sc_card *card,
apdu.datalen = p - sbuf;
apdu.lc = p - sbuf;
apdu.le = 0;
/* suppress errors, as don't know whether to use
/* we don't know whether to use
* COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */
sc_ctx_suppress_errors_on(card->ctx);
r = sc_transmit_apdu(card, &apdu);
sc_ctx_suppress_errors_off(card->ctx);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
ex_data->fix_digestInfo = 0;
@ -708,7 +706,6 @@ static int atrust_acos_compute_signature(struct sc_card *card,
apdu.lc = 0;
apdu.datalen = 0;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
@ -783,7 +780,6 @@ static int atrust_acos_decipher(struct sc_card *card,
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.sensitive = 1;
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
memcpy(sbuf + 1, crgram, crgram_len);
@ -816,7 +812,7 @@ static int atrust_acos_check_sw(struct sc_card *card, unsigned int sw1,
return SC_NO_ERROR;
if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 )
{
sc_error(card->ctx, "Verification failed (remaining tries: %d)\n",
sc_debug(card->ctx, "Verification failed (remaining tries: %d)\n",
(sw2 & 0x0f));
return SC_ERROR_PIN_CODE_INCORRECT;
}
@ -889,9 +885,7 @@ static int atrust_acos_logout(struct sc_card *card)
apdu.datalen = 2;
apdu.resplen = 0;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_transmit_apdu(card, &apdu);
sc_ctx_suppress_errors_off(card->ctx);
SC_TEST_RET(card->ctx, r, "APDU re-transmit failed");
if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85)

View File

@ -286,7 +286,7 @@ struct pcsc_slot_data {
SCARDHANDLE pcsc_card;
}; /* comes from reader-pcsc.c */
#define GET_SLOT_DATA(r) ((struct pcsc_slot_data *) (r)->drv_data)
#define PCSC_ERROR(ctx, desc, rv) sc_error(ctx, desc ": %lx\n", rv);
#define PCSC_ERROR(ctx, desc, rv) sc_debug(ctx, desc ": %lx\n", rv);
#endif /* BELPIC_PIN_PAD */
@ -1035,7 +1035,7 @@ static int belpic_init(sc_card_t *card)
#ifdef HAVE_GUI
r = scgui_init();
if (r != 0)
sc_error(card->ctx, "scgui_init() returned error %d\n", i);
sc_debug(card->ctx, "scgui_init() returned error %d\n", i);
#endif
#ifdef BELPIC_PIN_PAD
@ -1209,7 +1209,7 @@ static int belpic_pp_verify(sc_card_t *card, SCR_Card * scr_card,
if (r1 == SCGUI_CANCEL)
return r;
else if (r1 != SCGUI_OK) {
sc_error(card->ctx, "scgui_ask_message returned %d\n", r1);
sc_debug(card->ctx, "scgui_ask_message returned %d\n", r1);
return SC_ERROR_INTERNAL;
}
} else
@ -1272,7 +1272,7 @@ static int belpic_pp_change(sc_card_t *card, SCR_Card * scr_card,
if (r1 == SCGUI_CANCEL)
return r;
else if (r1 != SCGUI_OK) {
sc_error(card->ctx, "scgui_ask_message returned %d\n", r1);
sc_debug(card->ctx, "scgui_ask_message returned %d\n", r1);
return SC_ERROR_INTERNAL;
}
}
@ -1417,7 +1417,7 @@ static int belpic_askpin_verify(sc_card_t *card, int pin_usage)
if (r1 == SCGUI_CANCEL)
return r;
else if (r1 != SCGUI_OK) {
sc_error(card->ctx, "scgui_ask_message returned %d\n", r1);
sc_debug(card->ctx, "scgui_ask_message returned %d\n", r1);
return SC_ERROR_INTERNAL;
}
@ -1470,7 +1470,7 @@ static int belpic_set_security_env(sc_card_t *card,
else if (env->algorithm_flags & SC_ALGORITHM_RSA_HASH_MD5)
sbuf[2] = 0x04;
else {
sc_error(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n",
sc_debug(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n",
env->algorithm_flags);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -1506,7 +1506,7 @@ static int belpic_set_security_env(sc_card_t *card,
#ifdef HAVE_GUI
r = belpic_askpin_verify(card, SCR_USAGE_SIGN);
if (r != 0 && r != SC_ERROR_KEYPAD_CANCELLED)
sc_error(card->ctx, "Verify PIN in SET command returned %d\n", r);
sc_debug(card->ctx, "Verify PIN in SET command returned %d\n", r);
else
sc_debug(card->ctx, "Verify PIN in SET command returned %d\n", r);
#else

View File

@ -42,7 +42,7 @@ static struct sc_atr_table cardos_atrs[] = {
/* 4.0 */
{ "3b:e2:00:ff:c1:10:31:fe:55:c8:02:9c", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL },
/* Italian eID card, postecert */
{ "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL },
{ "3b:e9:00:ff:c1:10:31:fe:55:00:64:05:00:c8:02:31:80:00:47", NULL, NULL, SC_CARD_TYPE_CARDOS_CIE_V1, 0, NULL },
/* Italian eID card, infocamere */
{ "3b:fb:98:00:ff:c1:10:31:fe:55:00:64:05:20:47:03:31:80:00:90:00:f3", NULL, NULL, SC_CARD_TYPE_CARDOS_GENERIC, 0, NULL },
/* Another Italian InfocamereCard */
@ -53,11 +53,6 @@ static struct sc_atr_table cardos_atrs[] = {
{ NULL, NULL, NULL, 0, 0, NULL }
};
static int cardos_finish(sc_card_t *card)
{
return 0;
}
static int cardos_match_card(sc_card_t *card)
{
int i;
@ -65,6 +60,9 @@ static int cardos_match_card(sc_card_t *card)
i = _sc_match_atr(card, cardos_atrs, &card->type);
if (i < 0)
return 0;
/* Do not change card type for CIE! */
if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1)
return 1;
if (card->type == SC_CARD_TYPE_CARDOS_M4_2) {
int rv;
sc_apdu_t apdu;
@ -255,13 +253,13 @@ static int cardos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
for (i = 0; i < err_count; i++) {
if (cardos_errors[i].SWs == ((sw1 << 8) | sw2)) {
if ( cardos_errors[i].errorstr )
sc_error(card->ctx, "%s\n",
sc_debug(card->ctx, "%s\n",
cardos_errors[i].errorstr);
return cardos_errors[i].errorno;
}
}
sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
return SC_ERROR_CARD_CMD_FAILED;
}
@ -291,7 +289,7 @@ get_next_part:
SC_TEST_RET(card->ctx, r, "DIRECTORY command returned error");
if (apdu.resplen > 256) {
sc_error(card->ctx, "directory listing > 256 bytes, cutting");
sc_debug(card->ctx, "directory listing > 256 bytes, cutting");
r = 256;
}
@ -301,7 +299,7 @@ get_next_part:
/* is there a file informatin block (0x6f) ? */
p = sc_asn1_find_tag(card->ctx, p, len, 0x6f, &tlen);
if (p == NULL) {
sc_error(card->ctx, "directory tag missing");
sc_debug(card->ctx, "directory tag missing");
return SC_ERROR_INTERNAL;
}
if (tlen == 0)
@ -309,7 +307,7 @@ get_next_part:
break;
q = sc_asn1_find_tag(card->ctx, p, tlen, 0x86, &ilen);
if (q == NULL || ilen != 2) {
sc_error(card->ctx, "error parsing file id TLV object");
sc_debug(card->ctx, "error parsing file id TLV object");
return SC_ERROR_INTERNAL;
}
/* put file id in buf */
@ -451,7 +449,7 @@ static int cardos_acl_to_bytes(sc_card_t *card, const sc_file_t *file,
else
byte = acl_to_byte(sc_file_get_acl_entry(file, idx[i]));
if (byte < 0) {
sc_error(card->ctx, "Invalid ACL\n");
sc_debug(card->ctx, "Invalid ACL\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
buf[i] = byte;
@ -581,7 +579,7 @@ static int cardos_construct_fcp(sc_card_t *card, const sc_file_t *file,
buf[4] |= (u8) file->record_count;
break;
default:
sc_error(card->ctx, "unknown EF type: %u", file->type);
sc_debug(card->ctx, "unknown EF type: %u", file->type);
return SC_ERROR_INVALID_ARGUMENTS;
}
if (file->ef_structure == SC_FILE_EF_CYCLIC ||
@ -657,7 +655,7 @@ static int cardos_create_file(sc_card_t *card, sc_file_t *file)
r = cardos_construct_fcp(card, file, sbuf, &len);
if (r < 0) {
sc_error(card->ctx, "unable to create FCP");
sc_debug(card->ctx, "unable to create FCP");
return r;
}
@ -685,7 +683,8 @@ cardos_restore_security_env(sc_card_t *card, int se_num)
SC_FUNC_CALLED(card->ctx, 1);
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 3, se_num);
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0, se_num);
apdu.p1 = (card->type == SC_CARD_TYPE_CARDOS_CIE_V1 ? 0xF3 : 0x03);
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@ -719,12 +718,18 @@ cardos_set_security_env(sc_card_t *card,
if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
|| env->key_ref_len != 1) {
sc_error(card->ctx, "No or invalid key reference\n");
sc_debug(card->ctx, "No or invalid key reference\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
key_id = env->key_ref[0];
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 1, 0);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0, 0);
if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1) {
cardos_restore_security_env(card, 0x30);
apdu.p1 = 0xF1;
} else {
apdu.p1 = 0x01;
}
switch (env->operation) {
case SC_SEC_OPERATION_DECIPHER:
apdu.p2 = 0xB8;
@ -774,7 +779,6 @@ do_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
apdu.data = data;
apdu.lc = datalen;
apdu.datalen = datalen;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@ -822,9 +826,7 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | SC_CARD_CAP_ONLY_RAW_HASH))) {
if (ctx->debug >= 3)
sc_debug(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n");
sc_ctx_suppress_errors_on(ctx);
r = do_compute_signature(card, data, datalen, out, outlen);
sc_ctx_suppress_errors_off(ctx);
if (r >= SC_SUCCESS)
SC_FUNC_RETURN(ctx, 4, r);
}
@ -849,9 +851,7 @@ cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
if (!(card->caps & (SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED | SC_CARD_CAP_ONLY_RAW_HASH)) || card->caps & SC_CARD_CAP_ONLY_RAW_HASH ) {
if (ctx->debug >= 3)
sc_debug(ctx, "trying to sign raw hash value with prefix\n");
sc_ctx_suppress_errors_on(ctx);
r = do_compute_signature(card, buf, tmp_len, out, outlen);
sc_ctx_suppress_errors_off(ctx);
if (r >= SC_SUCCESS)
SC_FUNC_RETURN(ctx, 4, r);
}
@ -906,7 +906,7 @@ cardos_lifecycle_get(sc_card_t *card, int *mode)
*mode = SC_CARDCTRL_LIFECYCLE_OTHER;
break;
default:
sc_error(card->ctx, "Unknown lifecycle byte %d", rbuf[0]);
sc_debug(card->ctx, "Unknown lifecycle byte %d", rbuf[0]);
r = SC_ERROR_INTERNAL;
}
@ -1173,7 +1173,6 @@ static struct sc_card_driver * sc_get_driver(void)
cardos_ops = *iso_ops;
cardos_ops.match_card = cardos_match_card;
cardos_ops.init = cardos_init;
cardos_ops.finish = cardos_finish;
cardos_ops.select_file = cardos_select_file;
cardos_ops.create_file = cardos_create_file;
cardos_ops.set_security_env = cardos_set_security_env;

View File

@ -29,11 +29,6 @@ static struct sc_card_driver default_drv = {
NULL, 0, NULL
};
static int default_finish(sc_card_t *card)
{
return 0;
}
static int default_match_card(sc_card_t *card)
{
return 1; /* always match */
@ -84,12 +79,12 @@ static int autodetect_class(sc_card_t *card)
if (card->ctx->debug >= 2)
sc_debug(card->ctx, "SELECT FILE returned %d bytes\n",
apdu.resplen);
return 0;
return SC_SUCCESS;
}
if (rbuf[0] == 0x6F) {
if (card->ctx->debug >= 2)
sc_debug(card->ctx, "SELECT FILE seems to behave according to ISO 7816-4\n");
return 0;
return SC_SUCCESS;
}
if (rbuf[0] == 0x00 && rbuf[1] == 0x00) {
struct sc_card_driver *drv;
@ -97,24 +92,24 @@ static int autodetect_class(sc_card_t *card)
sc_debug(card->ctx, "SELECT FILE seems to return Schlumberger 'flex stuff\n");
drv = sc_get_cryptoflex_driver();
card->ops->select_file = drv->ops->select_file;
return 0;
return SC_SUCCESS;
}
return 0;
return SC_SUCCESS;
}
static int default_init(sc_card_t *card)
{
int r;
card->name = "Unidentified card";
card->name = "Unsupported card";
card->drv_data = NULL;
r = autodetect_class(card);
if (r) {
sc_error(card->ctx, "unable to determine the right class byte\n");
sc_debug(card->ctx, "unable to determine the right class byte\n");
return SC_ERROR_INVALID_CARD;
}
return 0;
return SC_SUCCESS;
}
static struct sc_card_driver * sc_get_driver(void)
@ -124,14 +119,11 @@ static struct sc_card_driver * sc_get_driver(void)
default_ops = *iso_drv->ops;
default_ops.match_card = default_match_card;
default_ops.init = default_init;
default_ops.finish = default_finish;
return &default_drv;
}
#if 1
struct sc_card_driver * sc_get_default_driver(void)
{
return sc_get_driver();
}
#endif

View File

@ -23,7 +23,7 @@
static struct sc_card_operations emv_ops;
static struct sc_card_driver emv_drv = {
"EMV compatible cards",
"EMV cards (unsupported)",
"emv",
&emv_ops,
NULL, 0, NULL
@ -31,7 +31,7 @@ static struct sc_card_driver emv_drv = {
static int emv_finish(sc_card_t *card)
{
return 0;
return SC_SUCCESS;
}
static int parse_atr(const u8 *atr, size_t atr_len, int *t0_out, int *tx1, int *tx2,
@ -120,7 +120,7 @@ static int emv_init(sc_card_t *card)
card->drv_data = NULL;
card->cla = 0x00;
return 0;
return SC_SUCCESS;
}
static int emv_select_file(sc_card_t *card, const sc_path_t *path,
@ -137,7 +137,7 @@ static int emv_select_file(sc_card_t *card, const sc_path_t *path,
(*file)->type = SC_FILE_TYPE_DF;
if (file != NULL && (*file)->namelen)
(*file)->type = SC_FILE_TYPE_DF;
return 0;
return SC_SUCCESS;
}
static struct sc_card_driver * sc_get_driver(void)
@ -147,15 +147,13 @@ static struct sc_card_driver * sc_get_driver(void)
emv_ops = *iso_drv->ops;
emv_ops.match_card = emv_match_card;
emv_ops.init = emv_init;
emv_ops.finish = emv_finish;
emv_ops.finish = emv_finish;
emv_ops.select_file = emv_select_file;
return &emv_drv;
}
#if 1
struct sc_card_driver * sc_get_emv_driver(void)
{
return sc_get_driver();
}
#endif

View File

@ -195,18 +195,18 @@ static int entersafe_cipher_apdu(sc_card_t *card, sc_apdu_t *apdu,
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL);
if(!EVP_EncryptUpdate(&ctx,buff,&apdu->lc,buff,buffsize)){
sc_error(card->ctx, "entersafe encryption error.");
sc_debug(card->ctx, "entersafe encryption error.");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL);
}
if (!EVP_CIPHER_CTX_cleanup(&ctx)){
sc_error(card->ctx, "entersafe encryption error.");
sc_debug(card->ctx, "entersafe encryption error.");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL);
}
if(apdu->lc!=buffsize)
{
sc_error(card->ctx, "entersafe build cipher apdu failed.");
sc_debug(card->ctx, "entersafe build cipher apdu failed.");
SC_FUNC_RETURN(card->ctx, 3, SC_ERROR_INTERNAL);
}
@ -907,7 +907,6 @@ static int entersafe_compute_with_prkey(sc_card_t *card,
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = 256;
apdu.sensitive = 1;
r = entersafe_transmit_apdu(card, &apdu,0,0,0,0);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");

View File

@ -317,7 +317,7 @@ cryptoflex_process_file_attrs(sc_card_t *card, sc_file_t *file,
file->type = SC_FILE_TYPE_DF;
break;
default:
sc_error(ctx, "invalid file type: 0x%02X\n", *p);
sc_debug(ctx, "invalid file type: 0x%02X\n", *p);
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
p += 2;
@ -386,7 +386,7 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file,
file->type = SC_FILE_TYPE_WORKING_EF;
break;
default:
sc_error(ctx, "invalid file type: 0x%02X\n", *p);
sc_debug(ctx, "invalid file type: 0x%02X\n", *p);
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
@ -436,7 +436,7 @@ cyberflex_process_file_attrs(sc_card_t *card, sc_file_t *file,
#endif
break;
default:
sc_error(ctx, "invalid file type: 0x%02X\n", *p);
sc_debug(ctx, "invalid file type: 0x%02X\n", *p);
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
switch (file->ef_structure) {
@ -571,7 +571,7 @@ static int select_file_id(sc_card_t *card, const u8 *buf, size_t buflen,
if (apdu.resplen < 14)
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
if (apdu.resp[0] == 0x6F) {
sc_error(card->ctx, "unsupported: card returned FCI\n");
sc_debug(card->ctx, "unsupported: card returned FCI\n");
return SC_ERROR_UNKNOWN_DATA_RECEIVED; /* FIXME */
}
file = sc_file_new();
@ -672,7 +672,7 @@ static int cryptoflex_list_files(sc_card_t *card, u8 *buf, size_t buflen)
if (r)
return r;
if (apdu.resplen != 4) {
sc_error(card->ctx, "expected 4 bytes, got %d.\n", apdu.resplen);
sc_debug(card->ctx, "expected 4 bytes, got %d.\n", apdu.resplen);
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
memcpy(buf, rbuf + 2, 2);
@ -707,7 +707,7 @@ static int cyberflex_list_files(sc_card_t *card, u8 *buf, size_t buflen)
if (r)
return r;
if (apdu.resplen != 6) {
sc_error(card->ctx, "expected 6 bytes, got %d.\n", apdu.resplen);
sc_debug(card->ctx, "expected 6 bytes, got %d.\n", apdu.resplen);
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
memcpy(buf, rbuf + 4, 2);
@ -725,7 +725,7 @@ static int flex_delete_file(sc_card_t *card, const sc_path_t *path)
SC_FUNC_CALLED(card->ctx, 1);
if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) {
sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE4, 0x00, 0x00);
@ -810,7 +810,7 @@ cryptoflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file,
p[6] = 0x06;
break;
default:
sc_error(card->ctx, "Invalid EF structure\n");
sc_debug(card->ctx, "Invalid EF structure\n");
return -1;
}
p[7] = 0xFF; /* allow Decrease and Increase */
@ -906,7 +906,7 @@ cyberflex_construct_file_attrs(sc_card_t *card, const sc_file_t *file,
p[4] = 0x1D;
break;
default:
sc_error(card->ctx, "Invalid EF structure\n");
sc_debug(card->ctx, "Invalid EF structure\n");
return -1;
}
p[5] = 0x01; /* status?? */
@ -945,7 +945,7 @@ static int flex_create_file(sc_card_t *card, sc_file_t *file)
* abstracting the Cryptoflex/Cyberflex differences */
r = card->ops->construct_fci(card, file, sbuf, &sendlen);
if (r) {
sc_error(card->ctx, "File structure encoding failed.\n");
sc_debug(card->ctx, "File structure encoding failed.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (file->type != SC_FILE_TYPE_DF && file->ef_structure != SC_FILE_EF_TRANSPARENT)
@ -982,33 +982,33 @@ static int flex_set_security_env(sc_card_t *card,
if (env->operation != SC_SEC_OPERATION_SIGN &&
env->operation != SC_SEC_OPERATION_DECIPHER) {
sc_error(card->ctx, "Invalid crypto operation supplied.\n");
sc_debug(card->ctx, "Invalid crypto operation supplied.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (env->algorithm != SC_ALGORITHM_RSA) {
sc_error(card->ctx, "Invalid crypto algorithm supplied.\n");
sc_debug(card->ctx, "Invalid crypto algorithm supplied.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) ||
(env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) {
sc_error(card->ctx, "Card supports only raw RSA.\n");
sc_debug(card->ctx, "Card supports only raw RSA.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
if (env->key_ref_len != 1 ||
(env->key_ref[0] != 0 && env->key_ref[0] != 1)) {
sc_error(card->ctx, "Invalid key reference supplied.\n");
sc_debug(card->ctx, "Invalid key reference supplied.\n");
return SC_ERROR_NOT_SUPPORTED;
}
prv->rsa_key_ref = env->key_ref[0];
}
if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
sc_error(card->ctx, "Algorithm reference not supported.\n");
sc_debug(card->ctx, "Algorithm reference not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT)
if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) {
sc_error(card->ctx, "File reference is not 0012.\n");
sc_debug(card->ctx, "File reference is not 0012.\n");
return SC_ERROR_NOT_SUPPORTED;
}
return 0;
@ -1030,11 +1030,11 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data,
size_t i, i2;
if (data_len != 64 && data_len != 96 && data_len != 128 && data_len != 256) {
sc_error(card->ctx, "Illegal input length: %d\n", data_len);
sc_debug(card->ctx, "Illegal input length: %d\n", data_len);
return SC_ERROR_INVALID_ARGUMENTS;
}
if (outlen < data_len) {
sc_error(card->ctx, "Output buffer too small.\n");
sc_debug(card->ctx, "Output buffer too small.\n");
return SC_ERROR_BUFFER_TOO_SMALL;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x88, 0x00, prv->rsa_key_ref);
@ -1066,7 +1066,6 @@ cryptoflex_compute_signature(sc_card_t *card, const u8 *data,
apdu.resplen = outlen > sizeof(sbuf) ? sizeof(sbuf) : outlen;
apdu.le = apdu.resplen > 256 ? 256 : apdu.resplen;
apdu.resp = sbuf;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
@ -1090,13 +1089,13 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data,
case 96: alg_id = 0xC6; break;
case 128: alg_id = 0xC8; break;
default:
sc_error(card->ctx, "Illegal input length: %d\n", data_len);
sc_debug(card->ctx, "Illegal input length: %d\n", data_len);
return SC_ERROR_INVALID_ARGUMENTS;
}
key_id = prv->rsa_key_ref + 1; /* Why? */
if (outlen < data_len) {
sc_error(card->ctx, "Output buffer too small.\n");
sc_debug(card->ctx, "Output buffer too small.\n");
return SC_ERROR_BUFFER_TOO_SMALL;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x88, alg_id, key_id);
@ -1106,7 +1105,6 @@ cyberflex_compute_signature(sc_card_t *card, const u8 *data,
apdu.data = data;
apdu.resplen = outlen;
apdu.resp = out;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
@ -1163,7 +1161,7 @@ static int flex_generate_key(sc_card_t *card, struct sc_cardctl_cryptoflex_genke
case 1024: p2 = 0x80; break;
case 2048: p2 = 0x00; break;
default:
sc_error(card->ctx, "Illegal key length: %d\n", data->key_bits);
sc_debug(card->ctx, "Illegal key length: %d\n", data->key_bits);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -1279,7 +1277,6 @@ static int flex_build_verify_apdu(sc_card_t *card, sc_apdu_t *apdu,
apdu->data = sbuf;
apdu->datalen = len;
apdu->lc = len;
apdu->sensitive = 1;
return 0;
}

View File

@ -15,6 +15,7 @@
*/
/* Initially written by David Mattes (david.mattes@boeing.com) */
/* Portuguese eID card support by Joao Poupino (joao.poupino@ist.utl.pt) */
#include "internal.h"
#include "cardctl.h"
@ -32,20 +33,27 @@ static struct sc_card_driver gemsafe_drv = {
NULL, 0, NULL
};
static const char *gemexpresso_atrs[] = {
/* standard version */
"3B:7B:94:00:00:80:65:B0:83:01:01:74:83:00:90:00",
"3B:6B:00:00:80:65:B0:83:01:01:74:83:00:90:00",
/* fips 140 version */
"3B:6B:00:00:80:65:B0:83:01:03:74:83:00:90:00",
/* TODO: add more ATRs */
"3B:7A:94:00:00:80:65:A2:01:01:01:3D:72:D6:43",
"3B:7D:94:00:00:80:31:80:65:B0:83:01:01:90:83:00:90:00",
NULL
/* Known ATRs */
static struct sc_atr_table gemsafe_atrs[] = {
/* standard version */
{"3B:7B:94:00:00:80:65:B0:83:01:01:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL},
{"3B:6B:00:00:80:65:B0:83:01:01:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL},
/* fips 140 version */
{"3B:6B:00:00:80:65:B0:83:01:03:74:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL},
/* Undefined */
{"3B:7A:94:00:00:80:65:A2:01:01:01:3D:72:D6:43", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL},
{"3B:7D:94:00:00:80:31:80:65:B0:83:01:01:90:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_GENERIC, 0, NULL},
/* Portuguese eID cards */
{"3B:7D:95:00:00:80:31:80:65:B0:83:11:C0:A9:83:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL},
{"3B:7D:95:00:00:80:31:80:65:B0:83:11:C0:A9:83:00:90:00", NULL, NULL, SC_CARD_TYPE_GEMSAFEV1_PTEID, 0, NULL},
{NULL, NULL, NULL, 0, 0, NULL}
};
static const u8 gemsafe_def_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x18, 0x0A,
0x00, 0x00, 0x01, 0x63, 0x42, 0x00};
static const u8 gemsafe_pteid_aid[] = {0x60, 0x46, 0x32, 0xFF, 0x00, 0x00, 0x02};
/*
static const u8 gemsafe_def_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50,
0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35};
@ -113,27 +121,12 @@ static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len)
return SC_SUCCESS;
}
static int gemsafe_match_card(struct sc_card *card)
static int gemsafe_match_card(sc_card_t *card)
{
int i, match = -1;
int i;
SC_FUNC_CALLED(card->ctx, 1);
for (i = 0; gemexpresso_atrs[i] != NULL; i++) {
u8 defatr[SC_MAX_ATR_SIZE];
size_t len = sizeof(defatr);
const char *atrp = gemexpresso_atrs[i];
if (sc_hex_to_bin(atrp, defatr, &len))
continue;
if (len != card->atr_len)
continue;
if (memcmp(card->atr, defatr, len) != 0)
continue;
match = i + 1;
break;
}
if (match == -1)
i = _sc_match_atr(card, gemsafe_atrs, &card->type);
if (i < 0)
return 0;
return 1;
@ -153,12 +146,17 @@ static int gemsafe_init(struct sc_card *card)
if (!exdata)
return SC_ERROR_OUT_OF_MEMORY;
exdata->aid_len = sizeof(exdata->aid);
/* try to get a AID from the config file */
r = get_conf_aid(card, exdata->aid, &exdata->aid_len);
if (r < 0) {
/* failed, use default value */
memcpy(exdata->aid, gemsafe_def_aid, sizeof(gemsafe_def_aid));
exdata->aid_len = sizeof(gemsafe_def_aid);
if(card->type == SC_CARD_TYPE_GEMSAFEV1_GENERIC) {
/* try to get a AID from the config file */
r = get_conf_aid(card, exdata->aid, &exdata->aid_len);
if (r < 0) {
/* failed, use default value */
memcpy(exdata->aid, gemsafe_def_aid, sizeof(gemsafe_def_aid));
exdata->aid_len = sizeof(gemsafe_def_aid);
}
} else if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
memcpy(exdata->aid, gemsafe_pteid_aid, sizeof(gemsafe_pteid_aid));
exdata->aid_len = sizeof(gemsafe_pteid_aid);
}
/* increase lock_count here to prevent sc_unlock to select
@ -343,18 +341,18 @@ static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file,
return SC_SUCCESS;
}
static u8 gemsafe_flags2algref(const struct sc_security_env *env)
static u8 gemsafe_flags2algref(struct sc_card *card, const struct sc_security_env *env)
{
u8 ret = 0;
if (env->operation == SC_SEC_OPERATION_SIGN) {
if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
ret = 0x12;
ret = card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID ? 0x02 : 0x12;
else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_ISO9796)
ret = 0x11;
} else if (env->operation == SC_SEC_OPERATION_DECIPHER) {
if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
ret = 0x12;
ret = card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID ? 0x02 : 0x12;
}
return ret;
@ -388,7 +386,7 @@ static int gemsafe_set_security_env(struct sc_card *card,
if (!(se_env.flags & SC_SEC_ENV_ALG_REF_PRESENT)) {
/* set the algorithm reference */
alg_ref = gemsafe_flags2algref(&se_env);
alg_ref = gemsafe_flags2algref(card, &se_env);
if (alg_ref) {
se_env.algorithm_ref = alg_ref;
se_env.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
@ -417,11 +415,16 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data,
return SC_ERROR_INVALID_ARGUMENTS;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0xAC);
apdu.cla |= 0x80;
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = 256;
/* the Portuguese eID card requires a two-phase exchange */
if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x2A, 0x90, 0xA0);
} else {
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0xAC);
apdu.cla |= 0x80;
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = 256;
}
/* we sign a digestInfo object => tag 0x90 */
sbuf[0] = 0x90;
sbuf[1] = (u8)data_len;
@ -429,11 +432,21 @@ static int gemsafe_compute_signature(struct sc_card *card, const u8 * data,
apdu.data = sbuf;
apdu.lc = data_len + 2;
apdu.datalen = data_len + 2;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
/* finalize the exchange */
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x2A, 0x9E, 0x9A);
apdu.le = 128; /* 1024 bit keys */
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if(apdu.sw1 != 0x90 || apdu.sw2 != 0x00)
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
int len = apdu.resplen > outlen ? outlen : apdu.resplen;
memcpy(out, apdu.resp, len);
@ -459,7 +472,6 @@ static int gemsafe_decipher(struct sc_card *card, const u8 * crgram,
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;
apdu.sensitive = 1;
apdu.data = crgram;
apdu.lc = crgram_len;
@ -475,6 +487,25 @@ static int gemsafe_decipher(struct sc_card *card, const u8 * crgram,
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
static int gemsafe_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
{
int prev_cla, r;
prev_cla = card->cla;
if(card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID) {
/* Warning: this depends on iso7816_get_challenge not
* changing the value of the card's CLA
*/
card->cla = 0x80;
}
r = iso_ops->get_challenge(card, rnd, len);
/* Restore the CLA value if needed */
if(card->cla != prev_cla)
card->cla = prev_cla;
return r;
}
static int gemsafe_build_pin_apdu(struct sc_card *card,
struct sc_apdu *apdu,
struct sc_pin_cmd_data *data)
@ -549,7 +580,6 @@ static int gemsafe_build_pin_apdu(struct sc_card *card,
apdu->datalen = len;
apdu->data = sbuf;
apdu->resplen = 0;
apdu->sensitive = 1;
return 0;
}
@ -586,7 +616,7 @@ static int gemsafe_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data,
/* Call the reader driver to collect
* the PIN and pass on the APDU to the card */
if (data->pin1.offset == 0) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Card driver didn't set PIN offset");
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -598,7 +628,7 @@ static int gemsafe_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data,
data);
/* sw1/sw2 filled in by reader driver */
} else {
sc_error(card->ctx,
sc_debug(card->ctx,
"Card reader driver does not support "
"PIN entry through reader key pad");
r = SC_ERROR_NOT_SUPPORTED;
@ -625,7 +655,7 @@ static struct sc_card_driver *sc_get_driver(void)
iso_ops = iso_drv->ops;
/* use the standard iso operations as default */
gemsafe_ops = *iso_drv->ops;
/* gemsafe specfic functions */
/* gemsafe specific functions */
gemsafe_ops.match_card = gemsafe_match_card;
gemsafe_ops.init = gemsafe_init;
gemsafe_ops.finish = gemsafe_finish;
@ -634,6 +664,7 @@ static struct sc_card_driver *sc_get_driver(void)
gemsafe_ops.set_security_env = gemsafe_set_security_env;
gemsafe_ops.decipher = gemsafe_decipher;
gemsafe_ops.compute_signature = gemsafe_compute_signature;
gemsafe_ops.get_challenge = gemsafe_get_challenge;
gemsafe_ops.process_fci = gemsafe_process_fci;
gemsafe_ops.pin_cmd = gemsafe_pin_cmd;

View File

@ -232,23 +232,23 @@ gpk_check_sw(sc_card_t *card, u8 sw1, u8 sw2)
unsigned short int sw = (sw1 << 8) | sw2;
if ((sw & 0xFFF0) == 0x63C0) {
sc_error(card->ctx, "wrong PIN, %u tries left\n", sw&0xf);
sc_debug(card->ctx, "wrong PIN, %u tries left\n", sw&0xf);
return SC_ERROR_PIN_CODE_INCORRECT;
}
switch (sw) {
case 0x6400:
sc_error(card->ctx, "wrong crypto context\n");
sc_debug(card->ctx, "wrong crypto context\n");
return SC_ERROR_OBJECT_NOT_VALID; /* XXX ??? */
/* The following are handled by iso7816_check_sw
* but all return SC_ERROR_UNKNOWN_DATA_RECEIVED
* XXX: fix in the iso driver? */
case 0x6983:
sc_error(card->ctx, "PIN is blocked\n");
sc_debug(card->ctx, "PIN is blocked\n");
return SC_ERROR_PIN_CODE_INCORRECT;
case 0x6581:
sc_error(card->ctx, "out of space on card or file\n");
sc_debug(card->ctx, "out of space on card or file\n");
return SC_ERROR_OUT_OF_MEMORY;
case 0x6981:
return SC_ERROR_FILE_NOT_FOUND;
@ -577,9 +577,7 @@ gpk_select_id(sc_card_t *card, int kind, unsigned int fid,
fbuf[0] = fid >> 8;
fbuf[1] = fid & 0xff;
sc_ctx_suppress_errors_on(card->ctx);
r = gpk_select(card, kind, fbuf, 2, file);
sc_ctx_suppress_errors_off(card->ctx);
/* Fix up the path cache.
* NB we never cache the ID of an EF, just the DF path */
@ -724,7 +722,7 @@ gpk_read_binary(sc_card_t *card, unsigned int offset,
struct gpk_private_data *priv = DRVDATA(card);
if (offset & priv->offset_mask) {
sc_error(card->ctx, "Invalid file offset (not a multiple of %d)",
sc_debug(card->ctx, "Invalid file offset (not a multiple of %d)",
priv->offset_mask + 1);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -739,7 +737,7 @@ gpk_write_binary(sc_card_t *card, unsigned int offset,
struct gpk_private_data *priv = DRVDATA(card);
if (offset & priv->offset_mask) {
sc_error(card->ctx, "Invalid file offset (not a multiple of %d)",
sc_debug(card->ctx, "Invalid file offset (not a multiple of %d)",
priv->offset_mask + 1);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -754,7 +752,7 @@ gpk_update_binary(sc_card_t *card, unsigned int offset,
struct gpk_private_data *priv = DRVDATA(card);
if (offset & priv->offset_mask) {
sc_error(card->ctx, "Invalid file offset (not a multiple of %d)",
sc_debug(card->ctx, "Invalid file offset (not a multiple of %d)",
priv->offset_mask + 1);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -996,7 +994,6 @@ gpk_select_key(sc_card_t *card, int key_sfi, const u8 *buf, size_t buflen)
apdu.resp = resp;
apdu.resplen = sizeof(resp);
apdu.le = 12;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@ -1046,7 +1043,7 @@ gpk_set_security_env(sc_card_t *card,
if (env->flags & SC_SEC_ENV_ALG_PRESENT)
algorithm = env->algorithm;
if (algorithm != SC_ALGORITHM_RSA) {
sc_error(card->ctx, "Algorithm not supported.\n");
sc_debug(card->ctx, "Algorithm not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
priv->sec_algorithm = algorithm;
@ -1054,7 +1051,7 @@ gpk_set_security_env(sc_card_t *card,
/* If there's a key reference, it must be 0 */
if ((env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
&& (env->key_ref_len != 1 || env->key_ref[0] != 0)) {
sc_error(card->ctx, "Unknown key referenced.\n");
sc_debug(card->ctx, "Unknown key referenced.\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -1067,7 +1064,7 @@ gpk_set_security_env(sc_card_t *card,
else if (env->flags & SC_ALGORITHM_RSA_PAD_ISO9796)
priv->sec_padding = 2;
else {
sc_error(card->ctx, "Padding algorithm not supported.\n");
sc_debug(card->ctx, "Padding algorithm not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -1090,7 +1087,7 @@ gpk_set_security_env(sc_card_t *card,
context = GPK_SIGN_RSA_MD5;
priv->sec_hash_len = 16;
} else {
sc_error(card->ctx, "Unsupported signature algorithm");
sc_debug(card->ctx, "Unsupported signature algorithm");
return SC_ERROR_NOT_SUPPORTED;
}
break;
@ -1098,20 +1095,20 @@ gpk_set_security_env(sc_card_t *card,
context = GPK_UNWRAP_RSA;
break;
default:
sc_error(card->ctx, "Crypto operation not supported.\n");
sc_debug(card->ctx, "Crypto operation not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
/* Get the file ID */
if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT) {
if (env->file_ref.len != 2) {
sc_error(card->ctx, "File reference: invalid length.\n");
sc_debug(card->ctx, "File reference: invalid length.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
file_id = (env->file_ref.value[0] << 8)
| env->file_ref.value[1];
} else {
sc_error(card->ctx, "File reference missing.\n");
sc_debug(card->ctx, "File reference missing.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -1125,11 +1122,11 @@ gpk_set_security_env(sc_card_t *card,
SC_RECORD_BY_REC_NR);
SC_TEST_RET(card->ctx, r, "Failed to read PK sysrec");
if (r != 7 || sysrec[0] != 0) {
sc_error(card->ctx, "First record of file is not the sysrec");
sc_debug(card->ctx, "First record of file is not the sysrec");
return SC_ERROR_OBJECT_NOT_VALID;
}
if (sysrec[5] != 0x00) {
sc_error(card->ctx, "Public key is not an RSA key");
sc_debug(card->ctx, "Public key is not an RSA key");
return SC_ERROR_OBJECT_NOT_VALID;
}
switch (sysrec[1]) {
@ -1137,7 +1134,7 @@ gpk_set_security_env(sc_card_t *card,
case 0x10: priv->sec_mod_len = 768 / 8; break;
case 0x11: priv->sec_mod_len = 1024 / 8; break;
default:
sc_error(card->ctx, "Unsupported modulus length");
sc_debug(card->ctx, "Unsupported modulus length");
return SC_ERROR_OBJECT_NOT_VALID;
}
@ -1269,7 +1266,7 @@ gpk_compute_signature(sc_card_t *card, const u8 *data,
int r;
if (data_len > priv->sec_mod_len) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Data length (%u) does not match key modulus %u.\n",
data_len, priv->sec_mod_len);
return SC_ERROR_INTERNAL;
@ -1330,7 +1327,7 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen,
int r;
if (inlen != priv->sec_mod_len) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Data length (%u) does not match key modulus %u.\n",
inlen, priv->sec_mod_len);
return SC_ERROR_INVALID_ARGUMENTS;
@ -1349,7 +1346,6 @@ gpk_decipher(sc_card_t *card, const u8 *in, size_t inlen,
apdu.le = 256; /* give me all you got :) */
apdu.resp = buffer;
apdu.resplen = sizeof(buffer);
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@ -1517,7 +1513,7 @@ gpk_generate_key(sc_card_t *card, struct sc_cardctl_gpk_genkey *args)
if (card->ctx->debug)
sc_debug(card->ctx, "gpk_generate_key(%u)\n", args->privlen);
if (args->privlen != 512 && args->privlen != 1024) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Key generation not supported for key length %d",
args->privlen);
return SC_ERROR_NOT_SUPPORTED;
@ -1584,12 +1580,11 @@ gpk_pkfile_load(sc_card_t *card, struct sc_cardctl_gpk_pkload *args)
apdu.p1 = args->file->id & 0x1F;
apdu.p2 = args->len;
apdu.lc = args->datalen;
apdu.sensitive = 1;
/* encrypt the private key material */
assert(args->datalen <= sizeof(temp));
if (!priv->key_set) {
sc_error(card->ctx, "No secure messaging key set!\n");
sc_debug(card->ctx, "No secure messaging key set!\n");
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
}
@ -1694,7 +1689,7 @@ static int gpk_get_info(sc_card_t *card, int p1, int p2, u8 *buf,
apdu.resplen = buflen;
if ((r = sc_transmit_apdu(card, &apdu)) < 0) {
sc_error(card->ctx, "APDU transmit failed: %s",
sc_debug(card->ctx, "APDU transmit failed: %s",
sc_strerror(r));
sc_unlock(card);
return r;
@ -1838,7 +1833,6 @@ gpk_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu, struct sc_pin_cmd_data *dat
apdu->lc = 8;
apdu->datalen = 8;
apdu->data = sbuf;
apdu->sensitive = 1;
return 0;
}

543
src/libopensc/card-ias.c Normal file
View File

@ -0,0 +1,543 @@
/*
* Driver for IAS based cards, e.g. Portugal's eID card.
*
* Copyright (C) 2009, Joao Poupino <joao.poupino@ist.utl.pt>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Partially based on the ISO7816 driver.
*
* Thanks to Andre Cruz, Jorge Ferreira and Paulo F. Andrade
*/
#include "internal.h"
#include "cardctl.h"
#include "asn1.h"
#include <stdlib.h>
#include <string.h>
/* Portugal eID uses 1024 bit keys */
#define PTEID_RSA_KEYSIZE 128
#define DRVDATA(card) ((struct ias_priv_data *) ((card)->drv_data))
static struct sc_card_operations ias_ops;
static struct sc_card_operations *iso_ops = NULL;
static struct sc_card_driver ias_drv = {
"IAS",
"ias",
&ias_ops,
NULL, 0, NULL
};
/* Known ATRs */
static struct sc_atr_table ias_atrs[] = {
/* Portugal eID cards */
{"3B:65:00:00:D0:00:54:01:31", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL},
{"3B:65:00:00:D0:00:54:01:32", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL},
{"3B:95:95:40:FF:D0:00:54:01:31", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL},
{"3B:95:95:40:FF:D0:00:54:01:32", NULL, NULL, SC_CARD_TYPE_IAS_PTEID, 0, NULL},
{NULL, NULL, NULL, 0, 0, NULL}
};
/* Known AIDs */
static const u8 ias_aid_pteid[] = {0x60, 0x46, 0x32, 0xFF, 0x00, 0x01, 0x02};
static int ias_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len)
{
int r;
sc_path_t tpath;
tpath.type = SC_PATH_TYPE_DF_NAME;
tpath.len = aid_len;
memcpy(tpath.value, aid, aid_len);
r = iso_ops->select_file(card, &tpath, NULL);
if (r != SC_SUCCESS) {
sc_debug(card->ctx, "unable to select applet");
return r;
}
return SC_SUCCESS;
}
static int ias_init(sc_card_t *card)
{
unsigned long flags;
assert(card != NULL);
SC_FUNC_CALLED(card->ctx, 1);
card->name = "IAS";
card->cla = 0x00;
/* Card version detection */
if (card->type == SC_CARD_TYPE_IAS_PTEID) {
int r = ias_select_applet(card, ias_aid_pteid, sizeof(ias_aid_pteid));
if (r != SC_SUCCESS)
return r;
/* Add other cards if necessary */
} else {
return SC_ERROR_INTERNAL;
}
/* Set card capabilities */
card->caps |= SC_CARD_CAP_RNG;
/* Set the supported algorithms */
flags = SC_ALGORITHM_RSA_PAD_PKCS1 |
SC_ALGORITHM_RSA_HASH_NONE;
/* Only 1024 bit key sizes were tested */
_sc_card_add_rsa_alg(card, 1024, flags, 0);
return SC_SUCCESS;
}
static int ias_match_card(sc_card_t *card)
{
int i;
i = _sc_match_atr(card, ias_atrs, &card->type);
if (i < 0)
return 0;
return 1;
}
static int ias_build_pin_apdu(sc_card_t *card,
sc_apdu_t *apdu,
struct sc_pin_cmd_data *data)
{
static u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
int r, len, pad, use_pin_pad, ins, p1;
r = len = pad = use_pin_pad = ins = p1 = 0;
assert(card != NULL);
switch (data->pin_type) {
case SC_AC_CHV:
break;
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
if (data->flags & SC_PIN_CMD_USE_PINPAD)
use_pin_pad = 1;
/* "needs-padding" necessary for the PTEID card,
* but not defined in the pin structure
*/
if ((data->flags & SC_PIN_CMD_NEED_PADDING) ||
card->type == SC_CARD_TYPE_IAS_PTEID)
pad = 1;
data->pin1.offset = 5;
switch (data->cmd) {
case SC_PIN_CMD_VERIFY:
ins = 0x20;
if ( (r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0)
return r;
len = r;
break;
case SC_PIN_CMD_CHANGE:
ins = 0x24;
if ((data->flags & SC_PIN_CMD_IMPLICIT_CHANGE) == 0 &&
(data->pin1.len != 0 || use_pin_pad)) {
if ( (r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0)
return r;
len += r;
} else {
/* implicit test */
p1 = 1;
}
data->pin2.offset = data->pin1.offset + len;
if ( (r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0)
return r;
len += r;
break;
case SC_PIN_CMD_UNBLOCK:
ins = 0x2C;
if (data->pin1.len != 0 || use_pin_pad) {
if ( (r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0)
return r;
len += r;
} else {
p1 |= 0x02;
}
if (data->pin2.len != 0 || use_pin_pad) {
data->pin2.offset = data->pin1.offset + len;
if ( (r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0)
return r;
len += r;
} else {
p1 |= 0x01;
}
break;
default:
return SC_ERROR_NOT_SUPPORTED;
}
sc_format_apdu(card, apdu, SC_APDU_CASE_3_SHORT, ins, p1, data->pin_reference);
apdu->lc = len;
apdu->datalen = len;
apdu->data = sbuf;
apdu->resplen = 0;
return SC_SUCCESS;
}
static int ias_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
int *tries_left)
{
int r;
sc_apdu_t local_apdu;
SC_FUNC_CALLED(card->ctx, 1);
/* Check if a PIN change operation is being requested,
* as it requires sending two separate APDUs
*/
if (data->cmd == SC_PIN_CMD_CHANGE) {
/* Build a SC_PIN_CMD_VERIFY APDU */
data->cmd = SC_PIN_CMD_VERIFY;
r = ias_build_pin_apdu(card, &local_apdu, data);
if (r < 0)
return r;
data->apdu = &local_apdu;
r = iso_ops->pin_cmd(card, data, tries_left);
if (r < 0)
return r;
/* Continue processing */
data->cmd = SC_PIN_CMD_CHANGE;
/* The IAS spec mandates an implicit change PIN operation */
data->flags |= SC_PIN_CMD_IMPLICIT_CHANGE;
}
r = ias_build_pin_apdu(card, &local_apdu, data);
if (r < 0)
return r;
data->apdu = &local_apdu;
return iso_ops->pin_cmd(card, data, tries_left);
}
static int ias_set_security_env(sc_card_t *card,
const sc_security_env_t *env, int se_num)
{
int r;
sc_apdu_t apdu;
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
sc_debug(card->ctx, "ias_set_security_env, keyRef = 0x%0x, algo = 0x%0x\n",
*env->key_ref, env->algorithm_flags);
assert(card != NULL && env != NULL);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
switch (env->operation) {
case SC_SEC_OPERATION_DECIPHER:
apdu.p2 = 0xB8; /* confidentiality template */
sbuf[0] = 0x95; /* tag for usage qualifier byte */
sbuf[1] = 0x01; /* tag length */
sbuf[2] = 0x40; /* data decryption */
sbuf[3] = 0x84; /* tag for private key reference */
sbuf[4] = 0x01; /* tag length */
sbuf[5] = *env->key_ref; /* key reference */
sbuf[6] = 0x80; /* tag for algorithm reference */
sbuf[7] = 0x01; /* tag length */
if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
sbuf[8] = 0x1A; /* RSA PKCS#1 with no data formatting */
else {
sc_debug(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n",
env->algorithm_flags);
return SC_ERROR_INVALID_ARGUMENTS;
}
apdu.lc = 9;
apdu.datalen = 9;
break;
case SC_SEC_OPERATION_SIGN:
apdu.p2 = 0xA4; /* authentication template */
sbuf[0] = 0x95; /* tag for usage qualifier byte */
sbuf[1] = 0x01; /* tag length */
sbuf[2] = 0x40; /* internal authentication */
sbuf[3] = 0x84; /* tag for private key reference */
sbuf[4] = 0x01; /* tag length */
sbuf[5] = *env->key_ref; /* key reference */
sbuf[6] = 0x80; /* tag for algorithm reference */
sbuf[7] = 0x01; /* tag length */
if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
sbuf[8] = 0x02; /* RSA PKCS#1 with no data formatting */
else {
sc_debug(card->ctx, "Set Sec Env: unsupported algo 0X%0X\n",
env->algorithm_flags);
return SC_ERROR_INVALID_ARGUMENTS;
}
apdu.lc = 9;
apdu.datalen = 9;
break;
default:
return SC_ERROR_INVALID_ARGUMENTS;
}
apdu.le = 0;
apdu.data = sbuf;
apdu.resplen = 0;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "Set Security Env APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
SC_TEST_RET(card->ctx, r, "Card's Set Security Env command returned error");
return r;
}
static int ias_compute_signature(sc_card_t *card, const u8 * data,
size_t data_len, u8 * out, size_t outlen)
{
int r;
size_t len = 0;
sc_apdu_t apdu;
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
sc_context_t *ctx = card->ctx;
SC_FUNC_CALLED(ctx, 1);
if (data_len > 64) {
sc_debug(ctx, "error: input data too long: %lu bytes\n", data_len);
return SC_ERROR_INVALID_ARGUMENTS;
}
/* Send the data */
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x88, 0x02, 0x00);
memcpy(sbuf, data, data_len);
apdu.data = sbuf;
apdu.lc = data_len;
apdu.datalen = data_len;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
/* Get the result */
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
len = card->type == SC_CARD_TYPE_IAS_PTEID ? PTEID_RSA_KEYSIZE : outlen;
r = iso_ops->get_response(card, &len, out);
if (r == 0)
SC_FUNC_RETURN(card->ctx, 2, len);
else
SC_FUNC_RETURN(card->ctx, 2, r);
}
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
static int ias_select_file(sc_card_t *card, const sc_path_t *in_path,
sc_file_t **file_out)
{
int r, pathlen, stripped_len, offset;
u8 buf[SC_MAX_APDU_BUFFER_SIZE];
u8 pathbuf[SC_MAX_PATH_SIZE], *path;
sc_context_t *ctx;
sc_apdu_t apdu;
sc_file_t *file;
r = pathlen = stripped_len = offset = 0;
path = pathbuf;
file = NULL;
assert(card != NULL && in_path != NULL);
ctx = card->ctx;
if (in_path->len > SC_MAX_PATH_SIZE)
return SC_ERROR_INVALID_ARGUMENTS;
memcpy(path, in_path->value, in_path->len);
pathlen = in_path->len;
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
apdu.p2 = 0; /* First record, return FCI */
switch (in_path->type) {
case SC_PATH_TYPE_FILE_ID:
apdu.p1 = 2;
if (pathlen != 2)
return SC_ERROR_INVALID_ARGUMENTS;
break;
case SC_PATH_TYPE_DF_NAME:
apdu.p1 = 4;
break;
case SC_PATH_TYPE_PATH:
apdu.p1 = 9;
/* Strip the MF */
if (pathlen >= 2 && memcmp(path, "\x3f\x00", 2) == 0) {
if (pathlen == 2) { /* Only 3f00 provided */
apdu.p1 = 0;
break;
}
path += 2;
pathlen -= 2;
}
/* Optimization based on the normal Portuguese eID usage pattern:
* paths with len >= 4 shall be stripped - this avoids unnecessary
* "file not found" errors. Other cards may benefit from this also.
*
* This works perfectly for the Portuguese eID card, but if you
* are adapting this driver to another card, "false positives" may
* occur depending, of course, on the file structure of the card.
*
* Please have this in mind if adapting this driver to another card.
*/
if (pathlen >= 4) {
stripped_len = pathlen - 2;
path += stripped_len;
pathlen = 2;
} else if (pathlen == 2) {
apdu.p1 = 0;
}
break;
case SC_PATH_TYPE_FROM_CURRENT:
apdu.p1 = 9;
break;
case SC_PATH_TYPE_PARENT:
apdu.p1 = 3;
apdu.p2 = 0x0C;
pathlen = 0;
apdu.cse = SC_APDU_CASE_2_SHORT;
break;
default:
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
}
apdu.lc = pathlen;
apdu.data = path;
apdu.datalen = pathlen;
if (file_out != NULL) {
apdu.resp = buf;
apdu.resplen = sizeof(buf);
apdu.le = 256;
} else {
apdu.p2 = 0x0C;
apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
}
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (file_out == NULL) {
if (apdu.sw1 == 0x61)
SC_FUNC_RETURN(card->ctx, 2, 0);
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
/* A "file not found" error was received, this can mean two things:
* 1) the file does not exist
* 2) the current DF may be incorrect due to the optimization applied
* earlier. If the path was previously stripped, select the first DF
* and try to re-select the path with the full value.
*/
if (stripped_len > 0 && apdu.sw1 == 0x6A && apdu.sw2 == 0x82) {
sc_file_t *file = NULL;
sc_path_t tpath;
/* Restore original path value */
path -= stripped_len;
pathlen += stripped_len;
memset(&tpath, 0, sizeof(sc_path_t));
tpath.type = SC_PATH_TYPE_PATH;
tpath.len = 2;
if(path[0] == 0x3f && path[1] == 0x00)
offset = 2;
else
offset = 0;
tpath.value[0] = path[offset];
tpath.value[1] = path[offset + 1];
/* Go up in the hierarchy to the correct DF */
r = ias_select_file(card, &tpath, &file);
SC_TEST_RET(card->ctx, r, "Error selecting parent.");
if(file->type != SC_FILE_TYPE_DF)
return SC_ERROR_FILE_NOT_FOUND;
/* We're now in the right place, reconstruct the APDU and retry */
path += offset + 2;
pathlen -= offset + 2;
apdu.lc = pathlen;
apdu.data = path;
apdu.datalen = pathlen;
if (file_out != NULL)
apdu.resplen = sizeof(buf);
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (file_out == NULL) {
if (apdu.sw1 == 0x61)
SC_FUNC_RETURN(card->ctx, 2, 0);
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
}
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (r)
SC_FUNC_RETURN(card->ctx, 2, r);
if (apdu.resplen < 2)
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED);
switch (apdu.resp[0]) {
case 0x6F:
file = sc_file_new();
if (file == NULL)
SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_OUT_OF_MEMORY);
file->path = *in_path;
if (card->ops->process_fci == NULL) {
sc_file_free(file);
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
}
if ((size_t)apdu.resp[1] + 2 <= apdu.resplen)
card->ops->process_fci(card, file, apdu.resp+2, apdu.resp[1]);
*file_out = file;
break;
case 0x00: /* proprietary coding */
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED);
default:
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_UNKNOWN_DATA_RECEIVED);
}
return SC_SUCCESS;
}
static struct sc_card_driver *sc_get_driver(void)
{
struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
if (iso_ops == NULL)
iso_ops = iso_drv->ops;
/* Use the standard iso operations as default */
ias_ops = *iso_drv->ops;
/* IAS specific functions */
ias_ops.select_file = ias_select_file;
ias_ops.match_card = ias_match_card;
ias_ops.init = ias_init;
ias_ops.set_security_env = ias_set_security_env;
ias_ops.compute_signature = ias_compute_signature;
ias_ops.pin_cmd = ias_pin_cmd;
return &ias_drv;
}
struct sc_card_driver *sc_get_ias_driver(void)
{
return sc_get_driver();
}

View File

@ -49,11 +49,6 @@ static struct sc_atr_table incrypto34_atrs[] = {
{ NULL, NULL, NULL, 0, 0, NULL }
};
static int incrypto34_finish(struct sc_card *card)
{
return 0;
}
static int incrypto34_match_card(struct sc_card *card)
{
int i;
@ -154,13 +149,13 @@ static int incrypto34_check_sw(sc_card_t *card, unsigned int sw1, unsigned int s
for (i = 0; i < err_count; i++) {
if (incrypto34_errors[i].SWs == ((sw1 << 8) | sw2)) {
if ( incrypto34_errors[i].errorstr )
sc_error(card->ctx, "%s\n",
sc_debug(card->ctx, "%s\n",
incrypto34_errors[i].errorstr);
return incrypto34_errors[i].errorno;
}
}
sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
return SC_ERROR_CARD_CMD_FAILED;
}
@ -392,7 +387,7 @@ static int incrypto34_create_file(sc_card_t *card, sc_file_t *file)
byte = acl_to_byte(
sc_file_get_acl_entry(file, idx[i]));
if (byte < 0) {
sc_error(card->ctx, "Invalid ACL\n");
sc_debug(card->ctx, "Invalid ACL\n");
r = SC_ERROR_INVALID_ARGUMENTS;
goto out;
}
@ -452,7 +447,7 @@ static int incrypto34_set_security_env(sc_card_t *card,
if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
|| env->key_ref_len != 1) {
sc_error(card->ctx, "No or invalid key reference\n");
sc_debug(card->ctx, "No or invalid key reference\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
key_id = env->key_ref[0];
@ -516,7 +511,6 @@ static int do_compute_signature(sc_card_t *card,
apdu.data = sbuf;
apdu.lc = datalen;
apdu.datalen = datalen;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@ -553,9 +547,7 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
*/
if (ctx->debug >= 3)
sc_debug(ctx, "trying RSA_PURE_SIG (padded DigestInfo)\n");
sc_ctx_suppress_errors_on(ctx);
r = do_compute_signature(card, data, datalen, out, outlen);
sc_ctx_suppress_errors_off(ctx);
if (r >= SC_SUCCESS)
SC_FUNC_RETURN(ctx, 4, r);
if (ctx->debug >= 3)
@ -574,9 +566,7 @@ incrypto34_compute_signature(sc_card_t *card, const u8 *data, size_t datalen,
}
memcpy(buf, p, tmp_len);
}
sc_ctx_suppress_errors_on(ctx);
r = do_compute_signature(card, buf, tmp_len, out, outlen);
sc_ctx_suppress_errors_off(ctx);
if (r >= SC_SUCCESS)
SC_FUNC_RETURN(ctx, 4, r);
if (ctx->debug >= 3)
@ -624,7 +614,7 @@ incrypto34_lifecycle_get(sc_card_t *card, int *mode)
*mode = SC_CARDCTRL_LIFECYCLE_OTHER;
break;
default:
sc_error(card->ctx, "Unknown lifecycle byte %d", rbuf[0]);
sc_debug(card->ctx, "Unknown lifecycle byte %d", rbuf[0]);
r = SC_ERROR_INTERNAL;
}
@ -914,7 +904,6 @@ static struct sc_card_driver * sc_get_driver(void)
incrypto34_ops = *iso_ops;
incrypto34_ops.match_card = incrypto34_match_card;
incrypto34_ops.init = incrypto34_init;
incrypto34_ops.finish = incrypto34_finish;
incrypto34_ops.select_file = incrypto34_select_file;
incrypto34_ops.create_file = incrypto34_create_file;
incrypto34_ops.set_security_env = incrypto34_set_security_env;

View File

@ -328,9 +328,7 @@ static int jcop_read_binary(sc_card_t *card, unsigned int idx,
if (idx + count > 128) {
count=128-idx;
}
sc_ctx_suppress_errors_on(card->ctx);
r = iso_ops->select_file(card, &drvdata->aid, &tfile);
sc_ctx_suppress_errors_off(card->ctx);
if (r < 0) { /* no pkcs15 app, so return empty DIR. */
memset(buf, 0, count);
} else {
@ -356,9 +354,7 @@ static int jcop_list_files(sc_card_t *card, u8 *buf, size_t buflen) {
if (buflen < 4)
return 2;
/* AppDF only exists if applet is selectable */
sc_ctx_suppress_errors_on(card->ctx);
r = iso_ops->select_file(card, &drvdata->aid, &tfile);
sc_ctx_suppress_errors_off(card->ctx);
if (r < 0) {
return 2;
} else {
@ -650,11 +646,11 @@ static int jcop_set_security_env(sc_card_t *card,
tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT;
tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
if (tmp.algorithm != SC_ALGORITHM_RSA) {
sc_error(card->ctx, "Only RSA algorithm supported.\n");
sc_debug(card->ctx, "Only RSA algorithm supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (!(env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)){
sc_error(card->ctx, "Card requires RSA padding\n");
sc_debug(card->ctx, "Card requires RSA padding\n");
return SC_ERROR_NOT_SUPPORTED;
}
tmp.algorithm_ref = 0x02;
@ -755,7 +751,6 @@ static int jcop_compute_signature(sc_card_t *card,
}
apdu.data = sbuf;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
@ -793,7 +788,6 @@ static int jcop_decipher(sc_card_t *card,
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf); /* FIXME */
apdu.le = crgram_len;
apdu.sensitive = 1;
if (crgram_len == 256) {
apdu.p2 = crgram[0];

View File

@ -758,9 +758,7 @@ select_part(sc_card_t * card, u8 kind, unsigned short int fid,
fbuf[0] = fid >> 8;
fbuf[1] = fid & 0xff;
sc_ctx_suppress_errors_on(card->ctx);
r = do_select(card, kind, fbuf, 2, file);
sc_ctx_suppress_errors_off(card->ctx);
return r;
}
@ -1313,8 +1311,6 @@ static int mcrd_decipher(sc_card_t * card,
apdu.datalen = crgram_len;
apdu.lc = apdu.datalen;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);

View File

@ -40,11 +40,6 @@ static struct sc_card_driver miocos_drv = {
NULL, 0, NULL
};
static int miocos_finish(sc_card_t *card)
{
return 0;
}
static int miocos_match_card(sc_card_t *card)
{
int i;
@ -141,7 +136,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
*p++ = 0x43;
break;
default:
sc_error(card->ctx, "Invalid EF structure\n");
sc_debug(card->ctx, "Invalid EF structure\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
ops = ef_ops;
@ -151,7 +146,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
ops = key_ops;
break;
default:
sc_error(card->ctx, "Unknown file type\n");
sc_debug(card->ctx, "Unknown file type\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (file->type == SC_FILE_TYPE_DF) {
@ -172,7 +167,7 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
else {
int byte = acl_to_byte(sc_file_get_acl_entry(file, ops[i]));
if (byte < 0) {
sc_error(card->ctx, "Invalid ACL\n");
sc_debug(card->ctx, "Invalid ACL\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
nibble = byte;
@ -239,7 +234,7 @@ static int miocos_set_security_env(sc_card_t *card,
tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT;
tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
if (tmp.algorithm != SC_ALGORITHM_RSA) {
sc_error(card->ctx, "Only RSA algorithm supported.\n");
sc_debug(card->ctx, "Only RSA algorithm supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
tmp.algorithm_ref = 0x00;
@ -418,7 +413,7 @@ static int miocos_delete_file(sc_card_t *card, const sc_path_t *path)
SC_FUNC_CALLED(card->ctx, 1);
if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) {
sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
r = sc_select_file(card, path, NULL);
@ -456,7 +451,7 @@ static int miocos_create_ac(sc_card_t *card,
sendsize = 20;
break;
default:
sc_error(card->ctx, "AC type %d not supported\n", ac->type);
sc_debug(card->ctx, "AC type %d not supported\n", ac->type);
return SC_ERROR_NOT_SUPPORTED;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x1E, miocos_type,
@ -476,7 +471,7 @@ static int miocos_card_ctl(sc_card_t *card, unsigned long cmd,
case SC_CARDCTL_MIOCOS_CREATE_AC:
return miocos_create_ac(card, (struct sc_cardctl_miocos_ac_info *) arg);
}
sc_error(card->ctx, "card_ctl command 0x%X not supported\n", cmd);
sc_debug(card->ctx, "card_ctl command 0x%X not supported\n", cmd);
return SC_ERROR_NOT_SUPPORTED;
}
@ -488,7 +483,6 @@ static struct sc_card_driver * sc_get_driver(void)
miocos_ops = *iso_drv->ops;
miocos_ops.match_card = miocos_match_card;
miocos_ops.init = miocos_init;
miocos_ops.finish = miocos_finish;
if (iso_ops == NULL)
iso_ops = iso_drv->ops;
miocos_ops.create_file = miocos_create_file;

View File

@ -75,9 +75,7 @@ static int muscle_match_card(sc_card_t *card)
* however it's not always properly nulled out... */
card->ops->logout = NULL;
sc_ctx_suppress_errors_on(card->ctx);
i = msc_select_applet(card, muscleAppletId, 5);
sc_ctx_suppress_errors_off(card->ctx);
/* Mark the card for muscle_init */
card->drv_data = (void*)0xFFFFFFFF;
return i;
@ -282,14 +280,12 @@ static int muscle_delete_mscfs_file(sc_card_t *card, mscfs_file_t *file_data)
}
if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4))
|| (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4))) {
sc_ctx_suppress_errors_on(card->ctx);
}
r = msc_delete_object(card, id, 1);
/* Check if its the root... this file generally is virtual
* So don't return an error if it fails */
if((0 == memcmp(oid, "\x3F\x00\x00\x00", 4))
|| (0 == memcmp(oid, "\x3F\x00\x3F\x00", 4)))
sc_ctx_suppress_errors_off(card->ctx);
return 0;
if(r < 0) {
@ -560,7 +556,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd,
case SC_AC_AUT:
case SC_AC_NONE:
default:
sc_error(card->ctx, "Unsupported authentication method\n");
sc_debug(card->ctx, "Unsupported authentication method\n");
return SC_ERROR_NOT_SUPPORTED;
}
case SC_PIN_CMD_CHANGE:
@ -576,7 +572,7 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd,
case SC_AC_AUT:
case SC_AC_NONE:
default:
sc_error(card->ctx, "Unsupported authentication method\n");
sc_debug(card->ctx, "Unsupported authentication method\n");
return SC_ERROR_NOT_SUPPORTED;
}
case SC_PIN_CMD_UNBLOCK:
@ -592,11 +588,11 @@ static int muscle_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *cmd,
case SC_AC_AUT:
case SC_AC_NONE:
default:
sc_error(card->ctx, "Unsupported authentication method\n");
sc_debug(card->ctx, "Unsupported authentication method\n");
return SC_ERROR_NOT_SUPPORTED;
}
default:
sc_error(card->ctx, "Unsupported command\n");
sc_debug(card->ctx, "Unsupported command\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -673,34 +669,34 @@ static int muscle_set_security_env(sc_card_t *card,
if (env->operation != SC_SEC_OPERATION_SIGN &&
env->operation != SC_SEC_OPERATION_DECIPHER) {
sc_error(card->ctx, "Invalid crypto operation supplied.\n");
sc_debug(card->ctx, "Invalid crypto operation supplied.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (env->algorithm != SC_ALGORITHM_RSA) {
sc_error(card->ctx, "Invalid crypto algorithm supplied.\n");
sc_debug(card->ctx, "Invalid crypto algorithm supplied.\n");
return SC_ERROR_NOT_SUPPORTED;
}
/* ADJUST FOR PKCS1 padding support for decryption only */
if ((env->algorithm_flags & SC_ALGORITHM_RSA_PADS) ||
(env->algorithm_flags & SC_ALGORITHM_RSA_HASHES)) {
sc_error(card->ctx, "Card supports only raw RSA.\n");
sc_debug(card->ctx, "Card supports only raw RSA.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
if (env->key_ref_len != 1 ||
(env->key_ref[0] > 0x0F)) {
sc_error(card->ctx, "Invalid key reference supplied.\n");
sc_debug(card->ctx, "Invalid key reference supplied.\n");
return SC_ERROR_NOT_SUPPORTED;
}
priv->rsa_key_ref = env->key_ref[0];
}
if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT) {
sc_error(card->ctx, "Algorithm reference not supported.\n");
sc_debug(card->ctx, "Algorithm reference not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
/* if (env->flags & SC_SEC_ENV_FILE_REF_PRESENT)
if (memcmp(env->file_ref.value, "\x00\x12", 2) != 0) {
sc_error(card->ctx, "File reference is not 0012.\n");
sc_debug(card->ctx, "File reference is not 0012.\n");
return SC_ERROR_NOT_SUPPORTED;
} */
priv->env = *env;
@ -731,7 +727,7 @@ static int muscle_decipher(sc_card_t * card,
key_id = priv->rsa_key_ref * 2; /* Private key */
if (out_len < crgram_len) {
sc_error(card->ctx, "Output buffer too small");
sc_debug(card->ctx, "Output buffer too small");
return SC_ERROR_BUFFER_TOO_SMALL;
}
@ -757,7 +753,7 @@ static int muscle_compute_signature(sc_card_t *card, const u8 *data,
key_id = priv->rsa_key_ref * 2; /* Private key */
if (outlen < data_len) {
sc_error(card->ctx, "Output buffer too small");
sc_debug(card->ctx, "Output buffer too small");
return SC_ERROR_BUFFER_TOO_SMALL;
}

View File

@ -25,19 +25,19 @@
#include <string.h>
#include <stdlib.h>
#define LOAD_KEY_MODULUS 0x80
#define LOAD_KEY_PUBLIC_EXPONENT 0x81
#define LOAD_KEY_PRIME_P 0x83
#define LOAD_KEY_PRIME_Q 0x84
#define LOAD_KEY_DP1 0x85
#define LOAD_KEY_DQ1 0x86
#define LOAD_KEY_INVQ 0x87
#define LOAD_KEY_MODULUS 0x80
#define LOAD_KEY_PUBLIC_EXPONENT 0x81
#define LOAD_KEY_PRIME_P 0x83
#define LOAD_KEY_PRIME_Q 0x84
#define LOAD_KEY_DP1 0x85
#define LOAD_KEY_DQ1 0x86
#define LOAD_KEY_INVQ 0x87
static struct sc_card_operations myeid_ops;
static struct sc_card_driver myeid_drv = {
"MyEID cards with PKCS#15 applet",
"myeid",
&myeid_ops
&myeid_ops
};
static const char *myeid_atrs[] = {
@ -46,12 +46,6 @@ static const char *myeid_atrs[] = {
NULL
};
static int myeid_finish(struct sc_card *card)
{
return 0;
}
static int myeid_match_card(struct sc_card *card)
{
int i, match = -1;
@ -89,7 +83,7 @@ static int myeid_init(struct sc_card *card)
/* State that we have an RNG */
card->caps |= SC_CARD_CAP_RNG;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
return 0;
}
@ -104,9 +98,9 @@ static int acl_to_byte(const struct sc_acl_entry *e)
case SC_AC_TERM:
case SC_AC_AUT:
if (e->key_ref == SC_AC_KEY_REF_NONE)
return 0x00;
return 0x00;
if (e->key_ref < 1 || e->key_ref > 14)
return 0x00;
return 0x00;
return e->key_ref;
case SC_AC_NEVER:
return 0x0F;
@ -179,26 +173,26 @@ static int myeid_select_file(struct sc_card *card, const struct sc_path *in_path
struct sc_file **file)
{
int r;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
r = iso_ops->select_file(card, in_path, file);
if (r == 0 && file != NULL) {
if (r == 0 && file != NULL) {
parse_sec_attr(*file, (*file)->sec_attr, (*file)->sec_attr_len);
}
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_read_binary(struct sc_card *card, unsigned int idx,
u8 * buf, size_t count, unsigned long flags)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->read_binary(card, idx, buf, count, flags));
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->read_binary(card, idx, buf, count, flags));
}
static int myeid_list_files(struct sc_card *card, u8 *buf, size_t buflen)
{
struct sc_apdu apdu;
int r,i;
int r;
SC_FUNC_CALLED(card->ctx, 1);
@ -222,10 +216,10 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
const u8 *tag = NULL;
int r ;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
r = iso_ops->process_fci(card, file, buf, buflen);
if (r < 0)
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
if(file->type == SC_FILE_EF_UNKNOWN)
{
@ -241,17 +235,17 @@ static int myeid_process_fci(struct sc_card *card, struct sc_file *file,
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
}
SC_FUNC_RETURN(card->ctx, 1, 0);
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
u8 *out, size_t *outlen)
{
const sc_acl_entry_t *read, *update, *delete;
const sc_acl_entry_t *read, *update, *delete;
u8 buf[40];
int i;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
/* PrivateKey
* 0E0000019 6217 81020400 820111 83024B01 8603000000 85028000 8A0100 RESULT 6984
* 6217 81020400 820111 83024B01 8603000000 85021000 8A0100 */
@ -290,38 +284,38 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
buf[17] = file->sec_attr[2];
sc_debug(card->ctx, "id (%X), sec_attr %X %X %X\n", file->id,
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
file->sec_attr[0],file->sec_attr[1],file->sec_attr[2]);
}
else
{
delete = sc_file_get_acl_entry(file, SC_AC_OP_DELETE);
switch (file->type) {
case SC_FILE_TYPE_WORKING_EF:
switch (file->type) {
case SC_FILE_TYPE_WORKING_EF:
read = sc_file_get_acl_entry(file, SC_AC_OP_READ);
update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE);
buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update);
buf[16] = (acl_to_byte(delete)<< 4) | 0x0F;
break;
case SC_FILE_TYPE_INTERNAL_EF:
buf[16] = (acl_to_byte(delete)<< 4) | 0x0F;
break;
case SC_FILE_TYPE_INTERNAL_EF:
read = sc_file_get_acl_entry(file, SC_AC_OP_CRYPTO);
update = sc_file_get_acl_entry(file, SC_AC_OP_UPDATE);
buf[15] = (acl_to_byte(read) << 4) | acl_to_byte(update);
buf[16] = (acl_to_byte(delete)<< 4) | 0x0F;
break;
case SC_FILE_TYPE_DF:
buf[16] = (acl_to_byte(delete)<< 4) | 0x0F;
break;
case SC_FILE_TYPE_DF:
update = sc_file_get_acl_entry(file, SC_AC_OP_CREATE);
buf[15] = (acl_to_byte(update) << 4) | acl_to_byte(update);
buf[16] = (acl_to_byte(delete) << 4) | 0x0F;
break;
default:
break;
buf[16] = (acl_to_byte(delete) << 4) | 0x0F;
break;
default:
break;
}
}
@ -352,22 +346,22 @@ static int encode_file_structure(sc_card_t *card, const sc_file_t *file,
{
buf[25] = 0x84;
buf[26] = (u8)file->namelen;
for(i=0;i < (int)file->namelen;i++)
buf[i + 26] = file->name[i];
buf[1] = 0x19 + file->namelen + 2;
}
break;
default:
sc_error(card->ctx, "Unknown file type\n");
sc_debug(card->ctx, "Unknown file type\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
*outlen = buf[1]+2;
memcpy(out, buf, *outlen);
SC_FUNC_RETURN(card->ctx, 1, 0);
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static int myeid_create_file(struct sc_card *card, struct sc_file *file)
@ -378,7 +372,7 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file)
int r;
SC_FUNC_CALLED(card->ctx, 1);
r = encode_file_structure(card, file, sbuf, &buflen);
if (r)
SC_FUNC_RETURN(card->ctx, 1, r);
@ -392,9 +386,9 @@ static int myeid_create_file(struct sc_card *card, struct sc_file *file)
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x6A && apdu.sw2 == 0x89)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_FILE_ALREADY_EXISTS);
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
SC_TEST_RET(card->ctx, r, "Card returned error");
SC_FUNC_RETURN(card->ctx, r, "Card returned error");
}
/* no record oriented file services */
@ -402,37 +396,37 @@ static int myeid_read_record_unsupp(struct sc_card *card, unsigned int rec_nr,
u8 *buf, size_t count, unsigned long flags)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
static int myeid_wrupd_record_unsupp(struct sc_card *card, unsigned int rec_nr,
const u8 *buf, size_t count, unsigned long flags)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
static int myeid_append_record_unsupp(struct sc_card *card, const u8 *buf,
size_t count, unsigned long flags)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
static int myeid_write_binary(struct sc_card *card, unsigned int idx,
const u8 *buf, size_t count, unsigned long flags)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->write_binary(card, idx, buf, count, flags));
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->write_binary(card, idx, buf, count, flags));
}
static int myeid_update_binary(struct sc_card *card, unsigned int idx,
const u8 *buf, size_t count, unsigned long flags)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->update_binary(card, idx, buf, count, flags));
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, iso_ops->update_binary(card, idx, buf, count, flags));
}
static int myeid_delete_file(struct sc_card *card, const struct sc_path *path)
@ -443,7 +437,7 @@ static int myeid_delete_file(struct sc_card *card, const struct sc_path *path)
SC_FUNC_CALLED(card->ctx, 1);
if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2)
{
sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
r = sc_select_file(card, path, NULL);
@ -455,7 +449,7 @@ static int myeid_delete_file(struct sc_card *card, const struct sc_path *path)
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
SC_FUNC_RETURN(card->ctx, 1, sc_check_sw(card, apdu.sw1, apdu.sw2));
SC_FUNC_RETURN(card->ctx, 1, sc_check_sw(card, apdu.sw1, apdu.sw2));
}
static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
@ -481,7 +475,7 @@ static int myeid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
}
SC_FUNC_RETURN(card->ctx, 1, iso_ops->pin_cmd(card, data, tries_left));
}
}
static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env,
int se_num)
@ -492,16 +486,16 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env
int r, locked = 0;
assert(card != NULL && env != NULL);
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC)
{
sc_error(card->ctx, "asymmetric keyref not supported.\n");
sc_debug(card->ctx, "asymmetric keyref not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (se_num > 0)
{
sc_error(card->ctx, "restore security environment not supported.\n");
sc_debug(card->ctx, "restore security environment not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -575,14 +569,14 @@ static int myeid_set_security_env2(sc_card_t *card, const sc_security_env_t *env
err:
if (locked)
sc_unlock(card);
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_set_security_env(struct sc_card *card,
const struct sc_security_env *env, int se_num)
{
SC_FUNC_CALLED(card->ctx, 1);
if (env->flags & SC_SEC_ENV_ALG_PRESENT)
{
sc_security_env_t tmp;
@ -592,7 +586,7 @@ static int myeid_set_security_env(struct sc_card *card,
tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
if (tmp.algorithm != SC_ALGORITHM_RSA)
{
sc_error(card->ctx, "Only RSA algorithm supported.\n");
sc_debug(card->ctx, "Only RSA algorithm supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -617,7 +611,7 @@ static int myeid_compute_signature(struct sc_card *card, const u8 * data,
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
SC_FUNC_CALLED(card->ctx, 1);
assert(card != NULL && data != NULL && out != NULL);
if (datalen > 256)
SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
@ -644,7 +638,6 @@ static int myeid_compute_signature(struct sc_card *card, const u8 * data,
}
apdu.data = sbuf;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
@ -668,7 +661,7 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
SC_FUNC_CALLED(card->ctx, 1);
assert(card != NULL && crgram != NULL && out != NULL);
SC_FUNC_CALLED(card->ctx, 2);
if (crgram_len > 256)
@ -684,7 +677,6 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;
apdu.sensitive = 1;
if (crgram_len == 256)
{ apdu.le = 0;
@ -713,7 +705,6 @@ static int myeid_decipher(struct sc_card *card, const u8 * crgram,
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
apdu.le = crgram_len;
apdu.sensitive = 1;
/* padding indicator byte,
* 0x82 = Second half of 2048 bit cryptogram */
sbuf[0] = 0x82;
@ -813,7 +804,7 @@ static int myeid_loadkey(sc_card_t *card, int mode, u8* value, int value_len)
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
int r, len;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
len = 0;
if(value_len == 0 || value == NULL)
return 0;
@ -884,9 +875,9 @@ static int myeid_generate_store_key(struct sc_card *card,
{
struct sc_apdu apdu;
u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
int r=0,len;
int r=0,len;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
/* Setup key-generation paramters */
if (data->op_type == OP_TYPE_GENERATE)
{
@ -929,10 +920,10 @@ static int myeid_generate_store_key(struct sc_card *card,
data->mod, data->mod_len)) >= 0 &&
(r=myeid_loadkey(card, LOAD_KEY_PUBLIC_EXPONENT,
data->pubexp, data->pubexp_len)) >= 0)
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
}
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_activate_card(struct sc_card *card)
@ -941,7 +932,7 @@ static int myeid_activate_card(struct sc_card *card)
u8 sbuf[] ="\xA0\x00\x00\x00\x63\x50\x4B\x43\x53\x2D\x31\x35";
sc_apdu_t apdu;
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x44, 0x04, 0x00);
apdu.cla = 0x00;
apdu.data = sbuf;
@ -963,7 +954,7 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
sc_apdu_t apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_CALLED(card->ctx, 1);
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0xA0);
apdu.resp = rbuf;
apdu.resplen = sizeof(rbuf);
@ -988,27 +979,27 @@ static int myeid_get_serialnr(sc_card_t *card, sc_serial_number_t *serial)
/* copy and return serial number */
memcpy(serial, &card->serialnr, sizeof(*serial));
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
}
static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
{
int r = SC_ERROR_NOT_SUPPORTED;
SC_FUNC_CALLED(card->ctx, 1);
switch(cmd) {
case SC_CARDCTL_MYEID_PUTDATA:
r = myeid_putdata(card,
(struct sc_cardctl_myeid_data_obj*) ptr);
break;
break;
case SC_CARDCTL_MYEID_GETDATA:
r = myeid_getdata(card,
(struct sc_cardctl_myeid_data_obj*) ptr);
break;
break;
case SC_CARDCTL_MYEID_GENERATE_KEY:
r = myeid_generate_store_key(card,
(struct sc_cardctl_myeid_gen_store_key_info *) ptr);
break;
break;
case SC_CARDCTL_MYEID_ACTIVATE_CARD:
r = myeid_activate_card(card);
break;
@ -1017,9 +1008,9 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
break;
case SC_CARDCTL_LIFECYCLE_SET:
case SC_CARDCTL_LIFECYCLE_GET:
break;
break;
}
SC_FUNC_RETURN(card->ctx, 1, r);
SC_FUNC_RETURN(card->ctx, 1, r);
}
/* "The PINs are "global" in a PKCS#15 sense, meaning that they remain valid
@ -1029,8 +1020,8 @@ static int myeid_card_ctl(struct sc_card *card, unsigned long cmd, void *ptr)
*/
static int myeid_logout(struct sc_card *card)
{
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, 0);
SC_FUNC_CALLED(card->ctx, 1);
SC_FUNC_RETURN(card->ctx, 1, 0);
}
static struct sc_card_driver * sc_get_driver(void)
@ -1040,7 +1031,6 @@ static struct sc_card_driver * sc_get_driver(void)
myeid_ops = *iso_drv->ops;
myeid_ops.match_card = myeid_match_card;
myeid_ops.init = myeid_init;
myeid_ops.finish = myeid_finish;
if (iso_ops == NULL)
iso_ops = iso_drv->ops;
myeid_ops.read_binary = myeid_read_binary;
@ -1060,7 +1050,7 @@ static struct sc_card_driver * sc_get_driver(void)
myeid_ops.logout = myeid_logout;
myeid_ops.process_fci = myeid_process_fci;
myeid_ops.card_ctl = myeid_card_ctl;
myeid_ops.pin_cmd = myeid_pin_cmd;
myeid_ops.pin_cmd = myeid_pin_cmd;
return &myeid_drv;
}

View File

@ -232,7 +232,7 @@ auth_init(struct sc_card *card)
card->caps |= SC_CARD_CAP_USE_FCI_AC;
if (auth_select_aid(card)) {
sc_error(card->ctx, "Failed to initialize %s\n", card->name);
sc_debug(card->ctx, "Failed to initialize %s\n", card->name);
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_CARD, "Failed to initialize");
}
@ -383,7 +383,7 @@ auth_process_fci(struct sc_card *card, struct sc_file *file,
else if (file->size==2048)
file->size = PUBKEY_2048_ASN1_SIZE;
else {
sc_error(card->ctx, "Not supported public key size: %i\n", file->size);
sc_debug(card->ctx, "Not supported public key size: %i\n", file->size);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_UNKNOWN_DATA_RECEIVED);
}
break;
@ -621,7 +621,7 @@ auth_delete_file(struct sc_card *card, const struct sc_path *path)
}
if (path->len < 2) {
sc_error(card->ctx, "Invalid path length\n");
sc_debug(card->ctx, "Invalid path length\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
@ -782,7 +782,7 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file,
rv = SC_ERROR_INVALID_ARGUMENTS;
if (rv) {
sc_error(card->ctx, "Invalid EF structure %i/%i\n",
sc_debug(card->ctx, "Invalid EF structure %i/%i\n",
file->type, file->ef_structure);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCORRECT_PARAMETERS);
}
@ -810,7 +810,7 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file,
else if (file->size == PUBKEY_2048_ASN1_SIZE || file->size == 2048)
size = 2048;
else {
sc_error(card->ctx, "incorrect RSA size %X\n", file->size);
sc_debug(card->ctx, "incorrect RSA size %X\n", file->size);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCORRECT_PARAMETERS);
}
}
@ -823,7 +823,7 @@ encode_file_structure_V5(struct sc_card *card, const struct sc_file *file,
else if (file->size == 24 || file->size == 192)
size = 192;
else {
sc_error(card->ctx, "incorrect DES size %X\n", file->size);
sc_debug(card->ctx, "incorrect DES size %X\n", file->size);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INCORRECT_PARAMETERS);
}
}
@ -936,7 +936,7 @@ auth_create_file(struct sc_card *card, struct sc_file *file)
path.len -= 2;
if (auth_select_file(card, &path, NULL)) {
sc_error(card->ctx, "Cannot select parent DF.\n");
sc_debug(card->ctx, "Cannot select parent DF.\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
}
@ -1021,7 +1021,7 @@ auth_set_security_env(struct sc_card *card,
apdu.datalen = 3;
}
else {
sc_error(card->ctx, "Invalid crypto operation: %X\n", env->operation);
sc_debug(card->ctx, "Invalid crypto operation: %X\n", env->operation);
SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "Invalid crypto operation");
}
@ -1033,7 +1033,7 @@ auth_set_security_env(struct sc_card *card,
}
if (pads & (~supported_pads)) {
sc_error(card->ctx, "No support for PAD %X\n",pads);
sc_debug(card->ctx, "No support for PAD %X\n",pads);
SC_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "No padding support.");
}
@ -1054,7 +1054,7 @@ auth_set_security_env(struct sc_card *card,
apdu.data = rsa_sbuf;
}
else {
sc_error(card->ctx, "Invalid crypto operation: %X\n", env->operation);
sc_debug(card->ctx, "Invalid crypto operation: %X\n", env->operation);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
}
@ -1095,7 +1095,7 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
else if (ilen > 96) {
sc_error(card->ctx, "Illegal input length %d\n", ilen);
sc_debug(card->ctx, "Illegal input length %d\n", ilen);
SC_TEST_RET(card->ctx, SC_ERROR_INVALID_ARGUMENTS, "Illegal input length");
}
@ -1113,7 +1113,7 @@ auth_compute_signature(struct sc_card *card, const unsigned char *in, size_t ile
SC_TEST_RET(card->ctx, rv, "Compute signature failed");
if (apdu.resplen > olen) {
sc_error(card->ctx, "Compute signature failed: invalide response length %i\n",
sc_debug(card->ctx, "Compute signature failed: invalide response length %i\n",
apdu.resplen);
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_CARD_CMD_FAILED);
}
@ -1342,7 +1342,7 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a
EVP_EncryptInit_ex(&ctx, EVP_des_ecb(), NULL, args->data, NULL);
rv = EVP_EncryptUpdate(&ctx, out, &outl, in, 8);
if (!EVP_CIPHER_CTX_cleanup(&ctx) || rv == 0) {
sc_error(card->ctx, "OpenSSL encryption error.");
sc_debug(card->ctx, "OpenSSL encryption error.");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INTERNAL);
}
@ -1359,7 +1359,6 @@ auth_update_component(struct sc_card *card, struct auth_update_component_info *a
apdu.data = sbuf;
apdu.datalen = len;
apdu.lc = len;
apdu.sensitive = 1;
if (args->len == 0x100) {
sbuf[0] = args->type;
sbuf[1] = 0x20;
@ -1617,9 +1616,7 @@ auth_is_verified(struct sc_card *card, int pin_reference, int *tries_left)
apdu.sw2 = 0x83;
}
sc_ctx_suppress_errors_on(card->ctx);
rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
sc_ctx_suppress_errors_off(card->ctx);
return rv;
}
@ -1719,7 +1716,6 @@ auth_create_reference_data (struct sc_card *card,
apdu.data = sbuf;
apdu.datalen = len;
apdu.lc = len;
apdu.sensitive = 1;
rv = sc_transmit_apdu(card, &apdu);
sc_mem_clear(sbuf, sizeof(sbuf));

View File

@ -235,9 +235,7 @@ pgp_read_blob(sc_card_t *card, struct blob *blob)
if (blob->info == NULL)
return blob->status;
sc_ctx_suppress_errors_on(card->ctx);
r = blob->info->get_fn(card, blob->id, buffer, sizeof(buffer));
sc_ctx_suppress_errors_off(card->ctx);
if (r < 0) {
blob->status = r;
@ -308,7 +306,7 @@ pgp_enumerate_blob(sc_card_t *card, struct blob *blob)
return 0;
eoc: sc_error(card->ctx, "Unexpected end of contents\n");
eoc: sc_debug(card->ctx, "Unexpected end of contents\n");
return SC_ERROR_OBJECT_NOT_VALID;
}
@ -556,7 +554,7 @@ pgp_set_security_env(sc_card_t *card,
case SC_SEC_OPERATION_SIGN:
if (env->key_ref[0] != 0x00
&& env->key_ref[0] != 0x02) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Key reference not compatible with "
"requested usage\n");
return SC_ERROR_NOT_SUPPORTED;
@ -564,7 +562,7 @@ pgp_set_security_env(sc_card_t *card,
break;
case SC_SEC_OPERATION_DECIPHER:
if (env->key_ref[0] != 0x01) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Key reference not compatible with "
"requested usage\n");
return SC_ERROR_NOT_SUPPORTED;
@ -602,11 +600,11 @@ pgp_compute_signature(sc_card_t *card, const u8 *data,
0x88, 0, 0);
break;
case 0x01:
sc_error(card->ctx,
sc_debug(card->ctx,
"Invalid key reference (decipher only key)\n");
return SC_ERROR_INVALID_ARGUMENTS;
default:
sc_error(card->ctx, "Invalid key reference 0x%02x\n",
sc_debug(card->ctx, "Invalid key reference 0x%02x\n",
env->key_ref[0]);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -658,12 +656,12 @@ pgp_decipher(sc_card_t *card, const u8 *in, size_t inlen,
break;
case 0x00: /* signature key */
case 0x02: /* authentication key */
sc_error(card->ctx,
sc_debug(card->ctx,
"Invalid key reference (signature only key)\n");
free(temp);
return SC_ERROR_INVALID_ARGUMENTS;
default:
sc_error(card->ctx, "Invalid key reference 0x%02x\n",
sc_debug(card->ctx, "Invalid key reference 0x%02x\n",
env->key_ref[0]);
free(temp);
return SC_ERROR_INVALID_ARGUMENTS;

View File

@ -581,7 +581,6 @@ static int piv_find_aid(sc_card_t * card, sc_file_t *aid_file)
static int piv_get_data(sc_card_t * card, int enumtag,
u8 **buf, size_t *buf_len)
{
piv_private_data_t * priv = PIV_DATA(card);
u8 *p;
int r = 0;
u8 tagbuf[8];
@ -853,7 +852,7 @@ static int piv_cache_internal_data(sc_card_t *card, int enumtag)
priv->obj_cache[enumtag].internal_obj_data = newBuf;
priv->obj_cache[enumtag].internal_obj_len = len;
#else
sc_error(card->ctx,"PIV compression not supported, no zlib");
sc_debug(card->ctx,"PIV compression not supported, no zlib");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
#endif
} else {
@ -1690,9 +1689,7 @@ static int piv_select_file(sc_card_t *card, const sc_path_t *in_path,
if (file_out) {
/* we need to read it now, to get length into cache */
sc_ctx_suppress_errors_on(card->ctx);
r = piv_get_cached_data(card, i, &rbuf, &rbuflen);
sc_ctx_suppress_errors_off(card->ctx);
if (r < 0)
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_FILE_NOT_FOUND);
@ -1749,7 +1746,6 @@ sc_debug(card->ctx,"DEE freeing #%d, %p:%d %p:%d", i,
free(priv);
}
/* TODO temp see piv_init */
sc_ctx_suppress_errors_off(card->ctx);
return 0;
}
@ -1764,9 +1760,7 @@ static int piv_match_card(sc_card_t *card)
card->ops->logout = NULL;
/* Detect by selecting applet */
sc_ctx_suppress_errors_on(card->ctx);
i = !(piv_find_aid(card, &aidfile));
sc_ctx_suppress_errors_off(card->ctx);
return i; /* never match */
}
@ -1799,7 +1793,7 @@ static int piv_init(sc_card_t *card)
r = piv_find_aid(card, priv->aid_file);
if (r < 0) {
sc_error(card->ctx, "Failed to initialize %s\n", card->name);
sc_debug(card->ctx, "Failed to initialize %s\n", card->name);
SC_FUNC_RETURN(card->ctx, 1, r);
}
priv->enumtag = piv_aids[r].enumtag;
@ -1815,7 +1809,6 @@ static int piv_init(sc_card_t *card)
if (r > 0)
r = 0;
sc_ctx_suppress_errors_on(card->ctx); /*TODO temp to suppresss all error */
SC_FUNC_RETURN(card->ctx, 1, r);
}

View File

@ -345,7 +345,6 @@ static int rtecp_verify(sc_card_t *card, unsigned int type, int ref_qualifier,
apdu.lc = data_len;
apdu.data = data;
apdu.datalen = data_len;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (send_logout++ == 0 && apdu.sw1 == 0x6F && apdu.sw2 == 0x86)
@ -411,7 +410,6 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len,
apdu.lc = data_len;
apdu.data = buf;
apdu.datalen = data_len;
apdu.sensitive = 1;
apdu.resp = buf_out;
apdu.resplen = out_len + 2;
apdu.le = out_len;
@ -426,7 +424,7 @@ static int rtecp_cipher(sc_card_t *card, const u8 *data, size_t data_len,
assert(buf);
free(buf);
if (r)
sc_error(card->ctx, "APDU transmit failed: %s\n", sc_strerror(r));
sc_debug(card->ctx, "APDU transmit failed: %s\n", sc_strerror(r));
else
{
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
@ -521,7 +519,6 @@ static int rtecp_change_reference_data(sc_card_t *card, unsigned int type,
apdu.lc = p - buf;
apdu.data = buf;
apdu.datalen = p - buf;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
sc_mem_clear(buf, sizeof(buf));
@ -662,7 +659,7 @@ static int rtecp_card_ctl(sc_card_t *card, unsigned long request, void *data)
if (card->ctx->debug >= 4)
sc_debug(card->ctx, "%s\n",
"SC_CARDCTL_LIFECYCLE_SET not supported");
/* no call sc_error (SC_FUNC_RETURN) */
/* no call sc_debug (SC_FUNC_RETURN) */
return SC_ERROR_NOT_SUPPORTED;
default:
if (card->ctx->debug >= 3)
@ -788,7 +785,6 @@ struct sc_card_driver * sc_get_rtecp_driver(void)
rtecp_ops.match_card = rtecp_match_card;
rtecp_ops.init = rtecp_init;
rtecp_ops.finish = NULL;
/* read_binary */
rtecp_ops.write_binary = NULL;
/* update_binary */

View File

@ -234,12 +234,12 @@ static int rutoken_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
for (i = 0; i < sizeof(rutoken_errors)/sizeof(rutoken_errors[0]); ++i) {
if (rutoken_errors[i].SWs == ((sw1 << 8) | sw2)) {
if ( rutoken_errors[i].errorstr )
sc_error(card->ctx, "%s\n", rutoken_errors[i].errorstr);
sc_debug(card->ctx, "%s\n", rutoken_errors[i].errorstr);
sc_debug(card->ctx, "sw1 = %x, sw2 = %x", sw1, sw2);
return rutoken_errors[i].errorno;
}
}
sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
return SC_ERROR_CARD_CMD_FAILED;
}
@ -603,7 +603,7 @@ static int rutoken_delete_file(sc_card_t *card, const sc_path_t *path)
SC_FUNC_CALLED(card->ctx, 1);
if (!path || path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2))
{
sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
if (path->len == sizeof(sbuf))
@ -722,7 +722,7 @@ static int rutoken_reset_retry_counter(sc_card_t *card, unsigned int type,
if (puk && puklen)
{
ret = rutoken_verify(card, type, ref_qualifier, puk, puklen, &left);
sc_error(card->ctx, "Tries left: %i\n", left);
sc_debug(card->ctx, "Tries left: %i\n", left);
SC_TEST_RET(card->ctx, ret, "Invalid 'puk' pass");
}
#endif
@ -770,7 +770,7 @@ static int rutoken_set_security_env(sc_card_t *card,
senv->algorithm = SC_ALGORITHM_GOST;
if (env->key_ref_len != 1)
{
sc_error(card->ctx, "No or invalid key reference\n");
sc_debug(card->ctx, "No or invalid key reference\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
data[2] = env->key_ref[0];
@ -1308,7 +1308,7 @@ static int cipher_ext(sc_card_t *card, const u8 *data, size_t len,
ret = SC_ERROR_INTERNAL;
ERR_load_crypto_strings();
ERR_error_string(ERR_get_error(), error);
sc_error(card->ctx, error);
sc_debug(card->ctx, error);
ERR_free_strings();
}
}
@ -1504,7 +1504,7 @@ static int rutoken_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
case SC_CARDCTL_LIFECYCLE_SET:
sc_debug(card->ctx, "SC_CARDCTL_LIFECYCLE_SET not supported");
sc_debug(card->ctx, "returning SC_ERROR_NOT_SUPPORTED");
/* no call sc_error (SC_FUNC_RETURN) */
/* no call sc_debug (SC_FUNC_RETURN) */
return SC_ERROR_NOT_SUPPORTED;
}
}

View File

@ -70,11 +70,6 @@ static struct sc_card_driver setcos_drv = {
NULL, 0, NULL
};
static int setcos_finish(sc_card_t *card)
{
return 0;
}
static int match_hist_bytes(sc_card_t *card, const char *str, size_t len)
{
const char *src = (const char *) card->slot->atr_info.hist_bytes;
@ -145,9 +140,7 @@ static int select_pkcs15_app(sc_card_t * card)
/* Regular PKCS#15 AID */
sc_format_path("A000000063504B43532D3135", &app);
app.type = SC_PATH_TYPE_DF_NAME;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &app, NULL);
sc_ctx_suppress_errors_off(card->ctx);
return r;
}
@ -474,7 +467,7 @@ static int setcos_create_file_44(sc_card_t *card, sc_file_t *file)
break;
case SC_AC_CHV: /* pin */
if ((bNumber & 0x7F) == 0 || (bNumber & 0x7F) > 7) {
sc_error(card->ctx, "SetCOS 4.4 PIN refs can only be 1..7\n");
sc_debug(card->ctx, "SetCOS 4.4 PIN refs can only be 1..7\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
bCommands_pin[setcos_pin_index_44(pins, sizeof(pins), (int) bNumber)] |= 1 << i;
@ -577,11 +570,11 @@ static int setcos_set_security_env2(sc_card_t *card,
card->type == SC_CARD_TYPE_SETCOS_NIDEL ||
SETCOS_IS_EID_APPLET(card)) {
if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC) {
sc_error(card->ctx, "asymmetric keyref not supported.\n");
sc_debug(card->ctx, "asymmetric keyref not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (se_num > 0) {
sc_error(card->ctx, "restore security environment not supported.\n");
sc_debug(card->ctx, "restore security environment not supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
}
@ -671,7 +664,7 @@ static int setcos_set_security_env(sc_card_t *card,
tmp.flags &= ~SC_SEC_ENV_ALG_PRESENT;
tmp.flags |= SC_SEC_ENV_ALG_REF_PRESENT;
if (tmp.algorithm != SC_ALGORITHM_RSA) {
sc_error(card->ctx, "Only RSA algorithm supported.\n");
sc_debug(card->ctx, "Only RSA algorithm supported.\n");
return SC_ERROR_NOT_SUPPORTED;
}
switch (card->type) {
@ -684,7 +677,7 @@ static int setcos_set_security_env(sc_card_t *card,
case SC_CARD_TYPE_SETCOS_EID_V2_1:
break;
default:
sc_error(card->ctx, "Card does not support RSA.\n");
sc_debug(card->ctx, "Card does not support RSA.\n");
return SC_ERROR_NOT_SUPPORTED;
break;
}
@ -1122,7 +1115,6 @@ static struct sc_card_driver *sc_get_driver(void)
setcos_ops = *iso_drv->ops;
setcos_ops.match_card = setcos_match_card;
setcos_ops.init = setcos_init;
setcos_ops.finish = setcos_finish;
if (iso_ops == NULL)
iso_ops = iso_drv->ops;
setcos_ops.create_file = setcos_create_file;

View File

@ -1101,11 +1101,9 @@ static int starcos_set_security_env(sc_card_t *card,
apdu.datalen = p - sbuf;
apdu.lc = p - sbuf;
apdu.le = 0;
/* suppress errors, as don't know whether to use
/* we don't know whether to use
* COMPUTE SIGNATURE or INTERNAL AUTHENTICATE */
sc_ctx_suppress_errors_on(card->ctx);
r = sc_transmit_apdu(card, &apdu);
sc_ctx_suppress_errors_off(card->ctx);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
ex_data->fix_digestInfo = 0;
@ -1183,7 +1181,6 @@ static int starcos_compute_signature(sc_card_t *card,
apdu.lc = 0;
apdu.datalen = 0;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
@ -1246,7 +1243,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
return SC_NO_ERROR;
if (sw1 == 0x63 && (sw2 & ~0x0fU) == 0xc0 )
{
sc_error(card->ctx, "Verification failed (remaining tries: %d)\n",
sc_debug(card->ctx, "Verification failed (remaining tries: %d)\n",
(sw2 & 0x0f));
return SC_ERROR_PIN_CODE_INCORRECT;
}
@ -1255,7 +1252,7 @@ static int starcos_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
for (i = 0; i < err_count; i++)
if (starcos_errors[i].SWs == ((sw1 << 8) | sw2))
{
sc_error(card->ctx, "%s\n", starcos_errors[i].errorstr);
sc_debug(card->ctx, "%s\n", starcos_errors[i].errorstr);
return starcos_errors[i].errorno;
}
@ -1340,9 +1337,7 @@ static int starcos_logout(sc_card_t *card)
apdu.datalen = 2;
apdu.resplen = 0;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_transmit_apdu(card, &apdu);
sc_ctx_suppress_errors_off(card->ctx);
SC_TEST_RET(card->ctx, r, "APDU re-transmit failed");
if (apdu.sw1 == 0x69 && apdu.sw2 == 0x85)

View File

@ -484,7 +484,7 @@ static int tcos_delete_file(sc_card_t *card, const sc_path_t *path)
SC_FUNC_CALLED(card->ctx, 1);
if (path->type != SC_PATH_TYPE_FILE_ID && path->len != 2) {
sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
sbuf[0] = path->value[0];
@ -575,7 +575,7 @@ static int tcos_compute_signature(sc_card_t *card, const u8 * data, size_t datal
if(((tcos_data *)card->drv_data)->next_sign){
if(datalen>48){
sc_error(card->ctx, "Data to be signed is too long (TCOS supports max. 48 bytes)\n");
sc_debug(card->ctx, "Data to be signed is too long (TCOS supports max. 48 bytes)\n");
SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS);
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A);

View File

@ -185,14 +185,10 @@ static int westcos_match_card(sc_card_t * card)
apdu.lc = sizeof(aid);
apdu.datalen = sizeof(aid);
apdu.data = aid;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_transmit_apdu(card, &apdu);
sc_ctx_suppress_errors_off(card->ctx);
if (r)
return 0;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
sc_ctx_suppress_errors_off(card->ctx);
if (r)
return 0;
}
@ -782,7 +778,6 @@ static int westcos_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data,
apdu.datalen = len;
apdu.data = buf;
apdu.resplen = 0;
apdu.sensitive = 1;
if (!use_pin_pad) {
/* Transmit the APDU to the card */

View File

@ -90,7 +90,7 @@ static void sc_card_free(sc_card_t *card)
if (card->mutex != NULL) {
int r = sc_mutex_destroy(card->ctx, card->mutex);
if (r != SC_SUCCESS)
sc_error(card->ctx, "unable to destroy mutex\n");
sc_debug(card->ctx, "unable to destroy mutex\n");
}
sc_mem_clear(card, sizeof(*card));
free(card);
@ -172,7 +172,7 @@ int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out)
if (card->ops->init != NULL) {
r = card->ops->init(card);
if (r) {
sc_error(ctx, "driver '%s' init() failed: %s\n", card->driver->name,
sc_debug(ctx, "driver '%s' init() failed: %s\n", card->driver->name,
sc_strerror(r));
goto err;
}
@ -198,7 +198,7 @@ int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out)
card->driver = drv;
r = ops->init(card);
if (r) {
sc_error(ctx, "driver '%s' init() failed: %s\n", drv->name,
sc_debug(ctx, "driver '%s' init() failed: %s\n", drv->name,
sc_strerror(r));
if (r == SC_ERROR_INVALID_CARD) {
card->driver = NULL;
@ -210,7 +210,7 @@ int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out)
}
}
if (card->driver == NULL) {
sc_error(ctx, "unable to find driver for inserted card\n");
sc_debug(ctx, "unable to find driver for inserted card\n");
r = SC_ERROR_INVALID_CARD;
goto err;
}
@ -238,13 +238,13 @@ int sc_disconnect_card(sc_card_t *card, int action)
if (card->ops->finish) {
int r = card->ops->finish(card);
if (r)
sc_error(card->ctx, "card driver finish() failed: %s\n",
sc_debug(card->ctx, "card driver finish() failed: %s\n",
sc_strerror(r));
}
if (card->reader->ops->disconnect) {
int r = card->reader->ops->disconnect(card->reader, card->slot);
if (r)
sc_error(card->ctx, "disconnect() failed: %s\n",
sc_debug(card->ctx, "disconnect() failed: %s\n",
sc_strerror(r));
}
sc_card_free(card);
@ -271,7 +271,7 @@ int sc_reset(sc_card_t *card)
r2 = sc_mutex_unlock(card->ctx, card->mutex);
if (r2 != SC_SUCCESS) {
sc_error(card->ctx, "unable to release lock\n");
sc_debug(card->ctx, "unable to release lock\n");
r = r != SC_SUCCESS ? r : r2;
}
@ -290,8 +290,15 @@ int sc_lock(sc_card_t *card)
if (r != SC_SUCCESS)
return r;
if (card->lock_count == 0) {
if (card->reader->ops->lock != NULL)
if (card->reader->ops->lock != NULL) {
r = card->reader->ops->lock(card->reader, card->slot);
if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
/* invalidate cache */
memset(&card->cache, 0, sizeof(card->cache));
card->cache_valid = 0;
r = card->reader->ops->lock(card->reader, card->slot);
}
}
if (r == 0)
card->cache_valid = 1;
}
@ -299,7 +306,7 @@ int sc_lock(sc_card_t *card)
card->lock_count++;
r2 = sc_mutex_unlock(card->ctx, card->mutex);
if (r2 != SC_SUCCESS) {
sc_error(card->ctx, "unable to release lock\n");
sc_debug(card->ctx, "unable to release lock\n");
r = r != SC_SUCCESS ? r : r2;
}
return r;
@ -327,7 +334,7 @@ int sc_unlock(sc_card_t *card)
}
r2 = sc_mutex_unlock(card->ctx, card->mutex);
if (r2 != SC_SUCCESS) {
sc_error(card->ctx, "unable to release lock\n");
sc_debug(card->ctx, "unable to release lock\n");
r = (r == SC_SUCCESS) ? r2 : r;
}
return r;
@ -774,7 +781,7 @@ static int match_atr_table(sc_context_t *ctx, struct sc_atr_table *table, u8 *at
mbin_len = sizeof(mbin);
sc_hex_to_bin(matr, mbin, &mbin_len);
if (mbin_len != fix_bin_len) {
sc_error(ctx,"length of atr and atr mask do not match - ignored: %s - %s", tatr, matr);
sc_debug(ctx,"length of atr and atr mask do not match - ignored: %s - %s", tatr, matr);
continue;
}
for (s = 0; s < tbin_len; s++) {

View File

@ -44,6 +44,7 @@ enum {
SC_CARD_TYPE_CARDOS_M4_3,
SC_CARD_TYPE_CARDOS_M4_2B, /* 4.2b is after 4.3b */
SC_CARD_TYPE_CARDOS_M4_2C,
SC_CARD_TYPE_CARDOS_CIE_V1, /* Italian CIE (eID) v1 */
/* flex/cyberflex drivers */
SC_CARD_TYPE_FLEX_BASE = 2000,
@ -150,6 +151,15 @@ enum {
/* MyEID cards */
SC_CARD_TYPE_MYEID_BASE = 20000,
SC_CARD_TYPE_MYEID_GENERIC,
/* GemsafeV1 cards */
SC_CARD_TYPE_GEMSAFEV1_BASE = 21000,
SC_CARD_TYPE_GEMSAFEV1_GENERIC,
SC_CARD_TYPE_GEMSAFEV1_PTEID,
/* IAS cards */
SC_CARD_TYPE_IAS_BASE = 22000,
SC_CARD_TYPE_IAS_PTEID,
};
extern sc_card_driver_t *sc_get_default_driver(void);
@ -180,6 +190,7 @@ extern sc_card_driver_t *sc_get_rutoken_driver(void);
extern sc_card_driver_t *sc_get_rtecp_driver(void);
extern sc_card_driver_t *sc_get_westcos_driver(void);
extern sc_card_driver_t *sc_get_myeid_driver(void);
extern sc_card_driver_t *sc_get_ias_driver(void);
#ifdef __cplusplus
}

View File

@ -169,7 +169,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
r = ctbcs_build_modify_verification_apdu(&apdu, data, slot);
break;
default:
sc_error(reader->ctx, "Unknown PIN command %d", data->cmd);
sc_debug(reader->ctx, "Unknown PIN command %d", data->cmd);
return SC_ERROR_NOT_SUPPORTED;
}
@ -187,7 +187,7 @@ ctbcs_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
r = sc_transmit_apdu(card, &apdu);
s = sc_mutex_destroy(reader->ctx, card->mutex);
if (s != SC_SUCCESS) {
sc_error(reader->ctx, "unable to destroy mutex\n");
sc_debug(reader->ctx, "unable to destroy mutex\n");
return s;
}
SC_TEST_RET(card->ctx, r, "APDU transmit failed");

View File

@ -71,6 +71,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = {
{ "oberthur", (void *(*)(void)) sc_get_oberthur_driver },
#endif
{ "belpic", (void *(*)(void)) sc_get_belpic_driver },
{ "ias", (void *(*)(void)) sc_get_ias_driver },
{ "atrust-acos",(void *(*)(void)) sc_get_atrust_acos_driver },
{ "muscle", (void *(*)(void)) sc_get_muscle_driver },
{ "incrypto34", (void *(*)(void)) sc_get_incrypto34_driver },
@ -86,8 +87,7 @@ static const struct _sc_driver_entry internal_card_drivers[] = {
{ "rutoken_ecp",(void *(*)(void)) sc_get_rtecp_driver },
{ "westcos", (void *(*)(void)) sc_get_westcos_driver },
{ "myeid", (void *(*)(void)) sc_get_myeid_driver },
/* emv is not really used, not sure if it works, but it conflicts with
muscle and rutoken driver, thus has to be after them */
/* emv is not really implemented */
{ "emv", (void *(*)(void)) sc_get_emv_driver },
/* The default driver should be last, as it handles all the
* unrecognized cards. */
@ -177,13 +177,9 @@ static void add_internal_drvs(struct _sc_ctx_options *opts, int type)
static void set_defaults(sc_context_t *ctx, struct _sc_ctx_options *opts)
{
ctx->debug = 0;
if (ctx->debug_file && ctx->debug_file != stdout)
if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
fclose(ctx->debug_file);
ctx->debug_file = stdout;
ctx->suppress_errors = 0;
if (ctx->error_file && ctx->error_file != stderr)
fclose(ctx->error_file);
ctx->error_file = stderr;
ctx->debug_file = stderr;
ctx->forced_driver = NULL;
add_internal_drvs(opts, 0);
add_internal_drvs(opts, 1);
@ -204,21 +200,14 @@ static int load_parameters(sc_context_t *ctx, scconf_block *block,
val = scconf_get_str(block, "debug_file", NULL);
if (val) {
if (ctx->debug_file && ctx->debug_file != stdout)
if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
fclose(ctx->debug_file);
if (strcmp(val, "stdout") != 0)
ctx->debug_file = fopen(val, "a");
if (!strcmp(val, "stdout"))
ctx->debug_file = stdout;
else if (!strcmp(val, "stderr"))
ctx->debug_file = stderr;
else
ctx->debug_file = stdout;
}
val = scconf_get_str(block, "error_file", NULL);
if (val) {
if (ctx->error_file && ctx->error_file != stderr)
fclose(ctx->error_file);
if (strcmp(val, "stderr") != 0)
ctx->error_file = fopen(val, "a");
else
ctx->error_file = stderr;
ctx->debug_file = fopen(val, "a");
}
val = scconf_get_str(block, "force_card_driver", NULL);
if (val) {
@ -340,7 +329,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
const char *(**tmodv)(void) = &modversion;
if (name == NULL) { /* should not occurr, but... */
sc_error(ctx,"No module specified\n",name);
sc_debug(ctx,"No module specified\n",name);
return NULL;
}
libname = find_library(ctx, name, type);
@ -348,7 +337,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
return NULL;
handle = lt_dlopen(libname);
if (handle == NULL) {
sc_error(ctx, "Module %s: cannot load %s library: %s\n", name, libname, lt_dlerror());
sc_debug(ctx, "Module %s: cannot load %s library: %s\n", name, libname, lt_dlerror());
return NULL;
}
@ -356,7 +345,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
*(void **)tmodi = lt_dlsym(handle, "sc_module_init");
*(void **)tmodv = lt_dlsym(handle, "sc_driver_version");
if (modinit == NULL || modversion == NULL) {
sc_error(ctx, "dynamic library '%s' is not a OpenSC module\n",libname);
sc_debug(ctx, "dynamic library '%s' is not a OpenSC module\n",libname);
lt_dlclose(handle);
return NULL;
}
@ -364,7 +353,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll,
version = modversion();
/* XXX: We really need to have ABI version for each interface */
if (version == NULL || strncmp(version, PACKAGE_VERSION, strlen(PACKAGE_VERSION)) != 0) {
sc_error(ctx,"dynamic library '%s': invalid module version\n",libname);
sc_debug(ctx,"dynamic library '%s': invalid module version\n",libname);
lt_dlclose(handle);
return NULL;
}
@ -401,7 +390,7 @@ static int load_reader_drivers(sc_context_t *ctx,
*(void**)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name, 0);
/* if still null, assume driver not found */
if (func == NULL) {
sc_error(ctx, "Unable to load '%s'.\n", ent->name);
sc_debug(ctx, "Unable to load '%s'.\n", ent->name);
continue;
}
driver = func();
@ -464,7 +453,7 @@ static int load_card_drivers(sc_context_t *ctx,
*(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name, 1);
/* if still null, assume driver not found */
if (func == NULL) {
sc_error(ctx, "Unable to load '%s'.\n", ent->name);
sc_debug(ctx, "Unable to load '%s'.\n", ent->name);
continue;
}
@ -625,7 +614,7 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
if (r < 0)
sc_debug(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
else
sc_error(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
sc_debug(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
scconf_free(ctx->conf);
ctx->conf = NULL;
return;
@ -677,16 +666,6 @@ unsigned int sc_ctx_get_reader_count(sc_context_t *ctx)
return (unsigned int)ctx->reader_count;
}
void sc_ctx_suppress_errors_on(sc_context_t *ctx)
{
ctx->suppress_errors++;
}
void sc_ctx_suppress_errors_off(sc_context_t *ctx)
{
ctx->suppress_errors--;
}
int sc_establish_context(sc_context_t **ctx_out, const char *app_name)
{
sc_context_param_t ctx_param;
@ -792,16 +771,14 @@ int sc_release_context(sc_context_t *ctx)
if (ctx->mutex != NULL) {
int r = sc_mutex_destroy(ctx, ctx->mutex);
if (r != SC_SUCCESS) {
sc_error(ctx, "unable to destroy mutex\n");
sc_debug(ctx, "unable to destroy mutex\n");
return r;
}
}
if (ctx->conf != NULL)
scconf_free(ctx->conf);
if (ctx->debug_file && ctx->debug_file != stdout)
if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr))
fclose(ctx->debug_file);
if (ctx->error_file && ctx->error_file != stderr)
fclose(ctx->error_file);
if (ctx->app_name != NULL)
free(ctx->app_name);
sc_mem_clear(ctx, sizeof(*ctx));
@ -902,6 +879,6 @@ int sc_make_cache_dir(sc_context_t *ctx)
return SC_SUCCESS;
/* for lack of a better return code */
failed: sc_error(ctx, "failed to create cache directory\n");
failed: sc_debug(ctx, "failed to create cache directory\n");
return SC_ERROR_INTERNAL;
}

View File

@ -32,7 +32,9 @@ struct app_entry {
static const struct app_entry apps[] = {
{ (const u8 *) "\xA0\x00\x00\x00\x63PKCS-15", 12, "PKCS #15" },
{ (const u8 *) "\xA0\x00\x00\x01\x77PKCS-15", 12, "Belgian eID" },
{ (const u8 *) "\xA0\x00\x00\x01\x77PKCS-15", 12, "Belgian eID" }
/* Needed for the normal PKCS#15 processing of the Portugal eID card */
/* { (const u8 *) "\x44\x46\x20\x69\x73\x73\x75\x65\x72", 9, "Portugal eID" } */
};
static const struct app_entry * find_app_entry(const u8 * aid, size_t aid_len)
@ -96,12 +98,12 @@ static int parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen,
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
return r;
if (r) {
sc_error(card->ctx, "EF(DIR) parsing failed: %s\n",
sc_debug(card->ctx, "EF(DIR) parsing failed: %s\n",
sc_strerror(r));
return r;
}
if (aid_len > SC_MAX_AID_SIZE) {
sc_error(card->ctx, "AID is too long.\n");
sc_debug(card->ctx, "AID is too long.\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
app = (sc_app_info_t *) malloc(sizeof(sc_app_info_t));
@ -116,7 +118,7 @@ static int parse_dir_record(sc_card_t *card, u8 ** buf, size_t *buflen,
app->label = NULL;
if (asn1_dirrecord[2].flags & SC_ASN1_PRESENT) {
if (path_len > SC_MAX_PATH_SIZE) {
sc_error(card->ctx, "Application path is too long.\n");
sc_debug(card->ctx, "Application path is too long.\n");
free(app);
return SC_ERROR_INVALID_ASN1_OBJECT;
}
@ -167,9 +169,7 @@ int sc_enum_apps(sc_card_t *card)
sc_file_free(card->ef_dir);
card->ef_dir = NULL;
}
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, &card->ef_dir);
sc_ctx_suppress_errors_off(card->ctx);
if (r)
return r;
if (card->ef_dir->type != SC_FILE_TYPE_WORKING_EF) {
@ -198,7 +198,7 @@ int sc_enum_apps(sc_card_t *card)
bufsize = r;
while (bufsize > 0) {
if (card->app_count == SC_MAX_CARD_APPS) {
sc_error(card->ctx, "Too many applications on card");
sc_debug(card->ctx, "Too many applications on card");
break;
}
r = parse_dir_record(card, &p, &bufsize, -1);
@ -214,15 +214,13 @@ int sc_enum_apps(sc_card_t *card)
size_t rec_size;
for (rec_nr = 1; ; rec_nr++) {
sc_ctx_suppress_errors_on(card->ctx);
r = sc_read_record(card, rec_nr, buf, sizeof(buf),
SC_RECORD_BY_REC_NR);
sc_ctx_suppress_errors_off(card->ctx);
if (r == SC_ERROR_RECORD_NOT_FOUND)
break;
SC_TEST_RET(card->ctx, r, "read_record() failed");
if (card->app_count == SC_MAX_CARD_APPS) {
sc_error(card->ctx, "Too many applications on card");
sc_debug(card->ctx, "Too many applications on card");
break;
}
rec_size = r;
@ -285,7 +283,7 @@ static int encode_dir_record(sc_context_t *ctx, const sc_app_info_t *app,
(void *) &tapp.ddo_len, 1);
r = sc_asn1_encode(ctx, asn1_dir, buf, buflen);
if (r) {
sc_error(ctx, "sc_asn1_encode() failed: %s\n",
sc_debug(ctx, "sc_asn1_encode() failed: %s\n",
sc_strerror(r));
return r;
}
@ -352,9 +350,7 @@ static int update_single_record(sc_card_t *card, sc_file_t *file,
r = sc_update_record(card, (unsigned int)app->rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR);
else if (app->rec_nr == 0) {
/* create new record entry */
sc_ctx_suppress_errors_on(card->ctx);
r = sc_append_record(card, rec, rec_size, 0);
sc_ctx_suppress_errors_off(card->ctx);
if (r == SC_ERROR_NOT_SUPPORTED) {
/* if the card doesn't support APPEND RECORD we try a
* UPDATE RECORD on the next unused record (and hope
@ -368,7 +364,7 @@ static int update_single_record(sc_card_t *card, sc_file_t *file,
r = sc_update_record(card, (unsigned int)rec_nr, rec, rec_size, SC_RECORD_BY_REC_NR);
}
} else {
sc_error(card->ctx, "invalid record number\n");
sc_debug(card->ctx, "invalid record number\n");
r = SC_ERROR_INTERNAL;
}
free(rec);

View File

@ -1,24 +0,0 @@
/*
* emv.c: EMV functions
*
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "internal.h"
#include "emv.h"
/* FIXME: Implement */

View File

@ -1,41 +0,0 @@
/*
* emv.h: OpenSC EMV header file
*
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _OPENSC_EMV_H
#define _OPENSC_EMV_H
#include <opensc/opensc.h>
#ifdef __cplusplus
extern "C" {
#endif
struct sc_emv_card {
struct sc_card *card;
};
int sc_emv_bind(struct sc_card *card, struct sc_emv_card **emv_card);
int sc_emv_unbind(struct sc_emv_card *emv_card);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -89,7 +89,8 @@ const char *sc_strerror(int error)
"Wrong padding",
"Unsupported card",
"Unable to load external module",
"EF offset too large"
"EF offset too large",
"Not implemented"
};
const int int_base = -SC_ERROR_INTERNAL;
const char *p15i_errors[] = {

View File

@ -90,6 +90,7 @@ extern "C" {
#define SC_ERROR_WRONG_CARD -1413
#define SC_ERROR_CANNOT_LOAD_MODULE -1414
#define SC_ERROR_OFFSET_TOO_LARGE -1415
#define SC_ERROR_NOT_IMPLEMENTED -1416
/* Relating to PKCS #15 init stuff */
#define SC_ERROR_PKCS15INIT -1500

View File

@ -37,6 +37,7 @@ typedef unsigned __int8 uint8_t;
#define SCARD_SHARE_EXCLUSIVE 0x0001 /**< Exclusive mode only */
#define SCARD_SHARE_SHARED 0x0002 /**< Shared mode only */
#define SCARD_SHARE_DIRECT 0x0003 /**< Raw mode only */
#define SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */
#define SCARD_RESET_CARD 0x0001 /**< Reset on close */
@ -49,6 +50,8 @@ typedef unsigned __int8 uint8_t;
#define SCARD_E_INVALID_HANDLE 0x80100003 /**< The supplied handle was invalid. */
#define SCARD_E_TIMEOUT 0x8010000A /**< The user-specified timeout value has expired. */
#define SCARD_E_SHARING_VIOLATION 0x8010000B /**< The smart card cannot be accessed because of other connections outstanding. */
#define SCARD_E_NO_SMARTCARD 0x8010000C /**< The operation requires a smart card, but no smart card is currently in the device. */
#define SCARD_E_PROTO_MISMATCH 0x8010000F /**< The requested protocols are incompatible with the protocol currently in use with the smart card. */
#define SCARD_E_NOT_TRANSACTED 0x80100016 /**< An attempt was made to end a non-existent transaction. */
#define SCARD_E_READER_UNAVAILABLE 0x80100017 /**< The specified reader is not currently available for use. */
#define SCARD_E_NO_SERVICE 0x8010001D /**< The Smart card resource manager is not running. */

View File

@ -84,22 +84,22 @@ static int iso7816_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
/* Handle special cases here */
if (sw1 == 0x6C) {
sc_error(card->ctx, "Wrong length; correct length is %d\n", sw2);
sc_debug(card->ctx, "Wrong length; correct length is %d\n", sw2);
return SC_ERROR_WRONG_LENGTH;
}
if (sw1 == 0x90)
return SC_NO_ERROR;
if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U ) {
sc_error(card->ctx, "Verification failed (remaining tries: %d)\n",
sc_debug(card->ctx, "Verification failed (remaining tries: %d)\n",
(sw2 & 0x0f));
return SC_ERROR_PIN_CODE_INCORRECT;
}
for (i = 0; i < err_count; i++)
if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) {
sc_error(card->ctx, "%s\n", iso7816_errors[i].errorstr);
sc_debug(card->ctx, "%s\n", iso7816_errors[i].errorstr);
return iso7816_errors[i].errorno;
}
sc_error(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
sc_debug(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X\n", sw1, sw2);
return SC_ERROR_CARD_CMD_FAILED;
}
@ -112,7 +112,7 @@ static int iso7816_read_binary(sc_card_t *card,
int r;
if (idx > 0x7fff) {
sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
sc_debug(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
return SC_ERROR_OFFSET_TOO_LARGE;
}
@ -166,7 +166,7 @@ static int iso7816_write_record(sc_card_t *card, unsigned int rec_nr,
int r;
if (count > 256) {
sc_error(card->ctx, "Trying to send too many bytes\n");
sc_debug(card->ctx, "Trying to send too many bytes\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xD2, rec_nr, 0);
@ -193,7 +193,7 @@ static int iso7816_append_record(sc_card_t *card,
int r;
if (count > 256) {
sc_error(card->ctx, "Trying to send too many bytes\n");
sc_debug(card->ctx, "Trying to send too many bytes\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xE2, 0, 0);
@ -218,7 +218,7 @@ static int iso7816_update_record(sc_card_t *card, unsigned int rec_nr,
int r;
if (count > 256) {
sc_error(card->ctx, "Trying to send too many bytes\n");
sc_debug(card->ctx, "Trying to send too many bytes\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xDC, rec_nr, 0);
@ -247,7 +247,7 @@ static int iso7816_write_binary(sc_card_t *card,
assert(count <= card->max_send_size);
if (idx > 0x7fff) {
sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
sc_debug(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
return SC_ERROR_OFFSET_TOO_LARGE;
}
@ -274,7 +274,7 @@ static int iso7816_update_binary(sc_card_t *card,
assert(count <= card->max_send_size);
if (idx > 0x7fff) {
sc_error(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
sc_debug(card->ctx, "invalid EF offset: 0x%X > 0x7FFF", idx);
return SC_ERROR_OFFSET_TOO_LARGE;
}
@ -642,7 +642,7 @@ static int iso7816_delete_file(sc_card_t *card, const sc_path_t *path)
SC_FUNC_CALLED(card->ctx, 1);
if (path->type != SC_PATH_TYPE_FILE_ID || (path->len != 0 && path->len != 2)) {
sc_error(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
sc_debug(card->ctx, "File type has to be SC_PATH_TYPE_FILE_ID\n");
SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_INVALID_ARGUMENTS);
}
@ -782,7 +782,6 @@ static int iso7816_compute_signature(sc_card_t *card,
apdu.data = sbuf;
apdu.lc = datalen;
apdu.datalen = datalen;
apdu.sensitive = 1;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
@ -819,7 +818,6 @@ static int iso7816_decipher(sc_card_t *card,
* to tell the card the we want everything available (note: we
* always have Le <= crgram_len) */
apdu.le = (outlen >= 256 && crgram_len < 256) ? 256 : outlen;
apdu.sensitive = 1;
sbuf[0] = 0; /* padding indicator byte, 0x00 = No further indication */
memcpy(sbuf + 1, crgram, crgram_len);
@ -908,7 +906,6 @@ static int iso7816_build_pin_apdu(sc_card_t *card, sc_apdu_t *apdu,
apdu->datalen = len;
apdu->data = buf;
apdu->resplen = 0;
apdu->sensitive = 1;
return 0;
}
@ -946,7 +943,7 @@ static int iso7816_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
/* Call the reader driver to collect
* the PIN and pass on the APDU to the card */
if (data->pin1.offset == 0) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Card driver didn't set PIN offset");
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -958,7 +955,7 @@ static int iso7816_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
data);
/* sw1/sw2 filled in by reader driver */
} else {
sc_error(card->ctx,
sc_debug(card->ctx,
"Card reader driver does not support "
"PIN entry through reader key pad");
r = SC_ERROR_NOT_SUPPORTED;

View File

@ -1,7 +1,6 @@
_sc_asn1_decode
_sc_asn1_encode
_sc_debug
_sc_error
sc_append_file_id
sc_append_path
sc_append_path_id
@ -41,8 +40,6 @@ sc_create_file
sc_ctx_detect_readers
sc_ctx_get_reader
sc_ctx_get_reader_count
sc_ctx_suppress_errors_off
sc_ctx_suppress_errors_on
sc_decipher
sc_delete_file
sc_delete_record
@ -159,6 +156,7 @@ sc_pkcs15_make_absolute_path
sc_pkcs15_parse_df
sc_pkcs15_parse_tokeninfo
sc_pkcs15_parse_unusedspace
sc_pkcs15_pincache_clear
sc_pkcs15_print_id
sc_pkcs15_read_cached_file
sc_pkcs15_read_certificate

View File

@ -35,16 +35,6 @@
#include <io.h>
#endif
/* Although not used, we need this for consistent exports */
void _sc_error(sc_context_t *ctx, const char *format, ...)
{
va_list ap;
va_start(ap, format);
sc_do_log_va(ctx, SC_LOG_TYPE_ERROR, NULL, 0, NULL, format, ap);
va_end(ap);
}
/* Although not used, we need this for consistent exports */
void _sc_debug(sc_context_t *ctx, const char *format, ...)
{
@ -68,24 +58,12 @@ void sc_do_log_va(sc_context_t *ctx, int type, const char *file, int line, const
{
int (*display_fn)(sc_context_t *, const char *);
char buf[1836], *p;
const char *tag = "";
int r;
size_t left;
assert(ctx != NULL);
switch (type) {
case SC_LOG_TYPE_ERROR:
if (!ctx->suppress_errors) {
display_fn = &sc_ui_display_error;
tag = "error:";
break;
}
/* Fall thru - suppressed errors are logged as
* debug messages */
tag = "error (suppressed):";
type = SC_LOG_TYPE_DEBUG;
case SC_LOG_TYPE_DEBUG:
if (ctx->debug == 0)
return;

View File

@ -40,15 +40,12 @@ extern "C" {
#if defined(__GNUC__)
#define sc_error(ctx, format, args...) sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#define sc_debug(ctx, format, args...) sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, format , ## args)
#else
#define sc_error _sc_error
#define sc_debug _sc_debug
#endif
void _sc_error(struct sc_context *ctx, const char *format, ...);
void _sc_debug(struct sc_context *ctx, const char *format, ...);
void sc_do_log(struct sc_context *ctx, int type, const char *file, int line, const char *func, const char *format, ...);
void sc_do_log_va(struct sc_context *ctx, int type, const char *file, int line, const char *func, const char *format, va_list args);
@ -62,9 +59,7 @@ void sc_hex_dump(struct sc_context *ctx, const u8 * buf, size_t len, char *out,
#define SC_FUNC_RETURN(ctx, level, r) do { \
int _ret = r; \
if (_ret < 0 && !ctx->suppress_errors) { \
sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, "returning with: %s\n", sc_strerror(_ret)); \
} else if (ctx->debug >= level) { \
if (ctx->debug >= level) { \
sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "returning with: %d\n", _ret); \
} \
return _ret; \
@ -73,13 +68,13 @@ void sc_hex_dump(struct sc_context *ctx, const u8 * buf, size_t len, char *out,
#define SC_TEST_RET(ctx, r, text) do { \
int _ret = (r); \
if (_ret < 0) { \
sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", (text), sc_strerror(_ret)); \
sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", (text), sc_strerror(_ret)); \
return _ret; \
} \
} while(0)
#define sc_perror(ctx, errno, str) { \
sc_do_log(ctx, SC_LOG_TYPE_ERROR, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", str, sc_strerror(errno)); \
sc_do_log(ctx, SC_LOG_TYPE_DEBUG, __FILE__, __LINE__, __FUNCTION__, "%s: %s\n", str, sc_strerror(errno)); \
}
#ifdef __cplusplus

View File

@ -60,7 +60,7 @@ int msc_list_objects(sc_card_t* card, u8 next, mscfs_file_t* file) {
if(apdu.resplen == 0) /* No more left */
return 0;
if (apdu.resplen != 14) {
sc_error(card->ctx, "expected 14 bytes, got %d.\n", apdu.resplen);
sc_debug(card->ctx, "expected 14 bytes, got %d.\n", apdu.resplen);
return SC_ERROR_UNKNOWN_DATA_RECEIVED;
}
memcpy(file->objectId.id, fileData, 4);
@ -499,9 +499,7 @@ int msc_get_challenge(sc_card_t *card, unsigned short dataLength, unsigned short
r = msc_read_object(card, inputId, 2, outputData, dataLength);
if(r < 0)
SC_FUNC_RETURN(card->ctx, 0, r);
sc_ctx_suppress_errors_on(card->ctx);
msc_delete_object(card, inputId,0);
sc_ctx_suppress_errors_off(card->ctx);
SC_FUNC_RETURN(card->ctx, 0, r);
}
}
@ -829,23 +827,19 @@ static int msc_compute_crypt_final_object(
ptr++;
memcpy(ptr, inputData, dataLength);
sc_ctx_suppress_errors_on(card->ctx);
r = msc_create_object(card, outputId, dataLength + 2, 0x02, 0x02, 0x02);
if(r < 0) {
if(r == SC_ERROR_FILE_ALREADY_EXISTS) {
r = msc_delete_object(card, outputId, 0);
if(r < 0) {
sc_ctx_suppress_errors_off(card->ctx);
SC_FUNC_RETURN(card->ctx, 2, r);
}
r = msc_create_object(card, outputId, dataLength + 2, 0x02, 0x02, 0x02);
if(r < 0) {
sc_ctx_suppress_errors_off(card->ctx);
SC_FUNC_RETURN(card->ctx, 2, r);
}
}
}
sc_ctx_suppress_errors_off(card->ctx);
r = msc_update_object(card, outputId, 0, buffer + 1, dataLength + 2);
if(r < 0) return r;
@ -868,10 +862,8 @@ static int msc_compute_crypt_final_object(
} else {
r = SC_ERROR_CARD_CMD_FAILED;
}
/* no error checks.. this is last ditch cleanup */
sc_ctx_suppress_errors_on(card->ctx);
/* this is last ditch cleanup */
msc_delete_object(card, outputId, 0);
sc_ctx_suppress_errors_off(card->ctx);
SC_FUNC_RETURN(card->ctx, 0, r);
}
@ -996,25 +988,21 @@ int msc_import_key(sc_card_t *card,
CPYVAL(dq1);
}
sc_ctx_suppress_errors_on(card->ctx);
r = msc_create_object(card, outputId, bufferSize, 0x02, 0x02, 0x02);
if(r < 0) {
if(r == SC_ERROR_FILE_ALREADY_EXISTS) {
r = msc_delete_object(card, outputId, 0);
if(r < 0) {
sc_ctx_suppress_errors_off(card->ctx);
free(buffer);
SC_FUNC_RETURN(card->ctx, 2, r);
}
r = msc_create_object(card, outputId, bufferSize, 0x02, 0x02, 0x02);
if(r < 0) {
sc_ctx_suppress_errors_off(card->ctx);
free(buffer);
SC_FUNC_RETURN(card->ctx, 2, r);
}
}
}
sc_ctx_suppress_errors_off(card->ctx);
r = msc_update_object(card, outputId, 0, buffer, bufferSize);
free(buffer);
@ -1041,16 +1029,12 @@ int msc_import_key(sc_card_t *card,
sc_debug(card->ctx, "keyimport: got strange SWs: 0x%02X 0x%02X\n",
apdu.sw1, apdu.sw2);
}
/* no error checks.. this is last ditch cleanup */
sc_ctx_suppress_errors_on(card->ctx);
/* this is last ditch cleanup */
msc_delete_object(card, outputId, 0);
sc_ctx_suppress_errors_off(card->ctx);
SC_FUNC_RETURN(card->ctx, 0, r);
}
/* no error checks.. this is last ditch cleanup */
sc_ctx_suppress_errors_on(card->ctx);
/* this is last ditch cleanup */
msc_delete_object(card, outputId, 0);
sc_ctx_suppress_errors_off(card->ctx);
SC_FUNC_RETURN(card->ctx, 0, SC_ERROR_CARD_CMD_FAILED);
}

View File

@ -326,8 +326,9 @@ typedef struct sc_reader {
#define SC_PIN_CMD_CHANGE 1
#define SC_PIN_CMD_UNBLOCK 2
#define SC_PIN_CMD_USE_PINPAD 0x0001
#define SC_PIN_CMD_NEED_PADDING 0x0002
#define SC_PIN_CMD_USE_PINPAD 0x0001
#define SC_PIN_CMD_NEED_PADDING 0x0002
#define SC_PIN_CMD_IMPLICIT_CHANGE 0x0004
#define SC_PIN_ENCODING_ASCII 0
#define SC_PIN_ENCODING_BCD 1
@ -658,8 +659,7 @@ typedef struct sc_context {
char *app_name;
int debug;
int suppress_errors;
FILE *debug_file, *error_file;
FILE *debug_file;
char *preferred_language;
const struct sc_reader_driver *reader_drivers[SC_MAX_READER_DRIVERS];
@ -761,18 +761,6 @@ sc_reader_t *sc_ctx_get_reader(sc_context_t *ctx, unsigned int i);
*/
unsigned int sc_ctx_get_reader_count(sc_context_t *ctx);
/**
* Turns on error suppression
* @param ctx OpenSC context
*/
void sc_ctx_suppress_errors_on(sc_context_t *ctx);
/**
* Turns off error suppression
* @param ctx OpenSC context
*/
void sc_ctx_suppress_errors_off(sc_context_t *ctx);
/**
* Forces the use of a specified card driver
* @param ctx OpenSC context
@ -1153,6 +1141,7 @@ int sc_base64_decode(const char *in, u8 *out, size_t outlen);
* @param len length of the memory buffer
*/
void sc_mem_clear(void *ptr, size_t len);
void *sc_mem_alloc_secure(size_t len);
int sc_get_cache_dir(sc_context_t *ctx, char *buf, size_t bufsize);
int sc_make_cache_dir(sc_context_t *ctx);

View File

@ -142,29 +142,29 @@ CERT_HANDLE_FUNCTION(default_cert_handle) {
int modulus_len = 0;
const prdata* key = get_prkey_by_cert(items, cert);
if(!key) {
sc_error(p15card->card->ctx, "Error: No key for this certificate");
sc_debug(p15card->card->ctx, "Error: No key for this certificate");
return SC_ERROR_INTERNAL;
}
if(!d2i_X509(&cert_data, (const u8**)&data, length)) {
sc_error(p15card->card->ctx, "Error converting certificate");
sc_debug(p15card->card->ctx, "Error converting certificate");
return SC_ERROR_INTERNAL;
}
pkey = X509_get_pubkey(cert_data);
if(pkey == NULL) {
sc_error(p15card->card->ctx, "Error: no public key associated with the certificate");
sc_debug(p15card->card->ctx, "Error: no public key associated with the certificate");
r = SC_ERROR_INTERNAL;
goto err;
}
if(! EVP_PK_RSA & (certtype = X509_certificate_type(cert_data, pkey))) {
sc_error(p15card->card->ctx, "Error: certificate is not for an RSA key");
sc_debug(p15card->card->ctx, "Error: certificate is not for an RSA key");
r = SC_ERROR_INTERNAL;
goto err;
}
if(pkey->pkey.rsa->n == NULL) {
sc_error(p15card->card->ctx, "Error: no modulus associated with the certificate");
sc_debug(p15card->card->ctx, "Error: no modulus associated with the certificate");
r = SC_ERROR_INTERNAL;
goto err;
}

View File

@ -34,7 +34,6 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
int modulus_length = 0, usage = 0;
char buf[256];
sc_card_t *card = p15card->card;
sc_context_t *ctx = card->ctx;
sc_serial_number_t serial;
sc_path_t path;
sc_file_t *file = NULL;
@ -63,9 +62,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
p15card->version = buf[6];
p15card->flags = SC_PKCS15_CARD_FLAG_LOGIN_REQUIRED;
sc_format_path("AAAA", &path);
sc_ctx_suppress_errors_on(ctx);
r = sc_select_file(card, &path, &file);
sc_ctx_suppress_errors_off(ctx);
if (!r) {
for (i = 0; i < 1; i++) {
unsigned int flags;
@ -110,9 +107,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
sc_file_free(file);
file = NULL;
sc_format_path("0002", &path);
sc_ctx_suppress_errors_on(ctx);
r = sc_select_file(card, &path, &file);
sc_ctx_suppress_errors_off(ctx);
if (!r) {
struct sc_pkcs15_cert_info cert_info;
struct sc_pkcs15_object cert_obj;
@ -125,11 +120,9 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
cert_info.id.value[0] = 0x45;
cert_info.authority = 0;
cert_info.path = path;
sc_ctx_suppress_errors_on(ctx);
r = sc_pkcs15_read_certificate(p15card, &cert_info,
(sc_pkcs15_cert_t
**) (&cert_obj.data));
sc_ctx_suppress_errors_off(ctx);
if (!r) {
sc_pkcs15_cert_t *cert =
(sc_pkcs15_cert_t *) (cert_obj.data);
@ -189,9 +182,7 @@ static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
sc_file_free(file);
file = NULL;
sc_format_path("0001", &path);
sc_ctx_suppress_errors_on(ctx);
r = sc_select_file(card, &path, &file);
sc_ctx_suppress_errors_off(ctx);
if (!r) {
struct sc_pkcs15_prkey_info prkey_info;
struct sc_pkcs15_object prkey_obj;

View File

@ -231,7 +231,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
i = sc_pkcs1_add_digest_info_prefix(hash_algo, in, in_len,
out, &tmp_len);
if (i != SC_SUCCESS) {
sc_error(ctx, "Unable to add digest info 0x%x\n",
sc_debug(ctx, "Unable to add digest info 0x%x\n",
hash_algo);
return i;
}
@ -252,7 +252,7 @@ int sc_pkcs1_encode(sc_context_t *ctx, unsigned long flags,
mod_len);
default:
/* currently only pkcs1 padding is supported */
sc_error(ctx, "Unsupported padding algorithm 0x%x\n", pad_algo);
sc_debug(ctx, "Unsupported padding algorithm 0x%x\n", pad_algo);
return SC_ERROR_NOT_SUPPORTED;
}
}
@ -284,14 +284,14 @@ int sc_get_encoding_flags(sc_context_t *ctx,
*pflags |= SC_ALGORITHM_RSA_PAD_PKCS1;
} else if ((iflags & SC_ALGORITHM_RSA_PADS) == SC_ALGORITHM_RSA_PAD_NONE) {
if (!(caps & SC_ALGORITHM_RSA_RAW)) {
sc_error(ctx, "raw RSA is not supported");
sc_debug(ctx, "raw RSA is not supported");
return SC_ERROR_NOT_SUPPORTED;
}
*sflags |= SC_ALGORITHM_RSA_RAW;
/* in case of raw RSA there is nothing to pad */
*pflags = 0;
} else {
sc_error(ctx, "unsupported algorithm");
sc_debug(ctx, "unsupported algorithm");
return SC_ERROR_NOT_SUPPORTED;
}

View File

@ -177,7 +177,7 @@ static int sc_pkcs15emu_actalis_init(sc_pkcs15_card_t * p15card)
const char *authPRKEY = "Authentication Key";
/* const char *nonrepPRKEY = "Non repudiation Key"; */
p15card->opts.use_cache = 1;
p15card->opts.use_file_cache = 1;
/* Get Serial number */
sc_format_path("3F0030000001", &path);

View File

@ -345,7 +345,7 @@ sc_asn1_encode_algorithm_id(sc_context_t *ctx,
alg_info = sc_asn1_get_algorithm_info(id);
if (alg_info == NULL) {
sc_error(ctx, "Cannot encode unknown algorithm %u.\n",
sc_debug(ctx, "Cannot encode unknown algorithm %u.\n",
id->algorithm);
return SC_ERROR_INVALID_ARGUMENTS;
}

View File

@ -95,9 +95,7 @@ static int acos_detect_card(sc_pkcs15_card_t *p15card)
return SC_ERROR_WRONG_CARD;
/* read EF_CIN_CSN file */
sc_format_path("DF71D001", &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r != SC_SUCCESS)
return SC_ERROR_WRONG_CARD;
r = sc_read_binary(card, 0, buf, 8, 0);
@ -163,9 +161,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card)
/* read EF_CIN_CSN file */
sc_format_path("DF71D001", &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r != SC_SUCCESS)
return SC_ERROR_INTERNAL;
r = sc_read_binary(card, 0, buf, 8, 0);

View File

@ -154,7 +154,7 @@ int sc_pkcs15_cache_file(struct sc_pkcs15_card *p15card,
c = fwrite(buf, 1, bufsize, f);
fclose(f);
if (c != bufsize) {
sc_error(p15card->card->ctx, "fwrite() wrote only %d bytes", c);
sc_debug(p15card->card->ctx, "fwrite() wrote only %d bytes", c);
unlink(fname);
return SC_ERROR_INTERNAL;
}

View File

@ -80,7 +80,7 @@ static int parse_x509_cert(sc_context_t *ctx, const u8 *buf, size_t buflen, stru
obj = sc_asn1_verify_tag(ctx, buf, buflen, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS,
&objlen);
if (obj == NULL) {
sc_error(ctx, "X.509 certificate not found\n");
sc_debug(ctx, "X.509 certificate not found\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
cert->data_len = objlen + (obj - buf);

View File

@ -65,7 +65,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
iconv_t iso_utf;
char *inptr, *outptr;
size_t inbytes, outbytes, result;
unsigned char label[64], name1[32], name2[32];
char label[64], name1[32], name2[32];
#endif
unsigned char buff[128];
int r, i, flags;
@ -73,6 +73,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
set_string (&p15card->label, "ID-kaart");
set_string (&p15card->manufacturer_id, "AS Sertifitseerimiskeskus");
p15card->version = 2; /* Increases as the code changes for EstEID happen, not only in this file */
/* Select application directory */
sc_format_path ("3f00eeee5044", &tmppath);
@ -94,7 +95,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
r = sc_read_record (card, SC_ESTEID_PD_GIVEN_NAMES1, buff, sizeof(buff), SC_RECORD_BY_REC_NR);
SC_TEST_RET (card->ctx, r, "read name1 failed");
inptr = buff;
inptr = (char *) buff;
outptr = name1;
inbytes = r;
outbytes = 32;
@ -105,7 +106,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
r = sc_read_record (card, SC_ESTEID_PD_SURNAME, buff, sizeof(buff), SC_RECORD_BY_REC_NR);
SC_TEST_RET (card->ctx, r, "read name2 failed");
inptr = buff;
inptr = (char *) buff;
outptr = name2;
inbytes = r;
outbytes = 32;
@ -113,7 +114,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
if (result == (size_t) -1)
return SC_ERROR_INTERNAL;
*outptr = '\0';
iconv_close(iso_utf);
snprintf(label, sizeof(label), "%s %s", name1, name2);
set_string (&p15card->label, label);
#endif
@ -192,6 +193,7 @@ sc_pkcs15emu_esteid_init (sc_pkcs15_card_t * p15card)
pin_info.max_length = 12;
pin_info.pad_char = '\0';
pin_info.tries_left = (int)tries_left;
pin_info.max_tries = 3;
strlcpy(pin_obj.label, esteid_pin_names[i], sizeof(pin_obj.label));
pin_obj.flags = esteid_pin_flags[i];

View File

@ -259,14 +259,10 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
path.value[1] = i;
path.len = 2;
path.type = SC_PATH_TYPE_FILE_ID;
sc_ctx_suppress_errors_on(card->ctx); /* file may not exist, and not an error */
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r < 0)
continue;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_read_record(card, 1, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR);
sc_ctx_suppress_errors_off(card->ctx);
if (r != 7 || sysrec[0] != 0) {
continue;
}
@ -279,7 +275,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
case 0x10: kinfo[num_keyinfo].modulus_len = 768 / 8; break;
case 0x11: kinfo[num_keyinfo].modulus_len = 1024 / 8; break;
default:
sc_error(card->ctx, "Unsupported modulus length");
sc_debug(card->ctx, "Unsupported modulus length");
continue;
}

View File

@ -144,7 +144,7 @@ static int gemsafe_get_cert_len(sc_card_t *card, sc_path_t *path,
sc_debug(card->ctx, "%s: Certificate object is of size: %d\n", fn_name, objlen);
if (objlen < 1 || objlen > 10240) {
sc_error(card->ctx, "%s: Invalid object size: %d\n", fn_name, objlen);
sc_debug(card->ctx, "%s: Invalid object size: %d\n", fn_name, objlen);
return 0;
}
@ -184,7 +184,7 @@ static int gemsafe_get_cert_len(sc_card_t *card, sc_path_t *path,
offset = block*248;
r = sc_read_binary(card, offset, ibuf, 248, 0);
if (r < 0) {
sc_error(card->ctx, "%s: Could not read cert object\n", fn_name);
sc_debug(card->ctx, "%s: Could not read cert object\n", fn_name);
return 0;
}
}
@ -416,7 +416,7 @@ sc_pkcs15emu_add_object(sc_pkcs15_card_t *p15card, int type,
df_type = SC_PKCS15_CDF;
break;
default:
sc_error(p15card->card->ctx,
sc_debug(p15card->card->ctx,
"Unknown PKCS15 object type %d\n", type);
free(obj);
return SC_ERROR_INVALID_ARGUMENTS;

View File

@ -242,9 +242,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
sc_format_path("3F002F02", &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, &file);
sc_ctx_suppress_errors_off(card->ctx);
if (r != SC_SUCCESS || file->size > 255) {
/* Not EF.GDO */
@ -308,9 +306,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
sc_format_path(infocamere_auth_certpath[ef_gdo[len_iccsn+6]-2], &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r >= 0) {
@ -398,9 +394,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
sc_format_path(infocamere_cacert_path[ef_gdo[len_iccsn+6]-2], &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r >= 0) {
size_t len;
@ -530,7 +524,7 @@ static int loadCertificate(sc_pkcs15_card_t * p15card, int i,
sc_read_binary(card, 4, compCert, compLen, 0);
if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) {
sc_error(p15card->card->ctx, "Zlib error: %d", r);
sc_debug(p15card->card->ctx, "Zlib error: %d", r);
return SC_ERROR_INTERNAL;
}
@ -596,7 +590,7 @@ static int infocamere_1400_init(sc_pkcs15_card_t * p15card)
set_security_env = card->ops->set_security_env;
card->ops->set_security_env = infocamere_1400_set_sec_env;
card->ops->compute_signature = do_sign;
p15card->opts.use_cache = 1;
p15card->opts.use_file_cache = 1;
sc_format_path("30000001", &path);
@ -614,7 +608,7 @@ static int infocamere_1400_init(sc_pkcs15_card_t * p15card)
if ((r = loadCertificate(p15card, 0, certPath[0], certLabel[0])) !=
SC_SUCCESS) {
sc_error(p15card->card->ctx, "%s", sc_strerror(r));
sc_debug(p15card->card->ctx, "%s", sc_strerror(r));
return SC_ERROR_WRONG_CARD;
}

View File

@ -119,7 +119,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
if ((r = read_file(card, "006E007300C4", buffer, sizeof(buffer))) < 0)
goto failed;
if (r != 7) {
sc_error(ctx,
sc_debug(ctx,
"CHV status bytes have unexpected length "
"(expected 7, got %d)\n", r);
return SC_ERROR_OBJECT_NOT_VALID;
@ -229,7 +229,7 @@ sc_pkcs15emu_openpgp_init(sc_pkcs15_card_t *p15card)
return 0;
failed: sc_error(card->ctx, "Failed to initialize OpenPGP emulation: %s\n",
failed: sc_debug(card->ctx, "Failed to initialize OpenPGP emulation: %s\n",
sc_strerror(r));
return r;
}

View File

@ -51,6 +51,8 @@ static const struct sc_asn1_entry c_asn1_pin[] = {
{ NULL, 0, 0, 0, NULL, NULL }
};
static void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card, struct sc_pkcs15_pin_info *pininfo, const u8 *pin, size_t pinlen);
int sc_pkcs15_decode_aodf_entry(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_object *obj,
const u8 ** buf, size_t *buflen)
@ -198,15 +200,13 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
sc_card_t *card;
struct sc_pin_cmd_data data;
SC_FUNC_CALLED(p15card->card->ctx, 2);
if ((r = _validate_pin(p15card, pin, pinlen)) != SC_SUCCESS)
return r;
card = p15card->card;
r = sc_lock(card);
if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
r = sc_lock(card);
}
SC_TEST_RET(card->ctx, r, "sc_lock() failed");
/* the path in the pin object is optional */
if (pin->path.len > 0) {
@ -251,6 +251,8 @@ int sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card,
}
r = sc_pin_cmd(card, &data, &pin->tries_left);
if (r == SC_SUCCESS)
sc_pkcs15_pincache_add(p15card, pin, pincode, pinlen);
out:
sc_unlock(card);
return r;
@ -328,6 +330,8 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
}
r = sc_pin_cmd(card, &data, &pin->tries_left);
if (r == SC_SUCCESS)
sc_pkcs15_pincache_add(p15card, pin, newpin, newpinlen);
out:
sc_unlock(card);
@ -436,6 +440,8 @@ int sc_pkcs15_unblock_pin(struct sc_pkcs15_card *p15card,
}
r = sc_pin_cmd(card, &data, &pin->tries_left);
if (r == SC_SUCCESS)
sc_pkcs15_pincache_add(p15card, pin, newpin, newpinlen);
out:
sc_unlock(card);
@ -446,3 +452,94 @@ void sc_pkcs15_free_pin_info(sc_pkcs15_pin_info_t *pin)
{
free(pin);
}
/* Add a PIN to the PIN cache related to the card. Some operations can trigger re-authentication later. */
static void sc_pkcs15_pincache_add(struct sc_pkcs15_card *p15card,
struct sc_pkcs15_pin_info *pininfo,
const u8 *pin, size_t pinlen)
{
int i;
sc_pkcs15_pincache_entry_t *entry;
sc_pkcs15_object_t *obj;
SC_FUNC_CALLED(p15card->card->ctx, 2);
if (!p15card->opts.use_pin_cache)
return;
/* Is it a user consent protecting PIN ? */
if (sc_pkcs15_find_prkey_by_reference(p15card, NULL, pininfo->reference, &obj) == SC_SUCCESS) {
if (obj->user_consent) {
sc_debug(p15card->card->ctx, "Not caching userconsent related PIN");
return;
}
}
for (i=0; i<SC_PKCS15_MAX_PINS; i++) {
if (p15card->pin_cache[i] == NULL) {
entry = (sc_pkcs15_pincache_entry_t *) sc_mem_alloc_secure(sizeof(sc_pkcs15_pincache_entry_t));
if (!entry)
return;
memcpy(&entry->id, &pininfo->auth_id, sizeof(sc_pkcs15_id_t));
memcpy(&entry->pin, pin, pinlen);
entry->len = pinlen;
entry->counter = 0;
p15card->pin_cache[i] = entry;
return;
} else { /* Update the existing PIN */
sc_pkcs15_pincache_entry_t *entry = p15card->pin_cache[i];
if (sc_pkcs15_compare_id(&entry->id, &pininfo->auth_id)) {
memcpy(&entry->pin, pin, pinlen);
entry->len = pinlen;
entry->counter = 0;
return;
}
}
}
}
/* Validate the PIN code associated with an object */
int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj)
{
int r, i;
sc_pkcs15_object_t *pin_obj;
sc_pkcs15_pin_info_t *pin_info;
SC_FUNC_CALLED(p15card->card->ctx, 2);
if (!p15card->opts.use_pin_cache)
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
if (obj->user_consent)
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
if (p15card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD)
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj);
if (r != SC_SUCCESS) {
sc_debug(p15card->card->ctx, "Could not find pin object for auth_id %s", sc_pkcs15_print_id(&obj->auth_id));
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
}
pin_info = (sc_pkcs15_pin_info_t *) pin_obj->data;
for (i=0; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++) {
sc_pkcs15_pincache_entry_t *entry = p15card->pin_cache[i];
if (sc_pkcs15_compare_id(&entry->id, &obj->auth_id)) {
if (entry->counter >= p15card->opts.pin_cache_counter) {
sc_mem_clear(entry->pin, entry->len);
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
}
entry->counter++;
return sc_pkcs15_verify_pin(p15card, pin_info, entry->pin, entry->len);
}
}
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
}
void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card)
{
int i;
for (i=0; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++)
sc_mem_clear(p15card->pin_cache[i]->pin, p15card->pin_cache[i]->len);
}

View File

@ -248,9 +248,7 @@ const objdata objects[] = {
* but need serial number for Mac tokend
*/
sc_ctx_suppress_errors_on(card->ctx);
r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
sc_ctx_suppress_errors_off(card->ctx);
if (r < 0) {
sc_debug(card->ctx,"sc_card_ctl rc=%d",r);
p15card->serial_number = strdup("00000000");
@ -273,12 +271,10 @@ const objdata objects[] = {
/* We could make sure the object is on the card */
/* But really don't need to do this now */
// sc_ctx_suppress_errors_on(card->ctx);
// r = sc_select_file(card, &obj_info.path, NULL);
// sc_ctx_suppress_errors_off(card->ctx);
// if (r == SC_ERROR_FILE_NOT_FOUND)
// continue;
/* r = sc_select_file(card, &obj_info.path, NULL);
if (r == SC_ERROR_FILE_NOT_FOUND)
continue;
*/
strncpy(obj_info.app_label, objects[i].label, SC_PKCS15_MAX_LABEL_SIZE - 1);
r = sc_format_oid(&obj_info.app_oid, objects[i].aoid);
if (r != SC_SUCCESS)
@ -330,10 +326,8 @@ const objdata objects[] = {
/* see if we have a cert */
/* use a &file_out so card-piv will read cert if present */
sc_ctx_suppress_errors_on(card->ctx);
r = sc_pkcs15_read_file(p15card, &cert_info.path,
&cert_der.value, &cert_der.len, &file_out);
sc_ctx_suppress_errors_off(card->ctx);
if (file_out) {
sc_file_free(file_out);
file_out = NULL;
@ -368,7 +362,7 @@ const objdata objects[] = {
r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
if (r < 0) {
sc_error(card->ctx, " Failed to add cert obj r=%d",r);
sc_debug(card->ctx, " Failed to add cert obj r=%d",r);
continue;
}
}
@ -441,9 +435,7 @@ const objdata objects[] = {
/* TODO DSA */
pubkey_obj.type = SC_PKCS15_TYPE_PUBKEY_RSA;
pubkey_obj.data = &pubkey_info;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_pkcs15_read_pubkey(p15card, &pubkey_obj, &p15_key);
sc_ctx_suppress_errors_off(card->ctx);
pubkey_obj.data = NULL;
sc_debug(card->ctx," READING PUB KEY r=%d",r);
if (r < 0 ) {

View File

@ -332,7 +332,7 @@ static int sc_pkcs15emu_postecert_init(sc_pkcs15_card_t * p15card)
return 0;
failed:
sc_error(card->ctx,
sc_debug(card->ctx,
"Failed to initialize Postecert and Cnipa emulation: %s\n",
sc_strerror(r));
return r;

View File

@ -191,7 +191,7 @@ int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card,
keyinfo_gostparams->gostr3411 = gostr3410_params[1];
keyinfo_gostparams->gost28147 = gostr3410_params[2];
} else {
sc_error(ctx, "Neither RSA or DSA or GOSTR3410 key in PrKDF entry.\n");
sc_debug(ctx, "Neither RSA or DSA or GOSTR3410 key in PrKDF entry.\n");
SC_FUNC_RETURN(ctx, 0, SC_ERROR_INVALID_ASN1_OBJECT);
}
r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
@ -287,7 +287,7 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx,
}
break;
default:
sc_error(ctx, "Invalid private key type: %X\n", obj->type);
sc_debug(ctx, "Invalid private key type: %X\n", obj->type);
SC_FUNC_RETURN(ctx, 0, SC_ERROR_INTERNAL);
break;
}
@ -350,7 +350,7 @@ sc_pkcs15_encode_prkey(sc_context_t *ctx,
{
if (key->algorithm == SC_ALGORITHM_DSA)
return sc_pkcs15_encode_prkey_dsa(ctx, &key->u.dsa, buf, len);
sc_error(ctx, "Cannot encode private key type %u.\n",
sc_debug(ctx, "Cannot encode private key type %u.\n",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
}
@ -362,7 +362,7 @@ sc_pkcs15_decode_prkey(sc_context_t *ctx,
{
if (key->algorithm == SC_ALGORITHM_DSA)
return sc_pkcs15_decode_prkey_dsa(ctx, &key->u.dsa, buf, len);
sc_error(ctx, "Cannot decode private key type %u.\n",
sc_debug(ctx, "Cannot decode private key type %u.\n",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
}
@ -390,12 +390,12 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card,
key.algorithm = SC_ALGORITHM_DSA;
break;
default:
sc_error(ctx, "Unsupported object type.\n");
sc_debug(ctx, "Unsupported object type.\n");
return SC_ERROR_NOT_SUPPORTED;
}
info = (struct sc_pkcs15_prkey_info *) obj->data;
if (info->native) {
sc_error(ctx, "Private key is native, will not read.");
sc_debug(ctx, "Private key is native, will not read.");
return SC_ERROR_NOT_ALLOWED;
}
@ -405,7 +405,7 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card,
r = sc_pkcs15_read_file(p15card, &path, &data, &len, NULL);
if (r < 0) {
sc_error(ctx, "Unable to read private key file.\n");
sc_debug(ctx, "Unable to read private key file.\n");
return r;
}
@ -423,7 +423,7 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card,
data, len,
&clear, &clear_len);
if (r < 0) {
sc_error(ctx, "Failed to unwrap privat key.");
sc_debug(ctx, "Failed to unwrap privat key.");
goto fail;
}
free(data);
@ -433,7 +433,7 @@ sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card,
r = sc_pkcs15_decode_prkey(ctx, &key, data, len);
if (r < 0) {
sc_error(ctx, "Unable to decode private key");
sc_debug(ctx, "Unable to decode private key");
goto fail;
}

View File

@ -0,0 +1,295 @@
/*
* PKCS15 emulation layer for Portugal eID card.
*
* Copyright (C) 2009, Joao Poupino <joao.poupino@ist.utl.pt>
* Copyright (C) 2004, Martin Paljak <martin@paljak.pri.ee>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Based on the PKCS#15 emulation layer for EstEID card by Martin Paljak
*
*/
/*
* The card has a valid PKCS#15 file system. However, the private keys
* are missing the SC_PKCS15_CO_FLAG_PRIVATE flag and this causes problems
* with some applications (i.e. they don't work).
*
* The three main objectives of the emulation layer are:
*
* 1. Add the necessary SC_PKCS15_CO_FLAG_PRIVATE flag to private keys.
* 2. Hide "superfluous" PKCS#15 objects, e.g. PUKs (the user can't use them).
* 3. Improve usability by providing more descriptive names for the PINs, Keys, etc.
*
*/
#include "internal.h"
#include "pkcs15.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <compat_strlcpy.h>
#define IAS_CARD 0
#define GEMSAFE_CARD 1
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card)
{
int r, i, type;
unsigned char *buf;
size_t len;
sc_pkcs15_tokeninfo_t tokeninfo;
sc_path_t tmppath;
sc_card_t *card = p15card->card;
sc_context_t *ctx = card->ctx;
/* Parse the TokenInfo EF */
sc_format_path("3f004f005032", &tmppath);
r = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
if (r)
goto end;
if ( (len = p15card->file_tokeninfo->size) == 0) {
sc_debug(card->ctx, "EF(TokenInfo) is empty\n");
goto end;
}
buf = malloc(len);
if (buf == NULL)
return SC_ERROR_OUT_OF_MEMORY;
r = sc_read_binary(card, 0, buf, len, 0);
if (r < 0)
goto end;
if (r <= 2) {
r = SC_ERROR_PKCS15_APP_NOT_FOUND;
goto end;
}
memset(&tokeninfo, 0, sizeof(tokeninfo));
r = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t) r);
if (r != SC_SUCCESS)
goto end;
p15card->version = tokeninfo.version;
p15card->label = tokeninfo.label;
p15card->serial_number = tokeninfo.serial_number;
p15card->manufacturer_id = tokeninfo.manufacturer_id;
p15card->last_update = tokeninfo.last_update;
p15card->flags = tokeninfo.flags;
p15card->preferred_language = tokeninfo.preferred_language;
p15card->seInfo = tokeninfo.seInfo;
p15card->num_seInfo = tokeninfo.num_seInfo;
/* Card type detection */
if (card->type == SC_CARD_TYPE_IAS_PTEID)
type = IAS_CARD;
else if (card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID)
type = GEMSAFE_CARD;
else {
r = SC_ERROR_INTERNAL;
goto end;
}
p15card->flags = SC_PKCS15_CARD_FLAG_PRN_GENERATION
| SC_PKCS15_CARD_FLAG_EID_COMPLIANT
| SC_PKCS15_CARD_FLAG_READONLY;
/* TODO: Use the cardholder's name? */
/* TODO: Use Portuguese descriptions? */
/* Add X.509 Certificates */
static const char *pteid_cert_names[4] = {
"AUTHENTICATION CERTIFICATE",
"SIGNATURE CERTIFICATE",
"SIGNATURE SUB CA",
"AUTHENTICATION SUB CA"
};
/* X.509 Certificate Paths */
static const char *pteid_cert_paths[4] = {
"3f005f00ef09", /* Authentication Certificate path */
"3f005f00ef08", /* Digital Signature Certificate path */
"3f005f00ef0f", /* Signature sub CA path */
"3f005f00ef10" /* Authentication sub CA path */
};
/* X.509 Certificate IDs */
static const int pteid_cert_ids[4] = {0x45, 0x46, 0x51, 0x52};
struct sc_pkcs15_cert_info cert_info;
struct sc_pkcs15_object cert_obj;
for (i = 0; i < 4; i++) {
memset(&cert_info, 0, sizeof(cert_info));
memset(&cert_obj, 0, sizeof(cert_obj));
cert_info.id.value[0] = pteid_cert_ids[i];
cert_info.id.len = 1;
sc_format_path(pteid_cert_paths[i], &cert_info.path);
strlcpy(cert_obj.label, pteid_cert_names[i], sizeof(cert_obj.label));
r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
if (r < 0) {
r = SC_ERROR_INTERNAL;
goto end;
}
}
/* Add PINs */
static const char *pteid_pin_names[3] = {
"Auth PIN",
"Sign PIN",
"Address PIN"
};
/* PIN References */
static const int pteid_pin_ref[2][3] = { {1, 130, 131}, {129, 130, 131} };
/* PIN Authentication IDs */
static const int pteid_pin_authid[3] = {1, 2, 3};
/* PIN Paths */
static const char *pteid_pin_paths[2][3] = { {NULL, "3f005f00", NULL},
{NULL, NULL, NULL} };
struct sc_pkcs15_pin_info pin_info;
struct sc_pkcs15_object pin_obj;
for (i = 0; i < 3; i++) {
memset(&pin_info, 0, sizeof(pin_info));
memset(&pin_obj, 0, sizeof(pin_obj));
pin_info.auth_id.len = 1;
pin_info.auth_id.value[0] = pteid_pin_authid[i];
pin_info.reference = pteid_pin_ref[type][i];
pin_info.flags = SC_PKCS15_PIN_FLAG_NEEDS_PADDING
| SC_PKCS15_PIN_FLAG_INITIALIZED
| SC_PKCS15_PIN_FLAG_CASE_SENSITIVE;
pin_info.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC;
pin_info.min_length = 4;
pin_info.stored_length = 8;
pin_info.max_length = 8;
pin_info.pad_char = type == IAS_CARD ? 0x2F : 0xFF;
pin_info.tries_left = -1;
if (pteid_pin_paths[type][i] != NULL)
sc_format_path(pteid_pin_paths[type][i], &pin_info.path);
strlcpy(pin_obj.label, pteid_pin_names[i], sizeof(pin_obj.label));
pin_obj.flags = 0;
r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
if (r < 0) {
r = SC_ERROR_INTERNAL;
goto end;
}
}
/* Add Private Keys */
/* Key reference */
static const int pteid_prkey_keyref[2][2] = { {1, 130}, {2, 1} };
/* RSA Private Key usage */
static int pteid_prkey_usage[2] = {
SC_PKCS15_PRKEY_USAGE_SIGN,
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION};
/* RSA Private Key IDs */
static const int pteid_prkey_ids[2] = {0x45, 0x46};
static const char *pteid_prkey_names[2] = {
"CITIZEN AUTHENTICATION KEY",
"CITIZEN SIGNATURE KEY"};
/* RSA Private Key Paths */
static const char *pteid_prkey_paths[2][2] = { {NULL, "3f005f00"}, {NULL, NULL} };
struct sc_pkcs15_prkey_info prkey_info;
struct sc_pkcs15_object prkey_obj;
for (i = 0; i < 2; i++) {
memset(&prkey_info, 0, sizeof(prkey_info));
memset(&prkey_obj, 0, sizeof(prkey_obj));
prkey_info.id.len = 1;
prkey_info.id.value[0] = pteid_prkey_ids[i];
prkey_info.usage = pteid_prkey_usage[i];
prkey_info.native = 1;
prkey_info.key_reference = pteid_prkey_keyref[type][i];
prkey_info.modulus_length = 1024;
if (pteid_prkey_paths[type][i] != NULL)
sc_format_path(pteid_prkey_paths[type][i], &prkey_info.path);
strlcpy(prkey_obj.label, pteid_prkey_names[i], sizeof(prkey_obj.label));
prkey_obj.auth_id.len = 1;
prkey_obj.auth_id.value[0] = i + 1;
prkey_obj.user_consent = (i == 1) ? 1 : 0;
prkey_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE;
r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
if (r < 0) {
r = SC_ERROR_INTERNAL;
goto end;
}
}
/* Add objects */
static const char *object_ids[3] = {"1", "2", "3"};
static const char *object_oids[3] = {"-1", "-1", "-1"};
static const char *object_labels[3] = {"Citizen Data",
"Citizen Address Data",
"Citizen Notepad"};
static const char *object_authids[3] = {"3", "3", "1"};
static const char *object_paths[3] = {"3f005f00ef02",
"3f005f00ef05",
"3f005f00ef07"};
static const int object_flags[3] = {0,
SC_PKCS15_CO_FLAG_PRIVATE,
SC_PKCS15_CO_FLAG_MODIFIABLE};
struct sc_pkcs15_data_info obj_info;
struct sc_pkcs15_object obj_obj;
for (i = 0; i < 3; i++) {
memset(&obj_info, 0, sizeof(obj_info));
memset(&obj_obj, 0, sizeof(obj_obj));
sc_pkcs15_format_id(object_ids[i], &obj_info.id);
sc_format_path(object_paths[i], &obj_info.path);
r = sc_format_oid(&obj_info.app_oid, object_oids[i]);
if (r != SC_SUCCESS)
goto end;
strlcpy(obj_info.app_label, object_labels[i], SC_PKCS15_MAX_LABEL_SIZE);
if (object_authids[i] != NULL)
sc_pkcs15_format_id(object_authids[i], &obj_obj.auth_id);
strlcpy(obj_obj.label, object_labels[i], SC_PKCS15_MAX_LABEL_SIZE);
obj_obj.flags = object_flags[i];
r = sc_pkcs15emu_object_add(p15card, SC_PKCS15_TYPE_DATA_OBJECT, &obj_obj, &obj_info);
if (r < 0)
goto end;
}
end:
if (buf != NULL) {
free(buf);
buf = NULL;
}
if (r)
return r;
return SC_SUCCESS;
}
static int pteid_detect_card(sc_pkcs15_card_t *p15card)
{
if (p15card->card->type == SC_CARD_TYPE_IAS_PTEID ||
p15card->card->type == SC_CARD_TYPE_GEMSAFEV1_PTEID)
return SC_SUCCESS;
return SC_ERROR_WRONG_CARD;
}
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, sc_pkcs15emu_opt_t *opts)
{
if (opts != NULL && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
return sc_pkcs15emu_pteid_init(p15card);
else {
int r = pteid_detect_card(p15card);
if (r)
return SC_ERROR_WRONG_CARD;
return sc_pkcs15emu_pteid_init(p15card);
}
}

View File

@ -273,7 +273,7 @@ int sc_pkcs15_encode_pukdf_entry(sc_context_t *ctx,
}
break;
default:
sc_error(ctx, "Unsupported public key type: %X\n", obj->type);
sc_debug(ctx, "Unsupported public key type: %X\n", obj->type);
SC_FUNC_RETURN(ctx, 0, SC_ERROR_INTERNAL);
break;
}
@ -484,7 +484,7 @@ sc_pkcs15_encode_pubkey(sc_context_t *ctx,
if (key->algorithm == SC_ALGORITHM_GOSTR3410)
return sc_pkcs15_encode_pubkey_gostr3410(ctx,
&key->u.gostr3410, buf, len);
sc_error(ctx, "Encoding of public key type %u not supported\n",
sc_debug(ctx, "Encoding of public key type %u not supported\n",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
}
@ -501,7 +501,7 @@ sc_pkcs15_decode_pubkey(sc_context_t *ctx,
if (key->algorithm == SC_ALGORITHM_GOSTR3410)
return sc_pkcs15_decode_pubkey_gostr3410(ctx,
&key->u.gostr3410, buf, len);
sc_error(ctx, "Decoding of public key type %u not supported\n",
sc_debug(ctx, "Decoding of public key type %u not supported\n",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
}
@ -534,14 +534,14 @@ sc_pkcs15_read_pubkey(struct sc_pkcs15_card *p15card,
algorithm = SC_ALGORITHM_GOSTR3410;
break;
default:
sc_error(p15card->card->ctx, "Unsupported public key type.");
sc_debug(p15card->card->ctx, "Unsupported public key type.");
return SC_ERROR_NOT_SUPPORTED;
}
info = (const struct sc_pkcs15_pubkey_info *) obj->data;
r = sc_pkcs15_read_file(p15card, &info->path, &data, &len, NULL);
if (r < 0) {
sc_error(p15card->card->ctx, "Failed to read public key file.");
sc_debug(p15card->card->ctx, "Failed to read public key file.");
return r;
}
@ -583,7 +583,7 @@ sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx,
struct sc_pkcs15_prkey *prvkey, struct sc_pkcs15_pubkey **out)
{
struct sc_pkcs15_pubkey *pubkey;
int ii, rv = SC_SUCCESS;
int rv = SC_SUCCESS;
assert(prvkey && out);
@ -611,7 +611,7 @@ sc_pkcs15_pubkey_from_prvkey(struct sc_context *ctx,
case SC_ALGORITHM_GOSTR3410:
break;
default:
sc_error(ctx, "Unsupported private key algorithm");
sc_debug(ctx, "Unsupported private key algorithm");
return SC_ERROR_NOT_SUPPORTED;
}

View File

@ -77,13 +77,13 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
return SC_ERROR_EXTRACTABLE_KEY;
if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP))) {
sc_error(ctx, "This key cannot be used for decryption\n");
sc_debug(ctx, "This key cannot be used for decryption\n");
return SC_ERROR_NOT_ALLOWED;
}
alg_info = _sc_card_find_rsa_alg(p15card->card, prkey->modulus_length);
if (alg_info == NULL) {
sc_error(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length);
sc_debug(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length);
return SC_ERROR_NOT_SUPPORTED;
}
senv.algorithm = SC_ALGORITHM_RSA;
@ -121,6 +121,10 @@ int sc_pkcs15_decipher(struct sc_pkcs15_card *p15card,
SC_TEST_RET(ctx, r, "sc_set_security_env() failed");
}
r = sc_decipher(p15card->card, in, inlen, out, outlen);
if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
r = sc_decipher(p15card->card, in, inlen, out, outlen);
}
sc_unlock(p15card->card);
SC_TEST_RET(ctx, r, "sc_decipher() failed");
@ -157,7 +161,7 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
in, inlen, out, outlen);
}
if (modlen > tmplen) {
sc_error(ctx, "Buffer too small, needs recompile!\n");
sc_debug(ctx, "Buffer too small, needs recompile!\n");
return SC_ERROR_NOT_ALLOWED;
}
r = sc_pkcs1_encode(ctx, flags, in, inlen, buf, &tmplen, modlen);
@ -180,13 +184,13 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
if (!(prkey->usage & (SC_PKCS15_PRKEY_USAGE_SIGN|SC_PKCS15_PRKEY_USAGE_SIGNRECOVER|
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION))) {
sc_error(ctx, "This key cannot be used for signing\n");
sc_debug(ctx, "This key cannot be used for signing\n");
return SC_ERROR_NOT_ALLOWED;
}
alg_info = _sc_card_find_rsa_alg(p15card->card, prkey->modulus_length);
if (alg_info == NULL) {
sc_error(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length);
sc_debug(ctx, "Card does not support RSA with key length %d\n", prkey->modulus_length);
return SC_ERROR_NOT_SUPPORTED;
}
senv.algorithm = SC_ALGORITHM_RSA;
@ -268,6 +272,10 @@ int sc_pkcs15_compute_signature(struct sc_pkcs15_card *p15card,
}
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
if (r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
if (sc_pkcs15_pincache_revalidate(p15card, obj) == SC_SUCCESS)
r = sc_compute_signature(p15card->card, tmp, inlen, out, outlen);
}
sc_mem_clear(buf, sizeof(buf));
sc_unlock(p15card->card);
SC_TEST_RET(ctx, r, "sc_compute_signature() failed");

View File

@ -105,9 +105,7 @@ static int starcert_detect_card(sc_pkcs15_card_t *p15card)
return SC_ERROR_WRONG_CARD;
/* read EF_Info file */
sc_format_path("3F00FE13", &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r != SC_SUCCESS)
return SC_ERROR_WRONG_CARD;
r = sc_read_binary(card, 0, buf, 64, 0);

View File

@ -56,6 +56,8 @@ extern int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t
extern int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
extern int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
static struct {
const char * name;
int (*handler)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
@ -74,6 +76,7 @@ static struct {
{ "atrust-acos",sc_pkcs15emu_atrust_acos_init_ex},
{ "tccardos", sc_pkcs15emu_tccardos_init_ex },
{ "entersafe", sc_pkcs15emu_entersafe_init_ex },
{ "pteid", sc_pkcs15emu_pteid_init_ex },
{ NULL, NULL }
};
@ -90,6 +93,8 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
{
switch (card->type) {
case SC_CARD_TYPE_MCRD_ESTEID:
case SC_CARD_TYPE_IAS_PTEID:
case SC_CARD_TYPE_GEMSAFEV1_PTEID:
return 1;
default:
return 0;
@ -178,22 +183,13 @@ out: if (r == SC_SUCCESS) {
p15card->magic = SC_PKCS15_CARD_MAGIC;
p15card->flags |= SC_PKCS15_CARD_FLAG_EMULATED;
} else if (r != SC_ERROR_WRONG_CARD) {
sc_error(ctx, "Failed to load card emulator: %s\n",
sc_debug(ctx, "Failed to load card emulator: %s\n",
sc_strerror(r));
}
return r;
}
static int emu_detect_card(sc_card_t *card, const scconf_block *blk, int *force)
{
int ret = 0;
/* TBD */
return ret;
}
static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
{
sc_card_t *card = p15card->card;
@ -207,10 +203,6 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
driver = conf->name->data;
r = emu_detect_card(card, conf, &force);
if (r < 0)
return SC_ERROR_INTERNAL;
init_func = NULL;
init_func_ex = NULL;
@ -400,7 +392,7 @@ int sc_pkcs15emu_object_add(sc_pkcs15_card_t *p15card, unsigned int type,
data_len = sizeof(struct sc_pkcs15_data_info);
break;
default:
sc_error(p15card->card->ctx,
sc_debug(p15card->card->ctx,
"Unknown PKCS15 object type %d\n", type);
free(obj);
return SC_ERROR_INVALID_ARGUMENTS;

View File

@ -455,14 +455,10 @@ int sc_pkcs15emu_tcos_init_ex(
serial[19] = '\0';
p15card->serial_number = strdup(serial);
sc_ctx_suppress_errors_on(ctx);
if(!detect_netkey(p15card)) return SC_SUCCESS;
if(!detect_signtrust(p15card)) return SC_SUCCESS;
if(!detect_datev(p15card)) return SC_SUCCESS;
if(!detect_unicard(p15card)) return SC_SUCCESS;
sc_ctx_suppress_errors_off(ctx);
return SC_ERROR_INTERNAL;
}

View File

@ -78,7 +78,7 @@ sc_pkcs15_derive_key(sc_context_t *ctx,
/* XXX: We might also encounter PBES2 here */
if (der_alg->algorithm != SC_ALGORITHM_PBKDF2) {
sc_error(ctx, "Unsupported key derivation algorithm.\n");
sc_debug(ctx, "Unsupported key derivation algorithm.\n");
return SC_ERROR_NOT_SUPPORTED;
}
@ -92,27 +92,27 @@ sc_pkcs15_derive_key(sc_context_t *ctx,
iv = (u8 *) enc_alg->params;
break;
default:
sc_error(ctx, "Unsupported key encryption algorithm.\n");
sc_debug(ctx, "Unsupported key encryption algorithm.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (!iv) {
sc_error(ctx, "Unsupported key encryption parameters.\n");
sc_debug(ctx, "Unsupported key encryption parameters.\n");
return SC_ERROR_NOT_SUPPORTED;
}
key_len = EVP_CIPHER_key_length(cipher);
info = (struct sc_pbkdf2_params *) der_alg->params;
if (!info) {
sc_error(ctx, "Key parameters missing.\n");
sc_debug(ctx, "Key parameters missing.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (info->key_length && info->key_length != key_len) {
sc_error(ctx, "Incompatible key length.\n");
sc_debug(ctx, "Incompatible key length.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (key_len > sizeof(key)) {
sc_error(ctx, "Huge key length (%u).\n", key_len);
sc_debug(ctx, "Huge key length (%u).\n", key_len);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -120,7 +120,7 @@ sc_pkcs15_derive_key(sc_context_t *ctx,
info->salt, info->salt_len,
info->iterations, key_len, key);
if (r == 0) {
sc_error(ctx, "Key derivation failed.\n");
sc_debug(ctx, "Key derivation failed.\n");
return SC_ERROR_INTERNAL; /* for lack of something better */
}
@ -223,7 +223,7 @@ sc_pkcs15_unwrap_data(sc_context_t *ctx,
memset(&envdata, 0, sizeof(envdata));
r = sc_pkcs15_decode_enveloped_data(ctx, &envdata, in, in_len);
if (r < 0) {
sc_error(ctx, "Failed to decode EnvelopedData.\n");
sc_debug(ctx, "Failed to decode EnvelopedData.\n");
return r;
}

View File

@ -95,7 +95,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL);
if (r) {
sc_error(ctx, "ASN.1 parsing of EF(TokenInfo) failed: %s\n",
sc_debug(ctx, "ASN.1 parsing of EF(TokenInfo) failed: %s\n",
sc_strerror(r));
return r;
}
@ -196,7 +196,7 @@ int sc_pkcs15_encode_tokeninfo(sc_context_t *ctx,
r = sc_asn1_encode(ctx, asn1_tokeninfo, buf, buflen);
if (r) {
sc_error(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r));
sc_debug(ctx, "sc_asn1_encode() failed: %s\n", sc_strerror(r));
return r;
}
return 0;
@ -223,7 +223,7 @@ static int parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t bufl
r = sc_asn1_decode(p15card->card->ctx, asn1_ddo, buf, buflen, NULL, NULL);
if (r) {
sc_error(p15card->card->ctx, "DDO parsing failed: %s\n",
sc_debug(p15card->card->ctx, "DDO parsing failed: %s\n",
sc_strerror(r));
return r;
}
@ -276,7 +276,7 @@ static int encode_ddo(struct sc_pkcs15_card *p15card, u8 **buf, size_t *buflen)
r = sc_asn1_encode(ctx, asn1_dir, buf, buflen);
if (r) {
sc_error(ctx, "sc_asn1_encode() failed: %s\n",
sc_debug(ctx, "sc_asn1_encode() failed: %s\n",
sc_strerror(r));
return r;
}
@ -362,7 +362,7 @@ int sc_pkcs15_encode_odf(sc_context_t *ctx,
df = df->next;
};
if (df_count == 0) {
sc_error(ctx, "No DF's found.\n");
sc_debug(ctx, "No DF's found.\n");
return SC_ERROR_OBJECT_NOT_FOUND;
}
asn1_odf = (struct sc_asn1_entry *) malloc(sizeof(struct sc_asn1_entry) * (df_count + 1));
@ -384,7 +384,7 @@ int sc_pkcs15_encode_odf(sc_context_t *ctx,
break;
}
if (type == -1) {
sc_error(ctx, "Unsupported DF type.\n");
sc_debug(ctx, "Unsupported DF type.\n");
continue;
}
asn1_odf[c] = c_asn1_odf[type];
@ -416,6 +416,8 @@ struct sc_pkcs15_card * sc_pkcs15_card_new(void)
void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
{
size_t i;
if (p15card == NULL)
return;
assert(p15card->magic == SC_PKCS15_CARD_MAGIC);
@ -446,11 +448,14 @@ void sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
if (p15card->preferred_language != NULL)
free(p15card->preferred_language);
if (p15card->seInfo != NULL) {
size_t i;
for (i = 0; i < p15card->num_seInfo; i++)
free(p15card->seInfo[i]);
free(p15card->seInfo);
}
for (i=0; i<SC_PKCS15_MAX_PINS && p15card->pin_cache[i] != NULL; i++) {
sc_mem_clear(p15card->pin_cache[i]->pin, p15card->pin_cache[i]->len);
free(p15card->pin_cache[i]);
}
free(p15card);
}
@ -529,7 +534,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
if (card->app_count < 0) {
err = sc_enum_apps(card);
if (err < 0 && err != SC_ERROR_FILE_NOT_FOUND) {
sc_error(ctx, "unable to enumerate apps: %s\n", sc_strerror(err));
sc_debug(ctx, "unable to enumerate apps: %s\n", sc_strerror(err));
goto end;
}
}
@ -552,7 +557,6 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
}
/* Check if pkcs15 directory exists */
sc_ctx_suppress_errors_on(card->ctx);
err = sc_select_file(card, &p15card->file_app->path, NULL);
#if 1
/* If the above test failed on cards without EF(DIR),
@ -564,18 +568,14 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
err = SC_NO_ERROR;
}
#endif
sc_ctx_suppress_errors_off(card->ctx);
if (err < 0)
goto end;
if (p15card->file_odf == NULL) {
/* check if an ODF is present; suppress errors as we
* don't know yet whether we have a pkcs15 card */
/* check if an ODF is present; we don't know yet whether we have a pkcs15 card */
tmppath = p15card->file_app->path;
sc_append_path_id(&tmppath, (const u8 *) "\x50\x31", 2);
sc_ctx_suppress_errors_on(card->ctx);
err = sc_select_file(card, &tmppath, &p15card->file_odf);
sc_ctx_suppress_errors_off(card->ctx);
} else {
tmppath = p15card->file_odf->path;
@ -595,7 +595,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
}
if ((len = p15card->file_odf->size) == 0) {
sc_error(card->ctx, "EF(ODF) is empty\n");
sc_debug(card->ctx, "EF(ODF) is empty\n");
goto end;
}
buf = malloc(len);
@ -611,7 +611,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
len = err;
if (parse_odf(buf, len, p15card)) {
err = SC_ERROR_PKCS15_APP_NOT_FOUND;
sc_error(card->ctx, "Unable to parse ODF\n");
sc_debug(card->ctx, "Unable to parse ODF\n");
goto end;
}
free(buf);
@ -647,7 +647,7 @@ static int sc_pkcs15_bind_internal(sc_pkcs15_card_t *p15card)
goto end;
if ((len = p15card->file_tokeninfo->size) == 0) {
sc_error(card->ctx, "EF(TokenInfo) is empty\n");
sc_debug(card->ctx, "EF(TokenInfo) is empty\n");
goto end;
}
buf = malloc(len);
@ -692,8 +692,8 @@ int sc_pkcs15_bind(sc_card_t *card,
{
struct sc_pkcs15_card *p15card = NULL;
sc_context_t *ctx;
scconf_block *conf_block = NULL, **blocks;
int i, r, emu_first, enable_emu;
scconf_block *conf_block = NULL;
int r, emu_first, enable_emu;
assert(sc_card_valid(card) && p15card_out != NULL);
ctx = card->ctx;
@ -701,23 +701,25 @@ int sc_pkcs15_bind(sc_card_t *card,
p15card = sc_pkcs15_card_new();
if (p15card == NULL)
return SC_ERROR_OUT_OF_MEMORY;
p15card->card = card;
for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
"framework", "pkcs15");
if (blocks && blocks[0] != NULL)
conf_block = blocks[0];
free(blocks);
}
p15card->card = card;
p15card->opts.use_file_cache = 0;
p15card->opts.use_pin_cache = 1;
p15card->opts.pin_cache_counter = 10;
conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
if (conf_block) {
p15card->opts.use_cache = scconf_get_bool(conf_block, "use_caching", 0);
p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache);
p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache);
p15card->opts.pin_cache_counter = scconf_get_bool(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter);
}
sc_debug(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d",
p15card->opts.use_file_cache, p15card->opts.use_pin_cache, p15card->opts.pin_cache_counter);
r = sc_lock(card);
if (r) {
sc_error(ctx, "sc_lock() failed: %s\n", sc_strerror(r));
sc_debug(ctx, "sc_lock() failed: %s\n", sc_strerror(r));
sc_pkcs15_card_free(p15card);
SC_FUNC_RETURN(ctx, 1, r);
}
@ -1369,7 +1371,7 @@ int sc_pkcs15_encode_df(sc_context_t *ctx,
break;
}
if (func == NULL) {
sc_error(ctx, "unknown DF type: %d\n", df->type);
sc_debug(ctx, "unknown DF type: %d\n", df->type);
*buf_out = NULL;
*bufsize_out = 0;
return 0;
@ -1426,7 +1428,7 @@ int sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card,
break;
}
if (func == NULL) {
sc_error(ctx, "unknown DF type: %d\n", df->type);
sc_debug(ctx, "unknown DF type: %d\n", df->type);
return SC_ERROR_INVALID_ARGUMENTS;
}
if (df->file != NULL)
@ -1496,7 +1498,7 @@ int sc_pkcs15_add_unusedspace(struct sc_pkcs15_card *p15card,
if (r != SC_SUCCESS)
pbuf[0] = '\0';
sc_error(p15card->card->ctx, "No offset and length present in path %s\n", pbuf);
sc_debug(p15card->card->ctx, "No offset and length present in path %s\n", pbuf);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -1680,7 +1682,7 @@ int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card,
}
r = -1; /* file state: not in cache */
if (p15card->opts.use_cache) {
if (p15card->opts.use_file_cache) {
r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len);
}
if (r) {
@ -1719,10 +1721,8 @@ int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card,
for (i=1; ; i++) {
l = len - (head - data);
if (l > 256) { l = 256; }
p15card->card->ctx->suppress_errors++;
r = sc_read_record(p15card->card, i, head, l,
SC_RECORD_BY_REC_NR);
p15card->card->ctx->suppress_errors--;
if (r == SC_ERROR_RECORD_NOT_FOUND)
break;
if (r < 0) {

View File

@ -71,6 +71,7 @@ struct sc_pkcs15_pin_info {
u8 pad_char;
struct sc_path path;
int tries_left;
int max_tries;
unsigned int magic;
};
@ -379,6 +380,13 @@ typedef struct {
size_t aid_len;
} sc_pkcs15_sec_env_info_t;
typedef struct {
sc_pkcs15_id_t id;
u8 pin[SC_MAX_PIN_SIZE];
size_t len;
int counter;
} sc_pkcs15_pincache_entry_t;
typedef struct {
unsigned int version;
unsigned int flags;
@ -411,11 +419,14 @@ typedef struct sc_pkcs15_card {
int unusedspace_read;
struct sc_pkcs15_card_opts {
int use_cache;
int use_file_cache;
int use_pin_cache;
int pin_cache_counter;
} opts;
sc_pkcs15_sec_env_info_t **seInfo;
size_t num_seInfo;
sc_pkcs15_pincache_entry_t *pin_cache[SC_PKCS15_MAX_PINS];
unsigned int magic;
@ -565,6 +576,8 @@ int sc_pkcs15_find_pin_by_reference(struct sc_pkcs15_card *card,
struct sc_pkcs15_object **out);
int sc_pkcs15_find_so_pin(struct sc_pkcs15_card *card,
struct sc_pkcs15_object **out);
int sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_object_t *obj);
void sc_pkcs15_pincache_clear(struct sc_pkcs15_card *p15card);
int sc_pkcs15_encode_dir(struct sc_context *ctx,
struct sc_pkcs15_card *card,

View File

@ -96,11 +96,11 @@ static int ctapi_reset(sc_reader_t *reader, sc_slot_info_t *slot)
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
if (rv || (lr < 2)) {
sc_error(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv);
sc_debug(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv);
return SC_ERROR_TRANSMIT_FAILED;
}
if (rbuf[lr-2] != 0x90) {
sc_error(reader->ctx, "SW1/SW2: 0x%x/0x%x\n", rbuf[lr-2], rbuf[lr-1]);
sc_debug(reader->ctx, "SW1/SW2: 0x%x/0x%x\n", rbuf[lr-2], rbuf[lr-1]);
return SC_ERROR_TRANSMIT_FAILED;
}
return 0;
@ -141,7 +141,7 @@ static void detect_functional_units(sc_reader_t *reader)
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
if (rv || (lr < 4) || (rbuf[lr-2] != 0x90)) {
sc_error(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv);
sc_debug(reader->ctx, "Error getting status of terminal: %d, using defaults\n", rv);
set_default_fu(reader);
return;
}
@ -149,13 +149,13 @@ static void detect_functional_units(sc_reader_t *reader)
/* Number of slots might also detected by using CTBCS_P2_STATUS_ICC.
If you think that's important please do it... ;) */
set_default_fu(reader);
sc_error(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x\n", rbuf[0]);
sc_debug(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x\n", rbuf[0]);
return;
}
NumUnits = rbuf[1];
if (NumUnits + 4 > lr) {
set_default_fu(reader);
sc_error(reader->ctx, "Invalid data returnd: %d functional units, size %d\n", NumUnits, rv);
sc_debug(reader->ctx, "Invalid data returnd: %d functional units, size %d\n", NumUnits, rv);
set_default_fu(reader);
return;
}
@ -257,13 +257,13 @@ static int refresh_slot_attributes(sc_reader_t *reader,
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
if (rv || (lr < 3) || (rbuf[lr-2] != 0x90)) {
sc_error(reader->ctx, "Error getting status of terminal: %d/%d/0x%x\n", rv, lr, rbuf[lr-2]);
sc_debug(reader->ctx, "Error getting status of terminal: %d/%d/0x%x\n", rv, lr, rbuf[lr-2]);
return SC_ERROR_TRANSMIT_FAILED;
}
if (lr < 4) {
/* Looks like older readers do not return data tag and length field, so assume one slot only */
if (slot->id > 0) {
sc_error(reader->ctx, "Status for slot id %d not returned, have only 1\n", slot->id);
sc_debug(reader->ctx, "Status for slot id %d not returned, have only 1\n", slot->id);
return SC_ERROR_SLOT_NOT_FOUND;
}
if (rbuf[0] & CTBCS_DATA_STATUS_CARD)
@ -271,11 +271,11 @@ static int refresh_slot_attributes(sc_reader_t *reader,
} else {
if (rbuf[0] != CTBCS_P2_STATUS_ICC) {
/* Should we be more tolerant here? I do not think so... */
sc_error(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x\n", rbuf[0]);
sc_debug(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x\n", rbuf[0]);
return SC_ERROR_TRANSMIT_FAILED;
}
if (rbuf[1] <= slot->id) {
sc_error(reader->ctx, "Status for slot id %d not returned, only %d\n", slot->id, rbuf[1]);
sc_debug(reader->ctx, "Status for slot id %d not returned, only %d\n", slot->id, rbuf[1]);
return SC_ERROR_SLOT_NOT_FOUND;
}
if (rbuf[2+slot->id] & CTBCS_DATA_STATUS_CARD)
@ -306,7 +306,7 @@ static int ctapi_internal_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, (unsigned short)sendsize, (u8 *) sendbuf, &lr, recvbuf);
if (rv != 0) {
sc_error(reader->ctx, "Error transmitting APDU: %d\n", rv);
sc_debug(reader->ctx, "Error transmitting APDU: %d\n", rv);
return SC_ERROR_TRANSMIT_FAILED;
}
*recvsize = lr;
@ -337,7 +337,7 @@ static int ctapi_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
rbuf, &rsize, apdu->control);
if (r < 0) {
/* unable to transmit ... most likely a reader problem */
sc_error(reader->ctx, "unable to transmit");
sc_debug(reader->ctx, "unable to transmit");
goto out;
}
if (reader->ctx->debug >= 6)
@ -386,7 +386,7 @@ static int ctapi_connect(sc_reader_t *reader, sc_slot_info_t *slot)
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
if (rv || rbuf[lr-2] != 0x90) {
sc_error(reader->ctx, "Error activating card: %d\n", rv);
sc_debug(reader->ctx, "Error activating card: %d\n", rv);
return SC_ERROR_TRANSMIT_FAILED;
}
if (lr < 2)
@ -413,7 +413,7 @@ static int ctapi_connect(sc_reader_t *reader, sc_slot_info_t *slot)
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 9, cmd, &lr, rbuf);
if (rv) {
sc_error(reader->ctx, "Error negotiating PPS: %d\n", rv);
sc_debug(reader->ctx, "Error negotiating PPS: %d\n", rv);
return SC_ERROR_TRANSMIT_FAILED;
}
}
@ -483,14 +483,14 @@ static int ctapi_load_module(sc_context_t *ctx,
list = scconf_find_list(conf, "ports");
if (list == NULL) {
sc_error(ctx, "No ports configured.\n");
sc_debug(ctx, "No ports configured.\n");
return -1;
}
val = conf->name->data;
dlh = lt_dlopen(val);
if (!dlh) {
sc_error(ctx, "Unable to open shared library '%s': %s\n", val, lt_dlerror());
sc_debug(ctx, "Unable to open shared library '%s': %s\n", val, lt_dlerror());
return -1;
}
@ -513,12 +513,12 @@ static int ctapi_load_module(sc_context_t *ctx,
struct ctapi_private_data *priv;
if (sscanf(list->data, "%d", &port) != 1) {
sc_error(ctx, "Port '%s' is not a number.\n", list->data);
sc_debug(ctx, "Port '%s' is not a number.\n", list->data);
continue;
}
rv = funcs.CT_init((unsigned short)mod->ctn_count, (unsigned short)port);
if (rv) {
sc_error(ctx, "CT_init() failed with %d\n", rv);
sc_debug(ctx, "CT_init() failed with %d\n", rv);
continue;
}
reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t));
@ -550,7 +550,7 @@ static int ctapi_load_module(sc_context_t *ctx,
}
return 0;
symerr:
sc_error(ctx, "Unable to resolve CT-API symbols.\n");
sc_debug(ctx, "Unable to resolve CT-API symbols.\n");
lt_dlclose(dlh);
return -1;
}

View File

@ -221,21 +221,21 @@ openct_reader_connect(sc_reader_t *reader,
ct_reader_disconnect(data->h);
if (!(data->h = ct_reader_connect(data->num))) {
sc_error(reader->ctx, "ct_reader_connect socket failed\n");
sc_debug(reader->ctx, "ct_reader_connect socket failed\n");
return SC_ERROR_CARD_NOT_PRESENT;
}
rc = ct_card_request(data->h, slot->id, 0, NULL,
slot->atr, sizeof(slot->atr));
if (rc < 0) {
sc_error(reader->ctx,
sc_debug(reader->ctx,
"openct_reader_connect read failed: %s\n",
ct_strerror(rc));
return SC_ERROR_CARD_NOT_PRESENT;
}
if (rc == 0) {
sc_error(reader->ctx, "openct_reader_connect recved no data\n");
sc_debug(reader->ctx, "openct_reader_connect recved no data\n");
return SC_ERROR_READER;
}
@ -321,7 +321,7 @@ static int openct_reader_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
rbuf, &rsize, apdu->control);
if (r < 0) {
/* unable to transmit ... most likely a reader problem */
sc_error(reader->ctx, "unable to transmit");
sc_debug(reader->ctx, "unable to transmit");
goto out;
}
if (reader->ctx->debug >= 6)

View File

@ -20,7 +20,6 @@
#include "internal.h"
#ifdef ENABLE_PCSC
#include "ctbcs.h"
#include <assert.h>
#include <stdlib.h>
#include <string.h>
@ -39,7 +38,7 @@
#undef SCARD_PROTOCOL_ANY
#define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
/* Error printing */
#define PCSC_ERROR(ctx, desc, rv) sc_error(ctx, desc ": 0x%08lx\n", rv);
#define PCSC_ERROR(ctx, desc, rv) sc_debug(ctx, desc ": 0x%08lx\n", rv);
/* Utility for handling big endian IOCTL codes. */
#define dw2i_be(a, x) ((((((a[x] << 8) + a[x+1]) << 8) + a[x+2]) << 8) + a[x+3])
@ -47,9 +46,6 @@
#define GET_PRIV_DATA(r) ((struct pcsc_private_data *) (r)->drv_data)
#define GET_SLOT_DATA(r) ((struct pcsc_slot_data *) (r)->drv_data)
static int part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
struct sc_pin_cmd_data *data);
struct pcsc_global_private_data {
SCARDCONTEXT pcsc_ctx;
int enable_pinpad;
@ -74,7 +70,6 @@ struct pcsc_global_private_data {
};
struct pcsc_private_data {
char *reader_name;
struct pcsc_global_private_data *gpriv;
};
@ -93,9 +88,11 @@ struct pcsc_slot_data {
static int pcsc_detect_card_presence(sc_reader_t *reader, sc_slot_info_t *slot);
static int pcsc_ret_to_error(long rv)
static int pcsc_ret_to_error(LONG rv)
{
switch (rv) {
case SCARD_S_SUCCESS:
return SC_SUCCESS;
case SCARD_W_REMOVED_CARD:
return SC_ERROR_CARD_REMOVED;
case SCARD_E_NOT_TRANSACTED:
@ -113,6 +110,11 @@ static int pcsc_ret_to_error(long rv)
case SCARD_E_NO_SERVICE:
/* If the service is (auto)started, there could be readers later */
return SC_ERROR_NO_READERS_FOUND;
case SCARD_E_NO_SMARTCARD:
return SC_ERROR_CARD_NOT_PRESENT;
case SCARD_E_PROTO_MISMATCH: /* Should not happen */
return SC_ERROR_READER;
default:
return SC_ERROR_UNKNOWN;
}
@ -236,7 +238,7 @@ static int pcsc_transmit(sc_reader_t *reader, sc_slot_info_t *slot,
rbuf, &rsize, apdu->control);
if (r < 0) {
/* unable to transmit ... most likely a reader problem */
sc_error(reader->ctx, "unable to transmit");
sc_debug(reader->ctx, "unable to transmit");
goto out;
}
if (reader->ctx->debug >= 6)
@ -265,7 +267,7 @@ static int refresh_slot_attributes(sc_reader_t *reader, sc_slot_info_t *slot)
SC_FUNC_CALLED(reader->ctx, 3);
if (pslot->reader_state.szReader == NULL) {
pslot->reader_state.szReader = priv->reader_name;
pslot->reader_state.szReader = reader->name;
pslot->reader_state.dwCurrentState = SCARD_STATE_UNAWARE;
pslot->reader_state.dwEventState = SCARD_STATE_UNAWARE;
} else {
@ -380,7 +382,7 @@ static int pcsc_wait_for_event(sc_reader_t **readers,
for (i = 0; i < nslots; i++) {
struct pcsc_private_data *priv2 = GET_PRIV_DATA(readers[i]);
rgReaderStates[i].szReader = priv2->reader_name;
rgReaderStates[i].szReader = readers[i]->name;
rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
rgReaderStates[i].dwEventState = SCARD_STATE_UNAWARE;
@ -490,11 +492,11 @@ static int pcsc_reconnect(sc_reader_t * reader, sc_slot_info_t * slot, int reset
if (rv != SCARD_S_SUCCESS) {
PCSC_ERROR(reader->ctx, "SCardReconnect failed", rv);
return rv;
return pcsc_ret_to_error(rv);
}
slot->active_protocol = pcsc_proto_to_opensc(active_proto);
return rv;
return pcsc_ret_to_error(rv);
}
static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
@ -505,10 +507,6 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
struct pcsc_private_data *priv = GET_PRIV_DATA(reader);
struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
int r;
u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE];
size_t rcount;
DWORD i, feature_len, display_ioctl = 0;
PCSC_TLV_STRUCTURE *pcsc_tlv;
r = refresh_slot_attributes(reader, slot);
if (r)
@ -517,7 +515,7 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
return SC_ERROR_CARD_NOT_PRESENT;
/* Always connect with whatever protocol possible */
rv = priv->gpriv->SCardConnect(priv->gpriv->pcsc_ctx, priv->reader_name,
rv = priv->gpriv->SCardConnect(priv->gpriv->pcsc_ctx, reader->name,
priv->gpriv->connect_exclusive ? SCARD_SHARE_EXCLUSIVE : SCARD_SHARE_SHARED,
SCARD_PROTOCOL_ANY, &card_handle, &active_proto);
if (rv != SCARD_S_SUCCESS) {
@ -537,94 +535,14 @@ static int pcsc_connect(sc_reader_t *reader, sc_slot_info_t *slot)
if (slot->active_protocol != protocol) {
sc_debug(reader->ctx, "Protocol difference, forcing protocol (%d)", protocol);
/* Reconnect with a reset. pcsc_reconnect figures out the right forced protocol */
rv = pcsc_reconnect(reader, slot, 1);
if (rv != SCARD_S_SUCCESS) {
PCSC_ERROR(reader->ctx, "SCardReconnect (to force protocol) failed", rv);
return pcsc_ret_to_error(rv);
r = pcsc_reconnect(reader, slot, 1);
if (r != SC_SUCCESS) {
sc_debug(reader->ctx, "pcsc_reconnect (to force protocol) failed", r);
return r;
}
sc_debug(reader->ctx, "Proto after reconnect = %d", slot->active_protocol);
}
}
/* check for pinpad support */
if (priv->gpriv->SCardControl != NULL) {
sc_debug(reader->ctx, "Requesting reader features ... ");
rv = priv->gpriv->SCardControl(pslot->pcsc_card, CM_IOCTL_GET_FEATURE_REQUEST, NULL,
0, feature_buf, sizeof(feature_buf), &feature_len);
if (rv != SCARD_S_SUCCESS) {
sc_debug(reader->ctx, "SCardControl failed %08x", rv);
}
else {
if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0) {
sc_debug(reader->ctx, "Inconsistent TLV from reader!");
}
else {
char *log_disabled = "but it's disabled in configuration file";
/* get the number of elements instead of the complete size */
feature_len /= sizeof(PCSC_TLV_STRUCTURE);
pcsc_tlv = (PCSC_TLV_STRUCTURE *)feature_buf;
for (i = 0; i < feature_len; i++) {
if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT) {
pslot->verify_ioctl = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_START) {
pslot->verify_ioctl_start = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_FINISH) {
pslot->verify_ioctl_finish = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT) {
pslot->modify_ioctl = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_START) {
pslot->modify_ioctl_start = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) {
pslot->modify_ioctl_finish = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_IFD_PIN_PROPERTIES) {
display_ioctl = ntohl(pcsc_tlv[i].value);
} else {
sc_debug(reader->ctx, "Reader feature %02x is not supported", pcsc_tlv[i].tag);
}
}
/* Set slot capabilities based on detected IOCTLs */
if (pslot->verify_ioctl || (pslot->verify_ioctl_start && pslot->verify_ioctl_finish)) {
char *log_text = "Reader supports pinpad PIN verification";
if (priv->gpriv->enable_pinpad) {
sc_debug(reader->ctx, log_text);
slot->capabilities |= SC_SLOT_CAP_PIN_PAD;
} else {
sc_debug(reader->ctx, "%s %s", log_text, log_disabled);
}
}
if (pslot->modify_ioctl || (pslot->modify_ioctl_start && pslot->modify_ioctl_finish)) {
char *log_text = "Reader supports pinpad PIN modification";
if (priv->gpriv->enable_pinpad) {
sc_debug(reader->ctx, log_text);
slot->capabilities |= SC_SLOT_CAP_PIN_PAD;
} else {
sc_debug(reader->ctx, "%s %s", log_text, log_disabled);
}
}
if (display_ioctl) {
rcount = sizeof(rbuf);
r = pcsc_internal_transmit(reader, slot, NULL, 0, rbuf, &rcount, display_ioctl);
if (r == SC_SUCCESS) {
if (rcount != sizeof(PIN_PROPERTIES_STRUCTURE)) {
PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)rbuf;
if (caps->wLcdLayout > 0) {
sc_debug(reader->ctx, "Reader has a display: %04X", caps->wLcdLayout);
slot->capabilities |= SC_SLOT_CAP_DISPLAY;
} else
sc_debug(reader->ctx, "Reader does not have a display.");
} else {
sc_debug(reader->ctx, "Returned PIN properties structure has bad length (%d)", rcount);
}
}
}
}
}
}
return SC_SUCCESS;
}
@ -642,7 +560,8 @@ static int pcsc_disconnect(sc_reader_t * reader, sc_slot_info_t * slot)
static int pcsc_lock(sc_reader_t *reader, sc_slot_info_t *slot)
{
long rv;
LONG rv;
int r;
struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
struct pcsc_private_data *priv = GET_PRIV_DATA(reader);
@ -654,19 +573,19 @@ static int pcsc_lock(sc_reader_t *reader, sc_slot_info_t *slot)
switch (rv) {
case SCARD_E_INVALID_HANDLE:
case SCARD_E_READER_UNAVAILABLE:
rv = pcsc_connect(reader, slot);
if (rv != SCARD_S_SUCCESS) {
PCSC_ERROR(reader->ctx, "SCardConnect failed", rv);
return pcsc_ret_to_error(rv);
r = pcsc_connect(reader, slot);
if (r != SC_SUCCESS) {
sc_debug(reader->ctx, "pcsc_connect failed", r);
return r;
}
/* return failure so that upper layers will be notified and try to lock again */
return SC_ERROR_READER_REATTACHED;
case SCARD_W_RESET_CARD:
/* try to reconnect if the card was reset by some other application */
rv = pcsc_reconnect(reader, slot, 0);
if (rv != SCARD_S_SUCCESS) {
PCSC_ERROR(reader->ctx, "SCardReconnect failed", rv);
return pcsc_ret_to_error(rv);
r = pcsc_reconnect(reader, slot, 0);
if (r != SC_SUCCESS) {
sc_debug(reader->ctx, "pcsc_reconnect failed", r);
return r;
}
/* return failure so that upper layers will be notified and try to lock again */
return SC_ERROR_CARD_RESET;
@ -681,7 +600,7 @@ static int pcsc_lock(sc_reader_t *reader, sc_slot_info_t *slot)
static int pcsc_unlock(sc_reader_t *reader, sc_slot_info_t *slot)
{
long rv;
LONG rv;
struct pcsc_slot_data *pslot = GET_SLOT_DATA(slot);
struct pcsc_private_data *priv = GET_PRIV_DATA(reader);
@ -703,7 +622,6 @@ static int pcsc_release(sc_reader_t *reader)
{
struct pcsc_private_data *priv = GET_PRIV_DATA(reader);
free(priv->reader_name);
free(priv);
if (reader->slot[0].drv_data != NULL) {
free(reader->slot[0].drv_data);
@ -719,13 +637,13 @@ static int pcsc_reset(sc_reader_t *reader, sc_slot_info_t *slot)
int old_locked = pslot->locked;
r = pcsc_reconnect(reader, slot, 1);
if(r != SCARD_S_SUCCESS)
return pcsc_ret_to_error(r);
if(r != SC_SUCCESS)
return r;
/* pcsc_reconnect unlocks card... try to lock it again if it was locked */
if(old_locked)
r = pcsc_lock(reader, slot);
return r;
}
@ -756,7 +674,7 @@ static int pcsc_init(sc_context_t *ctx, void **reader_data)
gpriv->connect_reset = 1;
gpriv->connect_exclusive = 0;
gpriv->transaction_reset = 0;
gpriv->enable_pinpad = 0;
gpriv->enable_pinpad = 1;
gpriv->provider_library = DEFAULT_PCSC_PROVIDER;
gpriv->pcsc_ctx = -1;
@ -773,6 +691,8 @@ static int pcsc_init(sc_context_t *ctx, void **reader_data)
gpriv->provider_library =
scconf_get_str(conf_block, "provider_library", gpriv->provider_library);
}
sc_debug(ctx, "PC/SC options: connect_reset=%d connect_exclusive=%d transaction_reset=%d enable_pinpad=%d",
gpriv->connect_reset, gpriv->connect_exclusive, gpriv->transaction_reset, gpriv->enable_pinpad);
gpriv->dlhandle = lt_dlopen(gpriv->provider_library);
if (gpriv->dlhandle == NULL) {
@ -862,9 +782,13 @@ static int pcsc_finish(sc_context_t *ctx, void *prv_data)
static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)
{
DWORD active_proto;
SCARDHANDLE card_handle;
u8 feature_buf[256], rbuf[SC_MAX_APDU_BUFFER_SIZE];
PCSC_TLV_STRUCTURE *pcsc_tlv;
struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data;
LONG rv;
DWORD reader_buf_size;
DWORD reader_buf_size, rcount, feature_len, display_ioctl;
char *reader_buf = NULL, *reader_name;
const char *mszGroups = NULL;
int ret = SC_ERROR_INTERNAL;
@ -972,10 +896,6 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)
goto err1;
}
priv->gpriv = gpriv;
if ((priv->reader_name = strdup(reader_name)) == NULL) {
ret = SC_ERROR_OUT_OF_MEMORY;
goto err1;
}
slot = &reader->slot[0];
memset(slot, 0, sizeof(*slot));
slot->drv_data = pslot;
@ -984,14 +904,103 @@ static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data)
ret = SC_SUCCESS; /* silent ignore */
goto err1;
}
refresh_slot_attributes(reader, slot);
/* check for pinpad support */
if (gpriv->SCardControl != NULL) {
sc_debug(ctx, "Requesting reader features ... ");
#ifdef __APPLE__ /* 10.5.7 does not support 0 as protocol identifier */
rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_DIRECT, SCARD_PROTOCOL_ANY, &card_handle, &active_proto);
#else
rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_DIRECT, 0, &card_handle, &active_proto);
if (rv == SCARD_E_SHARING_VIOLATION) /* Assume that there is a card in the reader in shared mode */
rv = gpriv->SCardConnect(gpriv->pcsc_ctx, reader->name, SCARD_SHARE_SHARED, SCARD_PROTOCOL_ANY, &card_handle, &active_proto);
#endif
if (rv == SCARD_S_SUCCESS) {
rv = gpriv->SCardControl(card_handle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, feature_buf, sizeof(feature_buf), &feature_len);
if (rv != SCARD_S_SUCCESS) {
sc_debug(ctx, "SCardControl failed %08x", rv);
}
else {
if ((feature_len % sizeof(PCSC_TLV_STRUCTURE)) != 0) {
sc_debug(ctx, "Inconsistent TLV from reader!");
}
else {
char *log_disabled = "but it's disabled in configuration file";
/* get the number of elements instead of the complete size */
feature_len /= sizeof(PCSC_TLV_STRUCTURE);
pcsc_tlv = (PCSC_TLV_STRUCTURE *)feature_buf;
for (i = 0; i < feature_len; i++) {
sc_debug(ctx, "Reader feature %02x detected", pcsc_tlv[i].tag);
if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_DIRECT) {
pslot->verify_ioctl = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_START) {
pslot->verify_ioctl_start = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_VERIFY_PIN_FINISH) {
pslot->verify_ioctl_finish = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_DIRECT) {
pslot->modify_ioctl = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_START) {
pslot->modify_ioctl_start = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_MODIFY_PIN_FINISH) {
pslot->modify_ioctl_finish = ntohl(pcsc_tlv[i].value);
} else if (pcsc_tlv[i].tag == FEATURE_IFD_PIN_PROPERTIES) {
display_ioctl = ntohl(pcsc_tlv[i].value);
} else {
sc_debug(ctx, "Reader feature %02x is not supported", pcsc_tlv[i].tag);
}
}
/* Set slot capabilities based on detected IOCTLs */
if (pslot->verify_ioctl || (pslot->verify_ioctl_start && pslot->verify_ioctl_finish)) {
char *log_text = "Reader supports pinpad PIN verification";
if (priv->gpriv->enable_pinpad) {
sc_debug(ctx, log_text);
slot->capabilities |= SC_SLOT_CAP_PIN_PAD;
} else {
sc_debug(ctx, "%s %s", log_text, log_disabled);
}
}
if (pslot->modify_ioctl || (pslot->modify_ioctl_start && pslot->modify_ioctl_finish)) {
char *log_text = "Reader supports pinpad PIN modification";
if (priv->gpriv->enable_pinpad) {
sc_debug(ctx, log_text);
slot->capabilities |= SC_SLOT_CAP_PIN_PAD;
} else {
sc_debug(ctx, "%s %s", log_text, log_disabled);
}
}
if (display_ioctl) {
rcount = sizeof(rbuf);
rv = gpriv->SCardControl(card_handle, display_ioctl, NULL, 0, rbuf, sizeof(rbuf), &rcount);
if (rv == SCARD_S_SUCCESS) {
if (rcount == sizeof(PIN_PROPERTIES_STRUCTURE)) {
PIN_PROPERTIES_STRUCTURE *caps = (PIN_PROPERTIES_STRUCTURE *)rbuf;
if (caps->wLcdLayout > 0) {
sc_debug(ctx, "Reader has a display: %04X", caps->wLcdLayout);
slot->capabilities |= SC_SLOT_CAP_DISPLAY;
} else
sc_debug(ctx, "Reader does not have a display.");
} else {
sc_debug(ctx, "Returned PIN properties structure has bad length (%d/%d)", rcount, sizeof(PIN_PROPERTIES_STRUCTURE));
}
}
}
}
}
gpriv->SCardDisconnect(card_handle, SCARD_LEAVE_CARD);
}
else {
sc_debug(ctx, "SCardConnect failed %08x", rv);
}
}
refresh_slot_attributes(reader, slot);
continue;
err1:
if (priv != NULL) {
if (priv->reader_name)
free(priv->reader_name);
free(priv);
}
if (reader != NULL) {
@ -1015,36 +1024,6 @@ out:
SC_FUNC_RETURN(ctx, 3, ret);
}
static int
pcsc_pin_cmd(sc_reader_t *reader, sc_slot_info_t * slot, struct sc_pin_cmd_data *data)
{
if (slot->capabilities & SC_SLOT_CAP_PIN_PAD) {
return part10_pin_cmd(reader, slot, data);
} else {
/* XXX: probably dead code */
return ctbcs_pin_cmd(reader, slot, data);
}
}
struct sc_reader_driver * sc_get_pcsc_driver(void)
{
pcsc_ops.init = pcsc_init;
pcsc_ops.finish = pcsc_finish;
pcsc_ops.detect_readers = pcsc_detect_readers;
pcsc_ops.transmit = pcsc_transmit;
pcsc_ops.detect_card_presence = pcsc_detect_card_presence;
pcsc_ops.lock = pcsc_lock;
pcsc_ops.unlock = pcsc_unlock;
pcsc_ops.release = pcsc_release;
pcsc_ops.connect = pcsc_connect;
pcsc_ops.disconnect = pcsc_disconnect;
pcsc_ops.perform_verify = pcsc_pin_cmd;
pcsc_ops.wait_for_event = pcsc_wait_for_event;
pcsc_ops.reset = pcsc_reset;
return &pcsc_drv;
}
/*
* Pinpad support, based on PC/SC v2 Part 10 interface
* Similar to CCID in spirit.
@ -1100,7 +1079,7 @@ static int part10_build_verify_pin_block(u8 * buf, size_t * size, sc_slot_info_t
if (data->pin1.encoding == SC_PIN_ENCODING_GLP) {
/* GLP PIN length is encoded in 4 bits and block size is always 8 bytes */
tmp |= 0x40 | 0x08;
} else if (data->pin1.encoding == SC_PIN_ENCODING_ASCII && data->pin1.pad_length) {
} else if (data->pin1.encoding == SC_PIN_ENCODING_ASCII && data->flags & SC_PIN_CMD_NEED_PADDING) {
tmp |= data->pin1.pad_length;
}
pin_verify->bmPINBlockString = tmp;
@ -1223,11 +1202,20 @@ static int part10_build_modify_pin_block(u8 * buf, size_t * size, sc_slot_info_t
tmp16 = (data->pin1.min_length << 8 ) + data->pin1.max_length;
pin_modify->wPINMaxExtraDigit = HOST_TO_CCID_16(tmp16); /* Min Max */
pin_modify->bConfirmPIN = 0x03; /* bConfirmPIN, all */
/* bConfirmPIN flags
* 0x01: New Pin, Confirm Pin
* 0x03: Enter Old Pin, New Pin, Confirm Pin
*/
pin_modify->bConfirmPIN = data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? 0x01 : 0x03;
pin_modify->bEntryValidationCondition = 0x02; /* bEntryValidationCondition, keypress only */
/* bNumberMessage flags
* 0x02: Messages seen on Pinpad display: New Pin, Confirm Pin
* 0x03: Messages seen on Pinpad display: Enter Old Pin, New Pin, Confirm Pin
* Could be 0xFF too.
*/
if (slot->capabilities & SC_SLOT_CAP_DISPLAY)
pin_modify->bNumberMessage = 0x03; /* 3 messages (because bConfirmPIN = 3), all default. Could be 0xFF too */
pin_modify->bNumberMessage = data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? 0x02 : 0x03;
else
pin_modify->bNumberMessage = 0x00; /* No messages */
@ -1262,7 +1250,7 @@ static int part10_build_modify_pin_block(u8 * buf, size_t * size, sc_slot_info_t
/* Do the PIN command */
static int
part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
pcsc_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
struct sc_pin_cmd_data *data)
{
struct pcsc_private_data *priv = GET_PRIV_DATA(reader);
@ -1282,7 +1270,7 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
/* The APDU must be provided by the card driver */
if (!data->apdu) {
sc_error(reader->ctx, "No APDU provided for PC/SC v2 pinpad verification!");
sc_debug(reader->ctx, "No APDU provided for PC/SC v2 pinpad verification!");
return SC_ERROR_NOT_SUPPORTED;
}
@ -1290,7 +1278,7 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
switch (data->cmd) {
case SC_PIN_CMD_VERIFY:
if (!(pslot->verify_ioctl || (pslot->verify_ioctl_start && pslot->verify_ioctl_finish))) {
sc_error(reader->ctx, "Pinpad reader does not support verification!");
sc_debug(reader->ctx, "Pinpad reader does not support verification!");
return SC_ERROR_NOT_SUPPORTED;
}
r = part10_build_verify_pin_block(sbuf, &scount, slot, data);
@ -1299,14 +1287,14 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
case SC_PIN_CMD_CHANGE:
case SC_PIN_CMD_UNBLOCK:
if (!(pslot->modify_ioctl || (pslot->modify_ioctl_start && pslot->modify_ioctl_finish))) {
sc_error(reader->ctx, "Pinpad reader does not support modification!");
sc_debug(reader->ctx, "Pinpad reader does not support modification!");
return SC_ERROR_NOT_SUPPORTED;
}
r = part10_build_modify_pin_block(sbuf, &scount, slot, data);
ioctl = pslot->modify_ioctl ? pslot->modify_ioctl : pslot->modify_ioctl_start;
break;
default:
sc_error(reader->ctx, "Unknown PIN command %d", data->cmd);
sc_debug(reader->ctx, "Unknown PIN command %d", data->cmd);
return SC_ERROR_NOT_SUPPORTED;
}
@ -1362,5 +1350,25 @@ part10_pin_cmd(sc_reader_t *reader, sc_slot_info_t *slot,
/* PIN command completed, all is good */
return SC_SUCCESS;
}
struct sc_reader_driver * sc_get_pcsc_driver(void)
{
pcsc_ops.init = pcsc_init;
pcsc_ops.finish = pcsc_finish;
pcsc_ops.detect_readers = pcsc_detect_readers;
pcsc_ops.transmit = pcsc_transmit;
pcsc_ops.detect_card_presence = pcsc_detect_card_presence;
pcsc_ops.lock = pcsc_lock;
pcsc_ops.unlock = pcsc_unlock;
pcsc_ops.release = pcsc_release;
pcsc_ops.connect = pcsc_connect;
pcsc_ops.disconnect = pcsc_disconnect;
pcsc_ops.perform_verify = pcsc_pin_cmd;
pcsc_ops.wait_for_event = pcsc_wait_for_event;
pcsc_ops.reset = pcsc_reset;
return &pcsc_drv;
}
#endif /* HAVE_PCSC */

View File

@ -26,6 +26,9 @@
#include <openssl/crypto.h> /* for OPENSSL_cleanse */
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include "internal.h"
#include <stdio.h>
#include <ctype.h>
@ -660,12 +663,12 @@ int _sc_parse_atr(sc_context_t *ctx, sc_slot_info_t *slot)
slot->atr_info.hist_bytes = NULL;
if (atr_len == 0) {
sc_error(ctx, "empty ATR - card not present?\n");
sc_debug(ctx, "empty ATR - card not present?\n");
return SC_ERROR_INTERNAL;
}
if (p[0] != 0x3B && p[0] != 0x3F) {
sc_error(ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
sc_debug(ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
return SC_ERROR_INTERNAL;
}
n_hist = p[1] & 0x0F;
@ -715,6 +718,24 @@ int _sc_parse_atr(sc_context_t *ctx, sc_slot_info_t *slot)
return 0;
}
void *sc_mem_alloc_secure(size_t len)
{
void *pointer;
pointer = calloc(len, sizeof(unsigned char));
if (!pointer)
return NULL;
#ifdef HAVE_SYS_MMAN_H
/* TODO Windows support and mprotect too */
/* Do not swap the memory */
if (mlock(pointer, len) == -1) {
free(pointer);
return NULL;
}
#endif
return pointer;
}
void sc_mem_clear(void *ptr, size_t len)
{
#ifdef ENABLE_OPENSSL

View File

@ -192,10 +192,10 @@ int sc_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
break;
}
if (r == SC_ERROR_NOT_SUPPORTED)
sc_error(card->ctx, "unsupported PIN operation (%d)",
sc_debug(card->ctx, "unsupported PIN operation (%d)",
data->cmd);
} else {
sc_error(card->ctx, "Use of pin pad not supported by card driver");
sc_debug(card->ctx, "Use of pin pad not supported by card driver");
r = SC_ERROR_NOT_SUPPORTED;
}
SC_FUNC_RETURN(card->ctx, 2, r);

View File

@ -113,9 +113,6 @@ typedef struct sc_apdu {
u8 *resp; /* R-APDU data buffer */
size_t resplen; /* in: size of R-APDU buffer,
* out: length of data returned in R-APDU */
u8 sensitive; /* Set if either the command or
* the response contains secrets,
* e.g. a PIN. */
u8 control; /* Set if APDU should go to the reader */
unsigned int sw1, sw2; /* Status words returned in R-APDU */

View File

@ -182,7 +182,7 @@ static int sc_ui_get_func(sc_context_t *ctx, const char *name, void **ret)
sc_ui_lib_handle = lt_dlopen(lib_name);
if (!sc_ui_lib_handle) {
sc_error(ctx,
sc_debug(ctx,
"Unable to open user interface library '%s': %s\n",
lib_name, lt_dlerror());
return SC_ERROR_INTERNAL;
@ -391,10 +391,6 @@ sc_ui_display_msg(sc_context_t *ctx, int type, const char *msg)
int n;
switch (type) {
case SC_LOG_TYPE_ERROR:
outf = ctx->error_file;
break;
case SC_LOG_TYPE_DEBUG:
outf = ctx->debug_file;
break;

View File

@ -28,15 +28,8 @@
extern int hack_enabled;
#define MAX_CACHE_PIN 32
struct pkcs15_slot_data {
struct sc_pkcs15_object *auth_obj;
int user_consent;
struct {
sc_path_t path;
u8 value[MAX_CACHE_PIN];
unsigned int len;
} pin[2];
};
#define slot_data(p) ((struct pkcs15_slot_data *) (p))
#define slot_data_auth(p) (slot_data(p)->auth_obj)
@ -148,9 +141,6 @@ static CK_RV get_modulus_bits(struct sc_pkcs15_pubkey *,
static CK_RV get_usage_bit(unsigned int usage, CK_ATTRIBUTE_PTR attr);
static CK_RV asn1_sequence_wrapper(const u8 *, size_t, CK_ATTRIBUTE_PTR);
static CK_RV get_gostr3410_params(const u8 *, size_t, CK_ATTRIBUTE_PTR);
static void cache_pin(void *, int, const sc_path_t *, const void *, size_t);
static int revalidate_pin(struct pkcs15_slot_data *data,
struct sc_pkcs11_session *ses);
static int lock_card(struct pkcs15_fw_data *);
static int unlock_card(struct pkcs15_fw_data *);
static void add_pins_to_keycache(struct sc_pkcs11_card *p11card,
@ -674,11 +664,6 @@ pkcs15_add_object(struct sc_pkcs11_slot *slot,
obj->base.flags |= SC_PKCS11_OBJECT_SEEN;
obj->refcount++;
if (obj->p15_object && (obj->p15_object->user_consent > 0) ) {
sc_debug(context, "User consent object detected, marking slot as user_consent!\n");
((struct pkcs15_slot_data *)slot->fw_data)->user_consent = 1;
}
/* Add related objects
* XXX prevent infinite recursion when a card specifies two certificates
* referring to each other.
@ -728,7 +713,6 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card,
slot->token_info.flags |= CKF_USER_PIN_INITIALIZED;
if (card->card->slot->capabilities & SC_SLOT_CAP_PIN_PAD) {
slot->token_info.flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
sc_pkcs11_conf.cache_pins = 0;
}
if (card->card->caps & SC_CARD_CAP_RNG)
slot->token_info.flags |= CKF_RNG;
@ -745,6 +729,14 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card,
snprintf(tmp, sizeof(tmp), "%s", card->label);
}
slot->token_info.flags |= CKF_LOGIN_REQUIRED;
if (pin_info->tries_left >= 0) {
if (pin_info->tries_left == 1)
slot->token_info.flags |= CKF_USER_PIN_FINAL_TRY;
else if (pin_info->tries_left == 0)
slot->token_info.flags |= CKF_USER_PIN_LOCKED;
else if (pin_info->max_tries && pin_info->tries_left && pin_info->tries_left < pin_info->max_tries)
slot->token_info.flags |= CKF_USER_PIN_COUNT_LOW;
}
} else
snprintf(tmp, sizeof(tmp), "%s", card->label);
strcpy_bp(slot->token_info.label, tmp, 32);
@ -757,6 +749,8 @@ static void pkcs15_init_slot(struct sc_pkcs15_card *card,
slot->token_info.ulMaxPinLen = 8;
slot->token_info.ulMinPinLen = 4;
}
if (card->flags & SC_PKCS15_CARD_FLAG_EMULATED)
slot->token_info.flags |= CKF_WRITE_PROTECTED;
sc_debug(context, "Initialized token '%s'\n", tmp);
}
@ -1015,10 +1009,6 @@ static CK_RV pkcs15_login(struct sc_pkcs11_card *p11card,
rc = sc_pkcs15_verify_pin(card, pin, pPin, ulPinLen);
sc_debug(context, "PIN verification returned %d\n", rc);
if (rc >= 0)
cache_pin(fw_token, userType, &pin->path, pPin, ulPinLen);
return sc_to_cryptoki_error(rc, p11card->reader);
}
@ -1026,10 +1016,8 @@ static CK_RV pkcs15_logout(struct sc_pkcs11_card *p11card, void *fw_token)
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
int rc = 0;
cache_pin(fw_token, CKU_SO, NULL, NULL, 0);
cache_pin(fw_token, CKU_USER, NULL, NULL, 0);
sc_pkcs15_pincache_clear(fw_data->p15_card);
sc_logout(fw_data->p15_card->card);
if (sc_pkcs11_conf.lock_login)
@ -1066,9 +1054,6 @@ static CK_RV pkcs15_change_pin(struct sc_pkcs11_card *p11card,
rc = sc_pkcs15_change_pin(fw_data->p15_card, pin, pOldPin, ulOldLen,
pNewPin, ulNewLen);
sc_debug(context, "PIN change returned %d\n", rc);
if (rc >= 0)
cache_pin(fw_token, CKU_USER, &pin->path, pNewPin, ulNewLen);
return sc_to_cryptoki_error(rc, p11card->reader);
}
@ -1114,9 +1099,6 @@ static CK_RV pkcs15_init_pin(struct sc_pkcs11_card *p11card,
pkcs15_init_slot(fw_data->p15_card, slot, auth_obj);
pin_info = (sc_pkcs15_pin_info_t *) auth_obj->data;
cache_pin(slot->fw_data, CKU_USER, &pin_info->path, pPin, ulPinLen);
return CKR_OK;
}
@ -2135,6 +2117,10 @@ static CK_RV pkcs15_prkey_get_attribute(struct sc_pkcs11_session *session,
check_attribute_buffer(attr, sizeof(CK_BBOOL));
*(CK_BBOOL*)attr->pValue = TRUE;
break;
case CKA_ALWAYS_AUTHENTICATE:
check_attribute_buffer(attr, sizeof(CK_BBOOL));
*(CK_BBOOL*)attr->pValue = prkey->prv_p15obj->user_consent;
break;
case CKA_PRIVATE:
check_attribute_buffer(attr, sizeof(CK_BBOOL));
*(CK_BBOOL*)attr->pValue = (prkey->prv_p15obj->flags & SC_PKCS15_CO_FLAG_PRIVATE) != 0;
@ -2214,7 +2200,6 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
{
struct pkcs15_prkey_object *prkey = (struct pkcs15_prkey_object *) obj;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data;
struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data);
int rv, flags = 0;
sc_debug(context, "Initiating signing operation, mechanism 0x%x.\n",
@ -2286,15 +2271,6 @@ static CK_RV pkcs15_prkey_sign(struct sc_pkcs11_session *ses, void *obj,
pSignature,
*pulDataLen);
/* Do we have to try a re-login and then try to sign again? */
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
rv = revalidate_pin(data, ses);
if (rv == 0)
rv = sc_pkcs15_compute_signature(fw_data->p15_card,
prkey->prv_p15obj, flags, pData, ulDataLen,
pSignature, *pulDataLen);
}
sc_unlock(ses->slot->card->card);
sc_debug(context, "Sign complete. Result %d.\n", rv);
@ -2315,7 +2291,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
{
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) ses->slot->card->fw_data;
struct pkcs15_prkey_object *prkey;
struct pkcs15_slot_data *data = slot_data(ses->slot->fw_data);
u8 decrypted[256];
int buff_too_small, rv, flags = 0;
@ -2359,14 +2334,6 @@ pkcs15_prkey_decrypt(struct sc_pkcs11_session *ses, void *obj,
flags, pEncryptedData, ulEncryptedDataLen,
decrypted, sizeof(decrypted));
/* Do we have to try a re-login and then try to decrypt again? */
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
rv = revalidate_pin(data, ses);
if (rv == 0)
rv = sc_pkcs15_decipher(fw_data->p15_card, prkey->prv_p15obj,
flags, pEncryptedData, ulEncryptedDataLen,
decrypted, sizeof(decrypted));
}
sc_unlock(ses->slot->card->card);
sc_debug(context, "Key unwrap/decryption complete. Result %d.\n", rv);
@ -2609,7 +2576,6 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
int rv;
struct pkcs15_fw_data *fw_data =
(struct pkcs15_fw_data *) session->slot->card->fw_data;
struct pkcs15_slot_data *data = slot_data(session->slot->fw_data);
sc_card_t *card = session->slot->card->card;
int reader = session->slot->card->reader;
@ -2622,13 +2588,6 @@ static int pkcs15_dobj_get_value(struct sc_pkcs11_session *session,
rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data);
/* Do we have to try a re-login and then try to sign again? */
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
rv = revalidate_pin(data, session);
if (rv == 0)
rv = sc_pkcs15_read_data_object(fw_data->p15_card, dobj->info, out_data);
}
sc_unlock(card);
if (rv < 0)
return sc_to_cryptoki_error(rv, reader);
@ -2727,7 +2686,6 @@ static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object
struct pkcs15_data_object *obj = (struct pkcs15_data_object*) object;
struct sc_pkcs11_card *card = session->slot->card;
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) card->fw_data;
struct pkcs15_slot_data *data = slot_data(session->slot->fw_data);
struct sc_profile *profile = NULL;
int reader = session->slot->card->reader;
int rv;
@ -2748,13 +2706,7 @@ static CK_RV pkcs15_dobj_destroy(struct sc_pkcs11_session *session, void *object
/* Delete object in smartcard */
rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object);
/* Do we have to try a re-login and then try to delete again? */
if (rv == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) {
rv = revalidate_pin(data, session);
if (rv == 0)
rv = sc_pkcs15init_delete_object(fw_data->p15_card, profile, obj->base.p15_object);
}
/* FIXME: PIN revalidation missing, following belongs libopensc */
if (rv >= 0) {
/* pool_find_and_delete is called, therefore correct refcont
* Oppose to pkcs15_add_object */
@ -2942,64 +2894,6 @@ asn1_sequence_wrapper(const u8 *data, size_t len, CK_ATTRIBUTE_PTR attr)
return CKR_OK;
}
static void
cache_pin(void *p, int user, const sc_path_t *path, const void *pin, size_t len)
{
struct pkcs15_slot_data *data = (struct pkcs15_slot_data *) p;
#ifdef USE_PKCS15_INIT
if (len == 0) {
sc_keycache_forget_key(path, SC_AC_SYMBOLIC,
user? SC_PKCS15INIT_USER_PIN : SC_PKCS15INIT_SO_PIN);
}
#endif
if ((user != CKU_SO && user != CKU_USER) || !sc_pkcs11_conf.cache_pins)
return;
/* Don't cache pins related to user_consent objects/slots */
if (data->user_consent)
return;
memset(&data->pin[user], 0, sizeof(data->pin[user]));
if (len && len <= MAX_CACHE_PIN) {
memcpy(data->pin[user].value, pin, len);
data->pin[user].len = len;
if (path)
data->pin[user].path = *path;
}
}
/* TODO: GUI must indicate pinpad revalidation instead of a plain error.*/
static int
revalidate_pin(struct pkcs15_slot_data *data, struct sc_pkcs11_session *ses)
{
int rv;
u8 value[MAX_CACHE_PIN];
sc_debug(context, "PIN revalidation\n");
if (!sc_pkcs11_conf.cache_pins
&& !(ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH))
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
if (sc_pkcs11_conf.cache_pins && data->user_consent)
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
if (ses->slot->token_info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER, NULL, 0);
}
else {
memcpy(value, data->pin[CKU_USER].value, data->pin[CKU_USER].len);
rv = pkcs15_login(ses->slot->card, ses->slot->fw_data, CKU_USER,
value, data->pin[CKU_USER].len);
}
if (rv != CKR_OK)
sc_debug(context, "Re-login failed: 0x%0x (%d)\n", rv, rv);
return rv;
}
static int register_gost_mechanisms(struct sc_pkcs11_card *p11card, int flags)
{
CK_MECHANISM_INFO mech_info;
@ -3141,6 +3035,7 @@ static int register_mechanisms(struct sc_pkcs11_card *p11card)
return rc;
#endif
}
return CKR_OK;
}
@ -3172,7 +3067,8 @@ static void
add_pins_to_keycache(struct sc_pkcs11_card *p11card,
struct sc_pkcs11_slot *slot)
{
#ifdef USE_PKCS15_INIT
#if 0
//#ifdef USE_PKCS15_INIT
struct pkcs15_fw_data *fw_data = (struct pkcs15_fw_data *) p11card->fw_data;
struct sc_pkcs15_card *p15card = fw_data->p15_card;
struct pkcs15_slot_data *p15_data = slot_data(slot->fw_data);

View File

@ -33,9 +33,7 @@ static CK_RV pkcs15init_bind(struct sc_pkcs11_card *p11card)
struct sc_profile *profile;
int rc;
sc_ctx_suppress_errors_on(card->ctx);
rc = sc_pkcs15init_bind(card, "pkcs15", NULL, &profile);
sc_ctx_suppress_errors_off(card->ctx);
if (rc == 0)
p11card->fw_data = profile;
return sc_to_cryptoki_error(rc, p11card->reader);

View File

@ -80,10 +80,13 @@ sc_pkcs11_get_mechanism_list(struct sc_pkcs11_card *p11card,
unsigned int n, count = 0;
int rv;
if (!pulCount)
return CKR_ARGUMENTS_BAD;
for (n = 0; n < p11card->nmechanisms; n++) {
if (!(mt = p11card->mechanisms[n]))
continue;
if (count < *pulCount && pList)
if (pList && count < *pulCount)
pList[count] = mt->mech;
count++;
}

View File

@ -76,6 +76,8 @@ CK_RV sc_to_cryptoki_error(int rc, int reader)
case SC_ERROR_INVALID_DATA:
case SC_ERROR_INCORRECT_PARAMETERS:
return CKR_DATA_INVALID;
case SC_ERROR_CARD_UNRESPONSIVE:
return CKR_DEVICE_ERROR;
}
sc_debug(context, "opensc error: %s (%d)\n", sc_strerror(rc), rc);
return CKR_GENERAL_ERROR;
@ -320,8 +322,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t *ctx)
conf->max_virtual_slots = 16;
conf->slots_per_card = 4;
conf->hide_empty_tokens = 1;
conf->lock_login = 1;
conf->cache_pins = 1;
conf->lock_login = 0;
conf->soft_keygen_allowed = 0;
@ -337,6 +338,7 @@ void load_pkcs11_parameters(struct sc_pkcs11_config *conf, sc_context_t *ctx)
conf->slots_per_card = scconf_get_int(conf_block, "slots_per_card", conf->slots_per_card);
conf->hide_empty_tokens = scconf_get_bool(conf_block, "hide_empty_tokens", conf->hide_empty_tokens);
conf->lock_login = scconf_get_bool(conf_block, "lock_login", conf->lock_login);
conf->cache_pins = scconf_get_bool(conf_block, "cache_pins", conf->cache_pins);
conf->soft_keygen_allowed = scconf_get_bool(conf_block, "soft_keygen_allowed", conf->soft_keygen_allowed);
sc_debug(ctx, "PKCS#11 options: plug_and_play=%d max_virtual_slots=%d slots_per_card=%d hide_empty_tokens=%d lock_login=%d",
conf->plug_and_play, conf->max_virtual_slots, conf->slots_per_card, conf->hide_empty_tokens, conf->lock_login);
}

View File

@ -621,7 +621,7 @@ type_spec ck_attribute_specs[] = {
{ CKA_EC_POINT , "CKA_EC_POINT ", print_generic, NULL },
{ CKA_SECONDARY_AUTH , "CKA_SECONDARY_AUTH ", print_generic, NULL },
{ CKA_AUTH_PIN_FLAGS , "CKA_AUTH_PIN_FLAGS ", print_generic, NULL },
{ CKA_ALWAYS_AUTHENTICATE, "CKA_ALWAYS_AUTHENTICATE ", print_generic, NULL },
{ CKA_ALWAYS_AUTHENTICATE, "CKA_ALWAYS_AUTHENTICATE ", print_boolean, NULL },
{ CKA_WRAP_WITH_TRUSTED , "CKA_WRAP_WITH_TRUSTED ", print_generic, NULL },
{ CKA_WRAP_TEMPLATE , "CKA_WRAP_TEMPLATE ", print_generic, NULL },
{ CKA_UNWRAP_TEMPLATE , "CKA_UNWRAP_TEMPLATE ", print_generic, NULL },

View File

@ -188,7 +188,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
#endif
if (context != NULL) {
sc_error(context, "C_Initialize(): Cryptoki already initialized\n");
sc_debug(context, "C_Initialize(): Cryptoki already initialized\n");
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
}
@ -204,7 +204,7 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
rc = sc_context_create(&context, &ctx_opts);
if (rc != SC_SUCCESS) {
rv = CKR_DEVICE_ERROR;
rv = CKR_GENERAL_ERROR;
goto out;
}
@ -628,7 +628,7 @@ again:
return rv;
if (r != SC_SUCCESS) {
sc_error(context, "sc_wait_for_event() returned %d\n", r);
sc_debug(context, "sc_wait_for_event() returned %d\n", r);
rv = sc_to_cryptoki_error(r, -1);
goto out;
}

View File

@ -67,7 +67,7 @@ struct sc_pkcs11_card;
/* Object Pool */
struct sc_pkcs11_pool_item {
int handle;
unsigned long int handle;
void *item;
struct sc_pkcs11_pool_item *next;
struct sc_pkcs11_pool_item *prev;
@ -92,7 +92,6 @@ struct sc_pkcs11_config {
unsigned int slots_per_card;
unsigned char hide_empty_tokens;
unsigned char lock_login;
unsigned char cache_pins;
unsigned char soft_keygen_allowed;
};

View File

@ -37,9 +37,7 @@ static int asepcos_cond_delete(sc_profile_t *pro, sc_card_t *card,
int r;
sc_file_t *tfile = NULL;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, path, &tfile);
sc_ctx_suppress_errors_off(card->ctx);
if (r == SC_SUCCESS) {
r = sc_pkcs15init_authenticate(pro, card, tfile, SC_AC_OP_DELETE_SELF);
sc_file_free(tfile);
@ -64,9 +62,7 @@ static int asepcos_check_verify_tpin(sc_profile_t *profile, sc_card_t *card)
sc_path_t path;
/* check whether the file with the transport PIN exists */
sc_format_path("3f000001", &path);
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r == SC_SUCCESS) {
/* try to verify the transport key */
u8 pbuf[64];
@ -84,18 +80,18 @@ static int asepcos_check_verify_tpin(sc_profile_t *profile, sc_card_t *card)
card->caps |= SC_CARD_CAP_USE_FCI_AC;
sc_file_free(tfile);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to authenticate");
sc_debug(card->ctx, "unable to authenticate");
return r;
}
/* store the transport key as a PIN */
r = sc_keycache_get_key(&path, SC_AC_AUT, 0, pbuf, psize);
if (r < 0) {
sc_error(card->ctx, "unable to get transport key");
sc_debug(card->ctx, "unable to get transport key");
return r;
}
r = sc_keycache_put_key(&path, SC_AC_CHV, 0, pbuf, (size_t)r);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to store transport key");
sc_debug(card->ctx, "unable to store transport key");
return r;
}
}
@ -219,7 +215,7 @@ static int asepcos_pinid_to_akn(sc_card_t *card, int fileid, int *akn)
if (r != SC_SUCCESS)
return r;
if (nfile->prop_attr == NULL || nfile->prop_attr_len != 11) {
sc_error(card->ctx, "unable to determine AKN");
sc_debug(card->ctx, "unable to determine AKN");
sc_file_free(nfile);
return SC_ERROR_INTERNAL;
}
@ -244,7 +240,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card,
*p++ = pinid & 0xff;
/* pin length */
if (pinlen < 4 || pinlen > 16) {
sc_error(card->ctx, "invalid PIN length");
sc_debug(card->ctx, "invalid PIN length");
return SC_ERROR_INVALID_ARGUMENTS;
}
*p++ = 0x00;
@ -310,7 +306,7 @@ static int asepcos_do_store_pin(sc_profile_t *profile, sc_card_t *card,
r = sc_create_file(card, nfile);
sc_file_free(nfile);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to create PIN file");
sc_debug(card->ctx, "unable to create PIN file");
return r;
}
/* get AKN of the newly created PIN */
@ -380,7 +376,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card,
r = sc_pkcs15init_authenticate(profile, card, tfile, SC_AC_OP_CREATE);
sc_file_free(tfile);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to create PIN file, insufficent rights");
sc_debug(card->ctx, "unable to create PIN file, insufficent rights");
return r;
}
@ -393,13 +389,11 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card,
r = sc_append_file_id(&pin_path, pid & 0xff);
if (r != SC_SUCCESS)
return r;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &pin_path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r == SC_SUCCESS)
pid += 2;
else if (r != SC_ERROR_FILE_NOT_FOUND) {
sc_error(card->ctx, "error selecting PIN file");
sc_debug(card->ctx, "error selecting PIN file");
return r;
}
} while (r != SC_ERROR_FILE_NOT_FOUND);
@ -452,7 +446,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card,
return r;
r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_SET_SATTR, df);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to change the security attributes");
sc_debug(card->ctx, "unable to change the security attributes");
return r;
}
/* finally activate the application DF (fix ACLs) */
@ -465,7 +459,7 @@ static int asepcos_create_pin(sc_profile_t *profile, sc_card_t *card,
st.is_ef = 0;
r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_ACTIVATE_FILE, &st);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to activate DF");
sc_debug(card->ctx, "unable to activate DF");
return r;
}
}
@ -497,14 +491,14 @@ static int asepcos_do_authenticate(sc_profile_t *profile, sc_card_t *card,
sc_file_t *prkey = NULL;
r = sc_profile_get_file_by_path(profile, path, &prkey);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to find file in profile");
sc_debug(card->ctx, "unable to find file in profile");
return r;
}
r = sc_pkcs15init_authenticate(profile, card, prkey, op);
sc_file_free(prkey);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to authenticate");
sc_debug(card->ctx, "unable to authenticate");
return r;
}
return SC_SUCCESS;
@ -565,7 +559,7 @@ static int asepcos_do_create_key(sc_card_t *card, size_t ksize, int fileid,
nfile->id = fileid & 0xffff;
r = sc_file_set_prop_attr(nfile, buf, p - buf);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to set key prop. attributes");
sc_debug(card->ctx, "unable to set key prop. attributes");
sc_file_free(nfile);
return r;
}
@ -573,7 +567,7 @@ static int asepcos_do_create_key(sc_card_t *card, size_t ksize, int fileid,
r = sc_create_file(card, nfile);
sc_file_free(nfile);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to create key file");
sc_debug(card->ctx, "unable to create key file");
return r;
}
return r;
@ -599,7 +593,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_card_t *card,
st.akn = sc_keycache_find_named_pin(NULL, SC_PKCS15INIT_USER_PIN);
r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_AKN2FILEID, &st);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to determine file id of the PIN");
sc_debug(card->ctx, "unable to determine file id of the PIN");
return r;
}
afileid = st.fileid;
@ -664,7 +658,7 @@ static int asepcos_create_key(sc_profile_t *profile, sc_card_t *card,
r = asepcos_do_create_key(card, kinfo->modulus_length, fileid, buf, p - buf);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to create private key file");
sc_debug(card->ctx, "unable to create private key file");
return r;
}
return r;
@ -695,7 +689,7 @@ static int asepcos_do_store_rsa_key(sc_card_t *card, sc_profile_t *profile,
tpath.value[1] = kinfo->path.value[kinfo->path.len-1];
r = sc_select_file(card, &tpath, NULL);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to select rsa key file");
sc_debug(card->ctx, "unable to select rsa key file");
return r;
}
@ -734,7 +728,7 @@ static int asepcos_do_store_rsa_key(sc_card_t *card, sc_profile_t *profile,
r = sc_card_ctl(card, SC_CARDCTL_ASEPCOS_CHANGE_KEY, &ckdata);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to change key data");
sc_debug(card->ctx, "unable to change key data");
return r;
}
@ -754,7 +748,7 @@ static int asepcos_store_key(sc_profile_t *profile, sc_card_t *card,
sc_pkcs15_prkey_info_t *kinfo = (sc_pkcs15_prkey_info_t *) obj->data;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
sc_error(card->ctx, "only RSA is currently supported");
sc_debug(card->ctx, "only RSA is currently supported");
return SC_ERROR_NOT_SUPPORTED;
}
@ -790,7 +784,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_card_t *card,
tpath.value[1] = kinfo->path.value[kinfo->path.len-1];
r = sc_select_file(card, &tpath, NULL);
if (r != SC_SUCCESS) {
sc_error(card->ctx, "unable to select rsa key file");
sc_debug(card->ctx, "unable to select rsa key file");
return r;
}
@ -809,7 +803,7 @@ static int asepcos_generate_key(sc_profile_t *profile, sc_card_t *card,
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00) {
sc_error(card->ctx, "error creating key");
sc_debug(card->ctx, "error creating key");
return SC_ERROR_INTERNAL;
}

View File

@ -256,12 +256,12 @@ cardos_store_key(sc_profile_t *profile, sc_card_t *card,
int algorithm = 0, r;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
sc_error(card->ctx, "CardOS supports RSA keys only.");
sc_debug(card->ctx, "CardOS supports RSA keys only.");
return SC_ERROR_NOT_SUPPORTED;
}
if (cardos_key_algorithm(key_info->usage, key_info->modulus_length, &algorithm) < 0) {
sc_error(card->ctx, "CardOS does not support keys "
sc_debug(card->ctx, "CardOS does not support keys "
"that can both sign _and_ decrypt.");
return SC_ERROR_NOT_SUPPORTED;
}
@ -316,7 +316,7 @@ cardos_generate_key(sc_profile_t *profile, sc_card_t *card,
rsa_max_size = (card->caps & SC_CARD_CAP_RSA_2048) ? 2048 : 1024;
keybits = key_info->modulus_length & ~7UL;
if (keybits > rsa_max_size) {
sc_error(card->ctx, "Unable to generate key, max size is %lu",
sc_debug(card->ctx, "Unable to generate key, max size is %lu",
(unsigned long) rsa_max_size);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -325,13 +325,13 @@ cardos_generate_key(sc_profile_t *profile, sc_card_t *card,
use_ext_rsa = 1;
if (cardos_key_algorithm(key_info->usage, keybits, &algorithm) < 0) {
sc_error(card->ctx, "CardOS does not support keys "
sc_debug(card->ctx, "CardOS does not support keys "
"that can both sign _and_ decrypt.");
return SC_ERROR_NOT_SUPPORTED;
}
if (sc_profile_get_file(profile, "tempfile", &temp) < 0) {
sc_error(card->ctx, "Profile doesn't define temporary file "
sc_debug(card->ctx, "Profile doesn't define temporary file "
"for key generation.");
return SC_ERROR_NOT_SUPPORTED;
}
@ -399,7 +399,7 @@ cardos_store_pin(sc_profile_t *profile, sc_card_t *card,
* "no padding required". */
maxlen = MIN(profile->pin_maxlen, sizeof(pinpadded));
if (pin_len > maxlen) {
sc_error(card->ctx, "invalid pin length: %u (max %u)\n",
sc_debug(card->ctx, "invalid pin length: %u (max %u)\n",
pin_len, maxlen);
return SC_ERROR_INVALID_ARGUMENTS;
}
@ -675,13 +675,13 @@ static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len,
return SC_ERROR_INVALID_ARGUMENTS;
data = sc_asn1_find_tag(card->ctx, data, len, 0x7f49, &ilen);
if (data == NULL) {
sc_error(card->ctx, "invalid public key data: missing tag");
sc_debug(card->ctx, "invalid public key data: missing tag");
return SC_ERROR_INTERNAL;
}
p = sc_asn1_find_tag(card->ctx, data, ilen, 0x81, &tlen);
if (p == NULL) {
sc_error(card->ctx, "invalid public key data: missing modulus");
sc_debug(card->ctx, "invalid public key data: missing modulus");
return SC_ERROR_INTERNAL;
}
pubkey->u.rsa.modulus.len = tlen;
@ -692,7 +692,7 @@ static int parse_ext_pubkey_file(sc_card_t *card, const u8 *data, size_t len,
p = sc_asn1_find_tag(card->ctx, data, ilen, 0x82, &tlen);
if (p == NULL) {
sc_error(card->ctx, "invalid public key data: missing exponent");
sc_debug(card->ctx, "invalid public key data: missing exponent");
return SC_ERROR_INTERNAL;
}
pubkey->u.rsa.exponent.len = tlen;

View File

@ -72,9 +72,7 @@ cflex_delete_file(sc_profile_t *profile, sc_card_t *card, sc_file_t *df)
path.value[1] = df->id & 0xFF;
path.len = 2;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_delete_file(card, &path);
sc_ctx_suppress_errors_off(card->ctx);
return r;
}
@ -259,7 +257,7 @@ cflex_create_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj
int r;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
sc_error(card->ctx, "Cryptoflex supports only RSA keys.");
sc_debug(card->ctx, "Cryptoflex supports only RSA keys.");
return SC_ERROR_NOT_SUPPORTED;
}
@ -275,7 +273,7 @@ cflex_create_key(sc_profile_t *profile, sc_card_t *card, sc_pkcs15_object_t *obj
case 1024: size = 326; break;
case 2048: size = 646; break;
default:
sc_error(card->ctx, "Unsupported key size %u\n",
sc_debug(card->ctx, "Unsupported key size %u\n",
key_info->modulus_length);
r = SC_ERROR_INVALID_ARGUMENTS;
goto out;
@ -316,7 +314,7 @@ cflex_generate_key(sc_profile_t *profile, sc_card_t *card,
int r;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
sc_error(card->ctx, "Cryptoflex supports only RSA keys.");
sc_debug(card->ctx, "Cryptoflex supports only RSA keys.");
return SC_ERROR_NOT_SUPPORTED;
}
@ -378,7 +376,7 @@ cflex_store_key(sc_profile_t *profile, sc_card_t *card,
int r;
if (obj->type != SC_PKCS15_TYPE_PRKEY_RSA) {
sc_error(card->ctx, "Cryptoflex supports only RSA keys.");
sc_debug(card->ctx, "Cryptoflex supports only RSA keys.");
return SC_ERROR_NOT_SUPPORTED;
}
@ -451,9 +449,7 @@ cflex_create_dummy_chvs(sc_profile_t *profile, sc_card_t *card,
&& !memcmp(ef.value, parent.value, ef.len))
continue;
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &ef, NULL);
sc_ctx_suppress_errors_off(card->ctx);
}
/* If a valid EF(CHVx) was found, we're fine */
@ -524,9 +520,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_card_t *card,
path.value[path.len++] = 0;
/* See if the CHV already exists */
sc_ctx_suppress_errors_on(card->ctx);
r = sc_select_file(card, &path, NULL);
sc_ctx_suppress_errors_off(card->ctx);
if (r >= 0)
return SC_ERROR_FILE_ALREADY_EXISTS;
@ -534,7 +528,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_card_t *card,
if (sc_profile_get_file_by_path(profile, &path, &file) < 0
&& sc_profile_get_file(profile, (ref == 1)? "CHV1" : "CHV2", &file) < 0
&& sc_profile_get_file(profile, "CHV", &file) < 0) {
sc_error(card->ctx, "profile does not define pin file ACLs\n");
sc_debug(card->ctx, "profile does not define pin file ACLs\n");
return SC_ERROR_FILE_NOT_FOUND;
}
@ -559,7 +553,7 @@ cflex_create_pin_file(sc_profile_t *profile, sc_card_t *card,
file, SC_AC_OP_UPDATE,
dummies);
if (ndummies < 0) {
sc_error(card->ctx,
sc_debug(card->ctx,
"Unable to create dummy CHV file: %s",
sc_strerror(ndummies));
return ndummies;
@ -619,7 +613,7 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card,
if (r != SC_SUCCESS)
pbuf[0] = '\0';
sc_error(card->ctx, "Cannot find private key file info "
sc_debug(card->ctx, "Cannot find private key file info "
"in profile (path=%s).", pbuf);
return r;
}
@ -629,7 +623,7 @@ static int cflex_get_keyfiles(sc_profile_t *profile, sc_card_t *card,
sc_append_file_id(&path, 0x1012);
r = sc_profile_get_file_by_path(profile, &path, pukf);
if (r < 0) {
sc_error(card->ctx, "Cannot find public key file info in profile.");
sc_debug(card->ctx, "Cannot find public key file info in profile.");
sc_file_free(*prkf);
return r;
}

Some files were not shown because too many files have changed in this diff Show More