sc-hsm: Add support for SoC

- eac: allow CA without EF.CardSecurity
- sc-hsm: implemented CA based on document PKI
- sc-hsm: adds receive limit for SoC card
- introduces dedicated card type for SoC card
- md: integrate card's PIN pad capabilities
- installer: added SC-HSM SoC card to registry
- pkcs15-tool: Added support for PIN entry on card
- change/unblock PIN: add support for PIN entry on card
- added OpenPACE to macOS build
- travis-ci: install gengetopt/help2man via brew
- sc-hsm: Cache EF.C_DevAut
- sc-hsm: Prevent unnecessary applet selection and state resets
- sc-hsm: added support for session pin
- sc-hsm: avoid multiple AID selection
- sc-hsm: Use the information from match_card for all subsequent selections of the applet
- sc-hsm: cache optional files as empty files (Decoding the files will reveal that they were not existing prior caching. This avoids selecting the file though we have already tried to cache the file before.)
- use dedicated directory for CVC trust anchors
- appveyor: added OpenPACE to windows build
This commit is contained in:
Frank Morgner 2017-03-23 16:45:31 +01:00
parent 77f6e94e6f
commit 74ec7b04ff
32 changed files with 833 additions and 127 deletions

View File

@ -14,6 +14,7 @@ addons:
- wine
- xsltproc
- gengetopt
- help2man
coverity_scan:
project:
name: "OpenSC/OpenSC"
@ -51,7 +52,7 @@ before_install:
brew update;
brew uninstall libtool;
brew install libtool;
brew install gengetopt;
brew install gengetopt help2man;
fi
before_script:

View File

@ -40,9 +40,24 @@ if ! pkg-config libcrypto --atleast-version=1.0.1; then
export OPENSSL_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --libs libcrypto`"
fi
if ! test -e $BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig; then
if ! test -e openpace; then
git clone --depth=1 https://github.com/frankmorgner/openpace.git
fi
cd openpace
autoreconf -vis
./configure --disable-shared --prefix=$PREFIX CRYPTO_CFLAGS="$OPENSSL_CFLAGS" CRYPTO_LIBS="$OPENSSL_LIBS"
make DESTDIR=$BUILDPATH/openpace_bin install
cd ..
export OPENPACE_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --cflags libeac` $OPENSSL_CFLAGS"
export OPENPACE_LIBS="` env PKG_CONFIG_PATH=$BUILDPATH/openpace_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openpace_bin pkg-config --static --libs libeac` $OPENSSL_LIBS"
fi
if ! test -e ${BUILDPATH}/target/$PREFIX/lib/pkgconfig; then
./configure --prefix=$PREFIX \
--sysconfdir=$PREFIX/etc \
--enable-cvcdir=$PREFIX/etc/cvc \
--enable-x509dir=$PREFIX/etc/x509 \
--disable-dependency-tracking \
--enable-shared \
--disable-static \

View File

@ -30,6 +30,7 @@ install:
- date /T & time /T
- set PATH=C:\cygwin\bin;%PATH%
- set OPENSSL_VER=1_0_2e
- set OPENPACE_VER=1.0.1
- set ZLIB_VER_DOT=1.2.8
- ps: $env:PACKAGE_NAME=(git describe --tags)
- ps: >-
@ -62,6 +63,11 @@ install:
}
7z x zlib.zip -oC:\
Rename-Item -path "c:\zlib-${env:ZLIB_VER_DOT}" -newName "zlib"
If (!(Test-Path openpace.zip )) {
appveyor DownloadFile "https://github.com/frankmorgner/openpace/archive/${env:OPENPACE_VER}.zip" -FileName openpace.zip
}
7z x openpace.zip -oC:\
Rename-Item -path "c:\openpace-${env:OPENPACE_VER}" -newName "openpace"
}
- ps: $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
- echo "Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%"
@ -72,9 +78,9 @@ install:
- set
build_script:
# build zlib.lib as a static library
- ps: >-
if (!($env:Configuration -Like "*Light*")) {
# build zlib.lib as a static library
cd C:\zlib
(Get-Content win32/Makefile.msc).replace('-MD', '-MT') | Set-Content win32/Makefile.msc
If ($env:Platform -Match "x86") {
@ -83,7 +89,12 @@ build_script:
nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." OBJA="inffasx64.obj gvmat64.obj inffas8664.obj" zlib.lib
}
$env:NMAKE_EXTRA="ZLIBSTATIC_DEF=/DENABLE_ZLIB_STATIC ${env:NMAKE_EXTRA}"
cd c:\projects\Opensc
# build libeac.lib as a static library
cd C:\openpace\src
cl /IC:\OpenSSL-${env:OPENSSL_PF}\include /I. /DX509DIR=\`"/\`" /DCVCDIR=\`"/\`" /W3 /D_CRT_SECURE_NO_DEPRECATE /DWIN32_LEAN_AND_MEAN /GS /MT /c ca_lib.c cv_cert.c cvc_lookup.c x509_lookup.c eac_asn1.c eac.c eac_ca.c eac_dh.c eac_ecdh.c eac_kdf.c eac_lib.c eac_print.c eac_util.c misc.c pace.c pace_lib.c pace_mappings.c ri.c ri_lib.c ta.c ta_lib.c objects.c
lib /out:libeac.lib ca_lib.obj cv_cert.obj cvc_lookup.obj x509_lookup.obj eac_asn1.obj eac.obj eac_ca.obj eac_dh.obj eac_ecdh.obj eac_kdf.obj eac_lib.obj eac_print.obj eac_util.obj misc.obj pace.obj pace_lib.obj pace_mappings.obj ri.obj ri_lib.obj ta.obj ta_lib.obj objects.obj
$env:NMAKE_EXTRA="OPENPACE_DEF=/DENABLE_OPENPACE ${env:NMAKE_EXTRA}"
cd C:\projects\OpenSC
}
- bash -c "exec 0</dev/null && ./bootstrap"
# disable features to speed up the script

View File

@ -609,10 +609,18 @@ if test "${cvcdir}" = false ; then
cvcdir="`$PKG_CONFIG libeac --variable=cvcdir`"
fi
if test "${cvcdir}" = "" ; then
AC_MSG_WARN([use --enable-cvcdir=DIR])
case "${host}" in
*-mingw*|*-winnt*|*-cygwin*)
cvcdir="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\cvc"
;;
*)
AC_MSG_WARN([use --enable-cvcdir=DIR])
;;
esac
fi
CVCDIR="${cvcdir}"
AC_SUBST(CVCDIR)
AC_DEFINE_UNQUOTED([CVCDIR], ["${CVCDIR}"], [CVC directory])
AC_ARG_ENABLE(x509dir,
AC_HELP_STRING([--enable-x509dir=DIR],
@ -628,10 +636,18 @@ then
fi
if test -z "${x509dir}"
then
AC_MSG_WARN([use --enable-x509dir=DIR])
case "${host}" in
*-mingw*|*-winnt*|*-cygwin*)
x509dir="%PROGRAMFILES%\\\OpenSC Project\\\OpenSC\\\x509"
;;
*)
AC_MSG_WARN([use --enable-x509dir=DIR])
;;
esac
fi
X509DIR="${x509dir}"
AC_SUBST(X509DIR)
AC_DEFINE_UNQUOTED([X509DIR], ["${X509DIR}"], [CVC directory])
case "${enable_openpace}" in
no)
@ -905,7 +921,9 @@ AM_CONDITIONAL([ENABLE_THREAD_LOCKING], [test "${enable_thread_locking}" = "yes"
AM_CONDITIONAL([ENABLE_ZLIB], [test "${enable_zlib}" = "yes"])
AM_CONDITIONAL([ENABLE_READLINE], [test "${enable_readline}" = "yes"])
AM_CONDITIONAL([ENABLE_OPENSSL], [test "${enable_openssl}" = "yes"])
AM_CONDITIONAL([ENABLE_OPENPACE], [test "${enable_openpace}" = "yes"])
AM_CONDITIONAL([ENABLE_CRYPTOTOKENKIT], [test "${enable_cryptotokenkit}" = "yes"])
AM_CONDITIONAL([ENABLE_OPENCT], [test "${enable_openct}" = "yes"])
AM_CONDITIONAL([ENABLE_DOC], [test "${enable_doc}" = "yes"])
AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
AM_CONDITIONAL([CYGWIN], [test "${CYGWIN}" = "yes"])

BIN
etc/DESRCACC100001 Normal file

Binary file not shown.

View File

@ -1,7 +1,9 @@
CV_CERTS = UTSRCACC100001 DESRCACC100001
MAINTAINERCLEANFILES = $(srcdir)/Makefile.in
DISTCLEANFILES = opensc.conf
EXTRA_DIST = Makefile.mak
EXTRA_DIST = $(CV_CERTS) Makefile.mak
SUFFIXES = .in
@ -38,3 +40,12 @@ install-exec-hook: opensc.conf
uninstall-hook: opensc.conf
rm -f "$(DESTDIR)$(sysconfdir)/opensc.conf.new" "$(DESTDIR)$(sysconfdir)/opensc.conf"
if ENABLE_OPENPACE
install-data-local:
$(MKDIR_P) "$(DESTDIR)$(CVCDIR)"
for cert in $(CV_CERTS); do $(INSTALL_DATA) $(srcdir)/$${cert} "$(DESTDIR)$(CVCDIR)"; done
uninstall-local:
for cert in $(CV_CERTS); do rm -f "$(DESTDIR)$(CVCDIR)/$${cert}"; done
endif

BIN
etc/UTSRCACC100001 Normal file

Binary file not shown.

View File

@ -73,8 +73,8 @@ libopensc_static_la_SOURCES = $(libopensc_la_SOURCES_BASE)
if WIN32
libopensc_la_SOURCES += $(top_builddir)/win32/versioninfo.rc
endif
libopensc_la_LIBADD = $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) $(OPTIONAL_OPENCT_LIBS) \
$(OPTIONAL_ZLIB_LIBS) \
libopensc_la_LIBADD = $(OPENPACE_LIBS) $(OPTIONAL_OPENSSL_LIBS) \
$(OPTIONAL_OPENCT_LIBS) $(OPTIONAL_ZLIB_LIBS) \
$(top_builddir)/src/pkcs15init/libpkcs15init.la \
$(top_builddir)/src/scconf/libscconf.la \
$(top_builddir)/src/common/libscdl.la \

View File

@ -41,6 +41,7 @@ OBJECTS = \
LIBS = $(TOPDIR)\src\scconf\scconf.lib \
$(TOPDIR)\src\common\common.lib \
$(TOPDIR)\src\common\libscdl.lib \
$(TOPDIR)\src\sm\libsmiso.lib \
$(TOPDIR)\src\sm\libsmeac.lib \
$(TOPDIR)\src\pkcs15init\pkcs15init.lib

View File

@ -72,44 +72,108 @@ static struct sc_atr_table sc_hsm_jc_atrs[] = {
/* standard version */
{"3b:f8:13:00:00:81:31:fe:45:4a:43:4f:50:76:32:34:31:b7", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, // JCOP 2.4.1 Default ATR contact based
{"3b:88:80:01:4a:43:4f:50:76:32:34:31:5e", NULL, NULL, SC_CARD_TYPE_SC_HSM, 0, NULL}, // JCOP 2.4.1 Default ATR contactless
{"3B:80:80:01:01", NULL, NULL, SC_CARD_TYPE_SC_HSM_SOC, 0, NULL}, // SoC Sample Card
{NULL, NULL, NULL, 0, 0, NULL}
};
static int sc_hsm_select_file_ex(sc_card_t *card,
const sc_path_t *in_path, int forceselect,
sc_file_t **file_out)
{
int rv;
sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
sc_file_t *file = NULL;
sc_path_t cpath;
if (file_out == NULL) { // Versions before 0.16 of the SmartCard-HSM do not support P2='0C'
rv = sc_hsm_select_file_ex(card, in_path, forceselect, &file);
if (file != NULL) {
sc_file_free(file);
}
return rv;
}
if ((in_path->type == SC_PATH_TYPE_FILE_ID) && in_path->aid.len) {
// Split applet selection and file selection into two separate calls
cpath = *in_path;
cpath.len = 0;
cpath.type = SC_PATH_TYPE_DF_NAME;
rv = sc_hsm_select_file_ex(card, &cpath, forceselect, NULL);
LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
if (in_path->len) {
cpath = *in_path;
cpath.aid.len = 0;
rv = sc_hsm_select_file_ex(card, &cpath, forceselect, file_out);
}
return rv;
}
// Prevent selection of applet unless this is the first time, selection is forced or the device is not authenticated
if (in_path->type == SC_PATH_TYPE_DF_NAME
|| (in_path->type == SC_PATH_TYPE_PATH
&& in_path->len == sc_hsm_aid.len
&& !memcmp(in_path->value, sc_hsm_aid.value, sc_hsm_aid.len))
|| (in_path->type == SC_PATH_TYPE_PATH
&& in_path->len == 0
&& in_path->aid.len == sc_hsm_aid.len
&& !memcmp(in_path->aid.value, sc_hsm_aid.value, sc_hsm_aid.len))) {
if ((priv->dffcp == NULL) || forceselect) {
rv = (*iso_ops->select_file)(card, in_path, file_out);
LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
if (priv->dffcp != NULL) {
sc_file_free(priv->dffcp);
}
// Cache the FCP returned when selecting the applet
sc_file_dup(&priv->dffcp, *file_out);
} else {
sc_file_dup(file_out, priv->dffcp);
rv = SC_SUCCESS;
}
return rv;
}
if ((in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) {
// The SmartCard-HSM is an applet that is not default selected. Simulate selection of the MF
if (in_path->len == 2) {
file = sc_file_new();
if (file == NULL)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
file->path = *in_path;
file->id = 0x3F00;
file->type = SC_FILE_TYPE_DF;
file->magic = SC_FILE_MAGIC;
*file_out = file;
return SC_SUCCESS;
} else {
sc_path_t truncated;
memcpy(&truncated, in_path, sizeof truncated);
truncated.len = in_path->len - 2;
memcpy(truncated.value, in_path->value+2, truncated.len);
return (*iso_ops->select_file)(card, &truncated, file_out);
}
}
return (*iso_ops->select_file)(card, in_path, file_out);
}
static int sc_hsm_select_file(sc_card_t *card,
const sc_path_t *in_path,
sc_file_t **file_out)
{
int rv;
sc_file_t *file = NULL;
if (file_out == NULL) { // Versions before 0.16 of the SmartCard-HSM do not support P2='0C'
rv = sc_hsm_select_file(card, in_path, &file);
sc_file_free(file);
return rv;
}
if ((in_path->len == 2) && (in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) {
// The SmartCard-HSM is an applet that is not default selected. Simulate selection of the MF
file = sc_file_new();
if (file == NULL)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
file->path = *in_path;
file->id = 0x3F00;
file->type = SC_FILE_TYPE_DF;
file->magic = SC_FILE_MAGIC;
*file_out = file;
return SC_SUCCESS;
}
return (*iso_ops->select_file)(card, in_path, file_out);
return sc_hsm_select_file_ex(card, in_path, 0, file_out);
}
static int sc_hsm_match_card(struct sc_card *card)
{
sc_hsm_private_data_t *priv;
sc_path_t path;
int i, r;
@ -121,10 +185,44 @@ static int sc_hsm_match_card(struct sc_card *card)
if (i < 0)
return 0;
priv = calloc(1, sizeof(sc_hsm_private_data_t));
if (!priv)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
card->drv_data = priv;
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
r = sc_hsm_select_file(card, &path, NULL);
r = (*iso_ops->select_file)(card, &path, &priv->dffcp);
LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");
if (priv->dffcp) {
if (priv->dffcp->prop_attr && priv->dffcp->prop_attr_len >= 5) {
static char card_name[SC_MAX_APDU_BUFFER_SIZE];
u8 type = priv->dffcp->prop_attr[2];
u8 major = priv->dffcp->prop_attr[3];
u8 minor = priv->dffcp->prop_attr[4];
char p00[] = "SmartCard-HSM Applet for JCOP";
char p01[] = "SmartCard-HSM Demo Applet for JCOP";
char *p = "SmartCard-HSM";
switch (type) {
case 0x00:
p = p00;
break;
case 0x01:
p = p01;
break;
default:
break;
}
snprintf(card_name, sizeof card_name, "%s version %u.%u", p, major, minor);
card->name = card_name;
if (priv->dffcp->prop_attr[1] & 0x04) {
card->caps |= SC_CARD_CAP_SESSION_PIN;
}
}
}
// Select Applet to be sure
return 1;
}
@ -162,6 +260,258 @@ static int sc_hsm_encode_sopin(const u8 *sopin, u8 *sopinbin)
}
static int sc_hsm_soc_select_minbioclient(sc_card_t *card)
{
sc_apdu_t apdu;
struct sc_aid minBioClient_aid = {
{ 0xFF,'m','i','n','B','i','o','C','l','i','e','n','t',0x01 }, 14
};
/* Select MinBioClient */
sc_sm_stop(card);
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0x04, 0x0C);
apdu.data = minBioClient_aid.value;
apdu.datalen = minBioClient_aid.len;
apdu.lc = minBioClient_aid.len;
LOG_TEST_RET(card->ctx,
sc_transmit_apdu(card, &apdu),
"APDU transmit failed");
return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
static int sc_hsm_soc_change(sc_card_t *card, struct sc_pin_cmd_data *data,
int *tries_left)
{
sc_apdu_t apdu;
sc_path_t path;
int r;
/* Select MinBioClient */
r = sc_hsm_soc_select_minbioclient(card);
LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
/* verify PIN */
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x80);
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PIN");
/* change PIN */
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x24, 0x01, 0x80);
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_TEST_GOTO_ERR(card->ctx, r, "Could not change PIN");
err:
/* Select SC-HSM */
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
LOG_TEST_RET(card->ctx,
sc_hsm_select_file_ex(card, &path, 1, NULL),
"Could not select SmartCard-HSM application");
return r;
}
static int sc_hsm_soc_unblock(sc_card_t *card, struct sc_pin_cmd_data *data,
int *tries_left)
{
sc_apdu_t apdu;
sc_path_t path;
int r;
/* Select MinBioClient */
r = sc_hsm_soc_select_minbioclient(card);
LOG_TEST_RET(card->ctx, r, "Could not select MinBioClient application");
/* verify PUK */
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x20, 0x00, 0x81);
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_TEST_GOTO_ERR(card->ctx, r, "Could not verify PUK");
/* reset retry counter */
sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x2c, 0x03, 0x00);
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_GOTO_ERR(card->ctx, r, "APDU transmit failed");
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
LOG_TEST_GOTO_ERR(card->ctx, r, "Could not unblock PIN");
err:
/* Select SC-HSM */
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
LOG_TEST_RET(card->ctx,
sc_hsm_select_file_ex(card, &path, 1, NULL),
"Could not select SmartCard-HSM application");
return r;
}
static int sc_hsm_soc_biomatch(sc_card_t *card, struct sc_pin_cmd_data *data,
int *tries_left)
{
sc_apdu_t apdu;
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
int r;
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x20, 0x00, 0x85);
apdu.cla = 0x80;
apdu.data = (unsigned char*)"\x7F\x24\x00";
apdu.datalen = 3;
apdu.lc = 3;
apdu.resplen = 0;
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
/* ignore the actual status bytes */
/* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, 0x81);
apdu.resp = rbuf;
apdu.resplen = sizeof rbuf;
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
/* now check the status bytes */
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
if (r == SC_SUCCESS) {
LOG_FUNC_RETURN(card->ctx, r);
}
LOG_FUNC_RETURN(card->ctx, SC_ERROR_PIN_CODE_INCORRECT);
}
#ifdef ENABLE_OPENPACE
#include "sm/sm-eac.h"
#include <eac/cv_cert.h>
#include <eac/eac.h>
#include <eac/ta.h>
#include <openssl/bio.h>
#include <openssl/crypto.h>
static int sc_hsm_perform_chip_authentication(sc_card_t *card)
{
int r, protocol;
sc_path_t path;
u8 all_certs[1024];
EAC_CTX *ctx = NULL;
size_t all_certs_len = sizeof all_certs, left, device_cert_len, issuer_cert_len;
const unsigned char *cert = all_certs, *device_cert, *issuer_cert;
BUF_MEM *comp_pub_key = NULL;
sc_cvc_t cvc_device, cvc_issuer;
/* this is only needed to call sc_pkcs15emu_sc_hsm_decode_cvc */
sc_pkcs15_card_t p15card;
sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
/* we know that sc_pkcs15emu_sc_hsm_decode_cvc does not require anything
* else to be initialized than p15card->card */
p15card.card = card;
memset(&cvc_device, 0, sizeof(cvc_device));
memset(&cvc_issuer, 0, sizeof(cvc_issuer));
if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) {
all_certs_len = priv->EF_C_DevAut_len;
cert = priv->EF_C_DevAut;
} else {
/* get issuer and device certificate from the card */
r = sc_path_set(&path, SC_PATH_TYPE_FILE_ID, (u8 *) "\x2F\x02", 2, 0, 0);
if (r < 0)
goto err;
r = sc_select_file(card, &path, NULL);
if (r < 0)
goto err;
r = sc_read_binary(card, 0, all_certs, all_certs_len, 0);
if (r < 0)
goto err;
all_certs_len = r;
/* save EF_C_DevAut for further use */
cert = realloc(priv->EF_C_DevAut, all_certs_len);
if (cert) {
memcpy((unsigned char *) cert, all_certs, all_certs_len);
priv->EF_C_DevAut = (unsigned char *) cert;
priv->EF_C_DevAut_len = all_certs_len;
}
cert = all_certs;
}
left = all_certs_len;
device_cert = cert;
r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_device);
if (r < 0)
goto err;
device_cert_len = all_certs_len - left;
issuer_cert = cert;
r = sc_pkcs15emu_sc_hsm_decode_cvc(&p15card, &cert, &left, &cvc_issuer);
if (r < 0)
goto err;
issuer_cert_len = all_certs_len - device_cert_len - left;
ctx = EAC_CTX_new();
if (!ctx) {
r = SC_ERROR_INTERNAL;
goto err;
}
/* check all CVCs given of the document's pki */
if (!TA_STEP2_import_certificate(ctx, issuer_cert, issuer_cert_len)
|| !TA_STEP2_import_certificate(ctx, device_cert, device_cert_len)) {
r = SC_ERROR_INTERNAL;
goto err;
}
if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
/* SoC cards are known to be implemented on newer JCOPs */
protocol = NID_id_CA_ECDH_AES_CBC_CMAC_128;
} else {
/* Older cards may not support AES accelerator */
protocol = NID_id_CA_ECDH_3DES_CBC_CBC;
}
/* initialize CA domain parameter with the document's public key */
if (!EAC_CTX_init_ca(ctx, protocol, 8)) {
r = SC_ERROR_INTERNAL;
goto err;
}
EVP_PKEY_free(ctx->ca_ctx->ka_ctx->key);
CRYPTO_add(&ctx->ta_ctx->pub_key->references, 1, CRYPTO_LOCK_EVP_PKEY);
ctx->ca_ctx->ka_ctx->key = ctx->ta_ctx->pub_key;
/* generate keys for CA */
comp_pub_key = TA_STEP3_generate_ephemeral_key(ctx);
r = perform_chip_authentication_ex(card, ctx,
cvc_device.publicPoint, cvc_device.publicPointlen);
err:
if (r < 0)
EAC_CTX_clear_free(ctx);
if (comp_pub_key)
BUF_MEM_free(comp_pub_key);
sc_pkcs15emu_sc_hsm_free_cvc(&cvc_device);
sc_pkcs15emu_sc_hsm_free_cvc(&cvc_issuer);
return r;
}
#else
static int sc_hsm_perform_chip_authentication(sc_card_t *card)
{
return SC_ERROR_NOT_SUPPORTED;
}
#endif
static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
int *tries_left)
@ -169,43 +519,132 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data,
sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
sc_apdu_t apdu;
u8 cmdbuff[16];
u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
int r;
int cmd = data->cmd;
size_t pin2_len = data->pin2.len;
if ((data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x88)) {
if (data->pin1.len != 16)
return SC_ERROR_INVALID_PIN_LENGTH;
// Save SO PIN for later use in sc_hsm_init_pin()
r = sc_hsm_encode_sopin(data->pin1.data, priv->sopin);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
if (cmd == SC_PIN_CMD_GET_SESSION_PIN) {
/* First, perform a standard VERIFY */
data->cmd = SC_PIN_CMD_VERIFY;
/* we assign pin2.len to 0 early on so that in case of an error we are
* not exiting with an undefined session PIN */
data->pin2.len = 0;
}
if ((data->cmd == SC_PIN_CMD_CHANGE) && (data->pin_reference == 0x88)) {
if ((data->pin1.len != 16) || (data->pin2.len != 16))
return SC_ERROR_INVALID_PIN_LENGTH;
r = sc_hsm_encode_sopin(data->pin1.data, cmdbuff);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
r = sc_hsm_encode_sopin(data->pin2.data, cmdbuff + 8);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, data->pin_reference);
apdu.data = cmdbuff;
apdu.datalen = sizeof(cmdbuff);
apdu.lc = 16;
apdu.resplen = 0;
data->apdu = &apdu;
if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
&& (data->cmd == SC_PIN_CMD_CHANGE)
&& (data->pin_reference == 0x81)
&& (!data->pin1.data || data->pin1.len <= 0)) {
return sc_hsm_soc_change(card, data, tries_left);
} else if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
&& (data->cmd == SC_PIN_CMD_UNBLOCK)
&& (data->pin_reference == 0x81)
&& (!data->pin1.data || data->pin1.len <= 0)) {
return sc_hsm_soc_unblock(card, data, tries_left);
}
data->pin1.offset = 5;
data->pin1.length_offset = 4;
data->pin2.offset = 5;
data->pin2.length_offset = 4;
/* For contactless cards always establish a secure channel before PIN
* verification */
if (card->type == SC_CARD_TYPE_SC_HSM_SOC
&& (data->cmd != SC_PIN_CMD_GET_INFO)
&& card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) {
LOG_TEST_RET(card->ctx,
sc_hsm_perform_chip_authentication(card),
"Could not perform chip authentication");
}
return (*iso_ops->pin_cmd)(card, data, tries_left);
if ((card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
&& (data->cmd == SC_PIN_CMD_VERIFY)
&& (data->pin_reference == 0x81)
&& (!data->pin1.data || data->pin1.len <= 0)) {
r = sc_hsm_soc_biomatch(card, data, tries_left);
} else {
if ((data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x88)) {
if (data->pin1.len != 16)
return SC_ERROR_INVALID_PIN_LENGTH;
// Save SO PIN for later use in sc_hsm_init_pin()
r = sc_hsm_encode_sopin(data->pin1.data, priv->sopin);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
if ((data->cmd == SC_PIN_CMD_CHANGE) && (data->pin_reference == 0x88)) {
if ((data->pin1.len != 16) || (data->pin2.len != 16))
return SC_ERROR_INVALID_PIN_LENGTH;
r = sc_hsm_encode_sopin(data->pin1.data, cmdbuff);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
r = sc_hsm_encode_sopin(data->pin2.data, cmdbuff + 8);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, data->pin_reference);
apdu.data = cmdbuff;
apdu.datalen = sizeof(cmdbuff);
apdu.lc = 16;
apdu.resplen = 0;
data->apdu = &apdu;
}
if ((data->cmd == SC_PIN_CMD_GET_INFO)
&& (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT)) {
/* JCOP's SM accelerator is incapable of using case 1 APDU in SM */
sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x20, 0x00, data->pin_reference);
apdu.resp = rbuf;
apdu.resplen = sizeof rbuf;
data->apdu = &apdu;
}
data->pin1.offset = 5;
data->pin1.length_offset = 4;
data->pin2.offset = 5;
data->pin2.length_offset = 4;
r = (*iso_ops->pin_cmd)(card, data, tries_left);
}
LOG_TEST_RET(card->ctx, r, "Verification failed");
if (cmd == SC_PIN_CMD_GET_SESSION_PIN) {
/* reset data->cmd to its original value */
data->cmd = SC_PIN_CMD_GET_SESSION_PIN;
if (data->pin_reference == 0x81) {
u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"Session PIN generation only supported in SM");
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0x5A, 0x01, data->pin_reference);
apdu.cla = 0x80;
apdu.resp = recvbuf;
apdu.resplen = sizeof recvbuf;
apdu.le = 0;
if (sc_transmit_apdu(card, &apdu) != SC_SUCCESS
|| sc_check_sw(card, apdu.sw1, apdu.sw2) != SC_SUCCESS) {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"Generating session PIN failed");
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
if (data->pin2.data && pin2_len > 0) {
if (pin2_len >= apdu.resplen) {
memcpy((unsigned char *) data->pin2.data, apdu.resp,
apdu.resplen);
data->pin2.len = apdu.resplen;
} else {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"Buffer too small for session PIN");
}
}
} else {
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,
"Session PIN not supported for this PIN (0x%02X)",
data->pin_reference);
}
}
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
@ -215,10 +654,11 @@ static int sc_hsm_logout(sc_card_t * card)
sc_path_t path;
sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
memset(priv->sopin, 0, sizeof(priv->sopin));
sc_sm_stop(card);
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
return sc_hsm_select_file(card, &path, NULL);
return sc_hsm_select_file_ex(card, &path, 1, NULL);
}
@ -409,7 +849,6 @@ static int sc_hsm_delete_file(sc_card_t *card, const sc_path_t *path)
}
static int sc_hsm_set_security_env(sc_card_t *card,
const sc_security_env_t *env,
int se_num)
@ -565,6 +1004,7 @@ static int sc_hsm_compute_signature(sc_card_t *card,
apdu.lc = datalen;
apdu.datalen = datalen;
r = sc_transmit_apdu(card, &apdu);
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
int len;
@ -1029,17 +1469,17 @@ static int sc_hsm_card_ctl(sc_card_t *card, unsigned long cmd, void *ptr)
static int sc_hsm_init(struct sc_card *card)
{
sc_hsm_private_data_t *priv;
#ifdef _WIN32
char expanded_val[PATH_MAX];
size_t expanded_len = PATH_MAX;
#endif
int flags,ext_flags;
sc_file_t *file;
sc_path_t path;
sc_hsm_private_data_t *priv = card->drv_data;
LOG_FUNC_CALLED(card->ctx);
priv = calloc(1, sizeof(sc_hsm_private_data_t));
if (!priv)
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
card->drv_data = priv;
flags = SC_ALGORITHM_RSA_RAW|SC_ALGORITHM_ONBOARD_KEY_GEN;
_sc_card_add_rsa_alg(card, 1024, flags, 0);
@ -1066,8 +1506,56 @@ static int sc_hsm_init(struct sc_card *card)
card->caps |= SC_CARD_CAP_RNG|SC_CARD_CAP_APDU_EXT|SC_CARD_CAP_ISO7816_PIN_INFO;
sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
if (sc_hsm_select_file_ex(card, &path, 0, &file) == SC_SUCCESS
&& file->prop_attr && file->prop_attr_len >= 5) {
static char card_name[SC_MAX_APDU_BUFFER_SIZE];
u8 type = file->prop_attr[2];
u8 major = file->prop_attr[3];
u8 minor = file->prop_attr[4];
char p00[] = "SmartCard-HSM Applet for JCOP";
char p01[] = "SmartCard-HSM Demo Applet for JCOP";
char *p = "SmartCard-HSM";
switch (type) {
case 0x00:
p = p00;
break;
case 0x01:
p = p01;
break;
default:
break;
}
snprintf(card_name, sizeof card_name, "%s version %u.%u", p, major, minor);
card->name = card_name;
if (file->prop_attr[1] & 0x04) {
card->caps |= SC_CARD_CAP_SESSION_PIN;
}
sc_file_free(file);
}
card->max_send_size = 1431; // 1439 buffer size - 8 byte TLV because of odd ins in UPDATE BINARY
card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit
if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
card->max_recv_size = 0x0630; // SoC Proxy forces this limit
} else {
card->max_recv_size = 0; // Card supports sending with extended length APDU and without limit
}
priv->EF_C_DevAut = NULL;
priv->EF_C_DevAut_len = 0;
#ifdef ENABLE_OPENPACE
EAC_init();
#ifdef _WIN32
expanded_len = ExpandEnvironmentStringsA(CVCDIR, expanded_val, sizeof expanded_val);
if (0 < expanded_len && expanded_len < sizeof expanded_val)
EAC_set_cvc_default_dir(expanded_val);
#else
EAC_set_cvc_default_dir(CVCDIR);
#endif
#endif
return 0;
}
@ -1076,10 +1564,20 @@ static int sc_hsm_init(struct sc_card *card)
static int sc_hsm_finish(sc_card_t * card)
{
sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
sc_sm_stop(card);
if (priv->serialno) {
free(priv->serialno);
}
if (priv->dffcp) {
sc_file_free(priv->dffcp);
}
free(priv->EF_C_DevAut);
free(priv);
#ifdef ENABLE_OPENPACE
EAC_cleanup();
#endif
return SC_SUCCESS;
}

View File

@ -56,10 +56,13 @@
/* Information the driver maintains between calls */
typedef struct sc_hsm_private_data {
const sc_security_env_t *env;
sc_file_t *dffcp;
u8 algorithm;
int noExtLength;
char *serialno;
u8 sopin[8];
u8 *EF_C_DevAut;
size_t EF_C_DevAut_len;
} sc_hsm_private_data_t;

View File

@ -204,6 +204,7 @@ enum {
/* SmartCard-HSM */
SC_CARD_TYPE_SC_HSM = 26000,
SC_CARD_TYPE_SC_HSM_SOC = 26001,
/* Spanish DNIe card */
SC_CARD_TYPE_DNIE_BASE = 27000,

View File

@ -338,7 +338,7 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *
#ifdef _WIN32
expanded_len = PATH_MAX;
expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len);
if (expanded_len > 0)
if (0 < expanded_len && expanded_len < sizeof expanded_val)
val = expanded_val;
#endif
sc_ctx_log_to_file(ctx, val);

View File

@ -999,6 +999,8 @@ iso7816_build_pin_apdu(struct sc_card *card, struct sc_apdu *apdu,
switch (data->pin_type) {
case SC_AC_CHV:
/* fall through */
case SC_AC_SESSION:
break;
default:
return SC_ERROR_INVALID_ARGUMENTS;

View File

@ -342,6 +342,7 @@ typedef struct sc_reader {
#define SC_PIN_CMD_CHANGE 1
#define SC_PIN_CMD_UNBLOCK 2
#define SC_PIN_CMD_GET_INFO 3
#define SC_PIN_CMD_GET_SESSION_PIN 4
#define SC_PIN_CMD_USE_PINPAD 0x0001
#define SC_PIN_CMD_NEED_PADDING 0x0002
@ -475,6 +476,12 @@ struct sc_reader_operations {
#define SC_CARD_CAP_ONLY_RAW_HASH 0x00000040
#define SC_CARD_CAP_ONLY_RAW_HASH_STRIPPED 0x00000080
/* Card (or card driver) supports an protected authentication mechanism */
#define SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH 0x00000100
/* Card (or card driver) supports generating a session PIN */
#define SC_CARD_CAP_SESSION_PIN 0x00000200
typedef struct sc_card {
struct sc_context *ctx;
struct sc_reader *reader;

View File

@ -270,7 +270,9 @@ _validate_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_auth_info *auth_i
return SC_ERROR_BUFFER_TOO_SMALL;
/* if we use pinpad, no more checks are needed */
if (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD && !pinlen)
if ((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
&& !pinlen)
return SC_SUCCESS;
/* If pin is given, make sure it is within limits */
@ -391,7 +393,9 @@ _sc_pkcs15_verify_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *p
data.pin_reference = skey_info->key_reference;
}
if(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD && !pinlen) {
if((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)
&& !pinlen) {
data.flags |= SC_PIN_CMD_USE_PINPAD;
if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
@ -487,7 +491,8 @@ int sc_pkcs15_change_pin(struct sc_pkcs15_card *p15card,
}
if((!oldpin || !newpin)
&& p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
&& (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
data.flags |= SC_PIN_CMD_USE_PINPAD;
if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
data.pin1.prompt = "Please enter SO PIN";
@ -600,7 +605,8 @@ int sc_pkcs15_unblock_pin(struct sc_pkcs15_card *p15card,
break;
}
if(p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
if((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
data.flags |= SC_PIN_CMD_USE_PINPAD;
if (auth_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
data.pin1.prompt = "Please enter PUK";
@ -743,7 +749,8 @@ sc_pkcs15_pincache_revalidate(struct sc_pkcs15_card *p15card, const sc_pkcs15_ob
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
}
if (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
if ((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH))
return SC_ERROR_SECURITY_STATUS_NOT_SATISFIED;
r = sc_pkcs15_find_pin_by_auth_id(p15card, &obj->auth_id, &pin_obj);

View File

@ -181,7 +181,7 @@ static const struct sc_asn1_entry c_asn1_req[C_ASN1_REQ_SIZE] = {
static int read_file(sc_pkcs15_card_t * p15card, u8 fid[2],
u8 *efbin, size_t *len)
u8 *efbin, size_t *len, int optional)
{
sc_path_t path;
int r;
@ -196,12 +196,24 @@ static int read_file(sc_pkcs15_card_t * p15card, u8 fid[2],
/* avoid re-selection of SC-HSM */
path.aid.len = 0;
r = sc_select_file(p15card->card, &path, NULL);
LOG_TEST_RET(p15card->card->ctx, r, "Could not select EF");
if (r < 0) {
sc_log(p15card->card->ctx, "Could not select EF");
} else {
r = sc_read_binary(p15card->card, 0, efbin, *len, 0);
}
r = sc_read_binary(p15card->card, 0, efbin, *len, 0);
LOG_TEST_RET(p15card->card->ctx, r, "Could not read EF");
*len = r;
if (r < 0) {
sc_log(p15card->card->ctx, "Could not read EF");
if (!optional) {
return r;
}
/* optional files are saved as empty files to avoid card
* transactions. Parsing the file's data will reveal that they were
* missing. */
*len = 0;
} else {
*len = r;
}
if (p15card->opts.use_file_cache) {
/* save this with our AID */
@ -593,7 +605,7 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) {
/* Try to select a related EF containing the PKCS#15 description of the key */
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len);
r = read_file(p15card, fid, efbin, &len, 1);
LOG_TEST_RET(card->ctx, r, "Could not read EF.PRKD");
ptr = efbin;
@ -627,7 +639,8 @@ static int sc_pkcs15emu_sc_hsm_add_prkd(sc_pkcs15_card_t * p15card, u8 keyid) {
fid[0] = EE_CERTIFICATE_PREFIX;
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len);
r = read_file(p15card, fid, efbin, &len, 0);
LOG_TEST_RET(card->ctx, r, "Could not read EF");
LOG_TEST_RET(card->ctx, r, "Could not read EF");
@ -683,7 +696,7 @@ static int sc_pkcs15emu_sc_hsm_add_dcod(sc_pkcs15_card_t * p15card, u8 id) {
/* Try to select a related EF containing the PKCS#15 description of the data */
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len);
r = read_file(p15card, fid, efbin, &len, 1);
LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD");
ptr = efbin;
@ -722,7 +735,7 @@ static int sc_pkcs15emu_sc_hsm_add_cd(sc_pkcs15_card_t * p15card, u8 id) {
/* Try to select a related EF containing the PKCS#15 description of the data */
len = sizeof efbin;
r = read_file(p15card, fid, efbin, &len);
r = read_file(p15card, fid, efbin, &len, 1);
LOG_TEST_RET(card->ctx, r, "Could not read EF.DCOD");
ptr = efbin;
@ -753,7 +766,7 @@ static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
/* Read token info */
len = sizeof efbin;
r = read_file(p15card, (u8 *) "\x2F\x03", efbin, &len);
r = read_file(p15card, (u8 *) "\x2F\x03", efbin, &len, 1);
LOG_TEST_RET(card->ctx, r, "Could not read EF.TokenInfo");
r = sc_pkcs15_parse_tokeninfo(card->ctx, p15card->tokeninfo, efbin, len);
@ -771,6 +784,7 @@ static int sc_pkcs15emu_sc_hsm_read_tokeninfo (sc_pkcs15_card_t * p15card)
static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
{
sc_card_t *card = p15card->card;
sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
sc_file_t *file = NULL;
sc_path_t path;
u8 filelist[MAX_EXT_APDU_LENGTH];
@ -780,7 +794,8 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
struct sc_app_info *appinfo;
struct sc_pkcs15_auth_info pin_info;
struct sc_pkcs15_object pin_obj;
u8 efbin[512];
struct sc_pin_cmd_data pindata;
u8 efbin[1024];
u8 *ptr;
size_t len;
@ -809,11 +824,24 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
sc_file_free(file);
/* Read device certificate to determine serial number */
len = sizeof efbin;
r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len);
LOG_TEST_RET(card->ctx, r, "Could not select EF.C_DevAut");
if (priv->EF_C_DevAut && priv->EF_C_DevAut_len) {
ptr = priv->EF_C_DevAut;
len = priv->EF_C_DevAut_len;
} else {
len = sizeof efbin;
r = read_file(p15card, (u8 *) "\x2F\x02", efbin, &len, 1);
LOG_TEST_RET(card->ctx, r, "Could not select EF.C_DevAut");
ptr = efbin;
/* save EF_C_DevAut for further use */
ptr = realloc(priv->EF_C_DevAut, len);
if (ptr) {
memcpy(ptr, efbin, len);
priv->EF_C_DevAut = ptr;
priv->EF_C_DevAut_len = len;
}
ptr = efbin;
}
memset(&devcert, 0 ,sizeof(devcert));
r = sc_pkcs15emu_sc_hsm_decode_cvc(p15card, (const u8 **)&ptr, &len, &devcert);
@ -883,7 +911,6 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
if (r < 0)
LOG_FUNC_RETURN(card->ctx, r);
memset(&pin_info, 0, sizeof(pin_info));
memset(&pin_obj, 0, sizeof(pin_obj));
@ -909,6 +936,30 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
LOG_FUNC_RETURN(card->ctx, r);
if (card->type == SC_CARD_TYPE_SC_HSM_SOC) {
/* SC-HSM of this type always has a PIN-Pad */
r = SC_SUCCESS;
} else {
memset(&pindata, 0, sizeof(pindata));
pindata.cmd = SC_PIN_CMD_GET_INFO;
pindata.pin_type = SC_AC_CHV;
pindata.pin_reference = 0x85;
r = sc_pin_cmd(card, &pindata, NULL);
}
if (r == SC_ERROR_DATA_OBJECT_NOT_FOUND) {
memset(&pindata, 0, sizeof(pindata));
pindata.cmd = SC_PIN_CMD_GET_INFO;
pindata.pin_type = SC_AC_CHV;
pindata.pin_reference = 0x86;
r = sc_pin_cmd(card, &pindata, NULL);
}
if (r != SC_ERROR_DATA_OBJECT_NOT_FOUND)
card->caps |= SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;
filelistlength = sc_list_files(card, filelist, sizeof(filelist));
LOG_TEST_RET(card->ctx, filelistlength, "Could not enumerate file and key identifier");
@ -941,7 +992,8 @@ int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card,
if (opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
return sc_pkcs15emu_sc_hsm_init(p15card);
} else {
if (p15card->card->type != SC_CARD_TYPE_SC_HSM) {
if (p15card->card->type != SC_CARD_TYPE_SC_HSM
&& p15card->card->type != SC_CARD_TYPE_SC_HSM_SOC) {
return SC_ERROR_WRONG_CARD;
}
return sc_pkcs15emu_sc_hsm_init(p15card);

View File

@ -82,6 +82,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
case SC_CARD_TYPE_OPENPGP_V2:
case SC_CARD_TYPE_OPENPGP_GNUK:
case SC_CARD_TYPE_SC_HSM:
case SC_CARD_TYPE_SC_HSM_SOC:
case SC_CARD_TYPE_DNIE_BASE:
case SC_CARD_TYPE_DNIE_BLANK:
case SC_CARD_TYPE_DNIE_ADMIN:

View File

@ -148,6 +148,7 @@ struct sc_crt {
#define SC_AC_SEN 0x00000020 /* Security Environment. */
#define SC_AC_SCB 0x00000040 /* IAS/ECC SCB byte. */
#define SC_AC_IDA 0x00000080 /* PKCS#15 authentication ID */
#define SC_AC_SESSION 0x00000100 /* Session PIN */
#define SC_AC_UNKNOWN 0xFFFFFFFE
#define SC_AC_NEVER 0xFFFFFFFF

View File

@ -14,5 +14,5 @@ $(TARGET): $(OBJECTS) $(LIBS)
echo LIBRARY $* > $*.def
echo EXPORTS >> $*.def
type minidriver.exports >> $*.def
link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll
link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib bcrypt.lib DelayImp.lib Rpcrt4.lib /DELAYLOAD:bcrypt.dll
if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2

View File

@ -4774,7 +4774,8 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
return SCARD_F_INTERNAL_ERROR;
if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN || dwFlags == CARD_AUTHENTICATE_SESSION_PIN) {
if (! (vs->reader->capabilities & SC_READER_CAP_PIN_PAD))
if (! (vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH))
return SCARD_E_UNSUPPORTED_FEATURE;
}
@ -4783,7 +4784,8 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
/* using a pin pad */
if (NULL == pbPinData) {
if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD))
if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH))
return SCARD_E_INVALID_PARAMETER;
if (!(dwFlags & CARD_PIN_SILENT_CONTEXT)
&& !(vs->ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS)) {
@ -4809,7 +4811,9 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
/* Do we need to display a prompt to enter PIN on pin pad? */
logprintf(pCardData, 7, "PIN pad=%s, pbPinData=%p, hwndParent=%p\n",
vs->reader->capabilities & SC_READER_CAP_PIN_PAD ? "yes" : "no", pbPinData, vs->hwndParent);
vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH
? "yes" : "no", pbPinData, vs->hwndParent);
/* check if the pin is the session pin generated by a previous authentication with a pinpad */
if (pbPinData != NULL && cbPinData == sizeof(MAGIC_SESSION_PIN) && memcmp(MAGIC_SESSION_PIN, pbPinData, sizeof(MAGIC_SESSION_PIN)) == 0) {
@ -4836,7 +4840,9 @@ DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
logprintf(pCardData, 2, "Pin code correct.\n");
/* set the session pin according to the minidriver specification */
if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN && (vs->reader->capabilities & SC_READER_CAP_PIN_PAD)) {
if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN
&& (vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* we set it to a special value for pinpad authentication to force a new pinpad authentication */
if (pcbSessionPin) *pcbSessionPin = sizeof(MAGIC_SESSION_PIN);
if (ppbSessionPin) {
@ -4907,7 +4913,8 @@ DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD)) {
if (!(vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
if (pbAuthenticatingPinData == NULL || cbAuthenticatingPinData == 0) {
logprintf(pCardData, 1, "Invalid current PIN data\n");
return SCARD_E_INVALID_PARAMETER;
@ -5192,7 +5199,9 @@ DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
if (p->dwVersion != PIN_INFO_CURRENT_VERSION)
return ERROR_REVISION_MISMATCH;
p->PinType = vs->reader->capabilities & SC_READER_CAP_PIN_PAD ? ExternalPinType : AlphaNumericPinType;
p->PinType = vs->reader->capabilities & SC_READER_CAP_PIN_PAD
|| vs->p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH
? ExternalPinType : AlphaNumericPinType;
p->dwFlags = 0;
switch (dwFlags) {
case ROLE_USER:

View File

@ -17,15 +17,15 @@ all: $(TARGET1) $(TARGET2) $(TARGET3)
!INCLUDE $(TOPDIR)\win32\Make.rules.mak
$(TARGET1): $(OBJECTS) $(LIBS)
link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib
link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET1) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib
if EXIST $(TARGET1).manifest mt -manifest $(TARGET1).manifest -outputresource:$(TARGET1);2
$(TARGET2): $(OBJECTS) $(LIBS)
del pkcs11-global.obj
cl $(CODE_OPTIMIZATION) $(COPTS) /DMODULE_APP_NAME=\"onepin-opensc-pkcs11\" /c pkcs11-global.c
link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENSSL_LIB) gdi32.lib
link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET2) $(OBJECTS) $(LIBS) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib
if EXIST $(TARGET2).manifest mt -manifest $(TARGET2).manifest -outputresource:$(TARGET2);2
$(TARGET3): $(OBJECTS3) $(LIBS3)
link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENSSL_LIB) gdi32.lib advapi32.lib
link $(LINKFLAGS) /dll /implib:$*.lib /out:$(TARGET3) $(OBJECTS3) $(LIBS3) $(OPENPACE_LIB) $(OPENSSL_LIB) gdi32.lib advapi32.lib
if EXIST $(TARGET3).manifest mt -manifest $(TARGET3).manifest -outputresource:$(TARGET3);2

View File

@ -961,7 +961,7 @@ pkcs15_init_slot(struct sc_pkcs15_card *p15card, struct sc_pkcs11_slot *slot,
if (auth != NULL)
slot->token_info.flags |= CKF_USER_PIN_INITIALIZED;
if (p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
if ((p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) || (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH))
slot->token_info.flags |= CKF_PROTECTED_AUTHENTICATION_PATH;
if (p15card->card->caps & SC_CARD_CAP_RNG && p15card->card->ops->get_challenge != NULL)
@ -1489,7 +1489,8 @@ pkcs15_login(struct sc_pkcs11_slot *slot, CK_USER_TYPE userType,
if (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
return CKR_FUNCTION_REJECTED;
if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* pPin should be NULL in case of a pin pad reader, but
* some apps (e.g. older Netscapes) don't know about it.
* So we don't require that pPin == NULL, but set it to
@ -1650,7 +1651,8 @@ pkcs15_change_pin(struct sc_pkcs11_slot *slot,
return CKR_USER_PIN_NOT_INITIALIZED;
sc_log(context, "Change '%.*s' (ref:%i,type:%i)", (int) sizeof pin_obj->label, pin_obj->label, auth_info->attrs.pin.reference, login_user);
if (p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
if ((p11card->card->reader->capabilities & SC_READER_CAP_PIN_PAD)
|| (p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH)) {
/* pPin should be NULL in case of a pin pad reader, but
* some apps (e.g. older Netscapes) don't know about it.
* So we don't require that pPin == NULL, but set it to

View File

@ -1762,13 +1762,11 @@ int perform_chip_authentication(sc_card_t *card,
unsigned char **ef_cardsecurity, size_t *ef_cardsecurity_len)
{
int r;
BUF_MEM *picc_pubkey = NULL, *nonce = NULL, *token = NULL,
*eph_pub_key = NULL;
BUF_MEM *picc_pubkey = NULL;
struct iso_sm_ctx *isosmctx;
struct npa_sm_ctx *eacsmctx;
if (!card || !card->sm_ctx.info.cmd_data
|| !ef_cardsecurity || !ef_cardsecurity_len) {
if (!card || !ef_cardsecurity || !ef_cardsecurity_len) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
@ -1779,7 +1777,6 @@ int perform_chip_authentication(sc_card_t *card,
}
eacsmctx = isosmctx->priv_data;
/* Passive Authentication */
if (!*ef_cardsecurity && !*ef_cardsecurity_len) {
r = get_ef_card_security(card, ef_cardsecurity, ef_cardsecurity_len);
@ -1796,8 +1793,42 @@ int perform_chip_authentication(sc_card_t *card,
goto err;
}
r = perform_chip_authentication_ex(card, eacsmctx->ctx,
(unsigned char *) picc_pubkey->data, picc_pubkey->length);
r = npa_mse_set_at_ca(card, eacsmctx->ctx->ca_ctx->protocol);
err:
BUF_MEM_clear_free(picc_pubkey);
if (card)
SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r);
else
return r;
}
int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx,
unsigned char *picc_pubkey, size_t picc_pubkey_len)
{
int r;
BUF_MEM *picc_pubkey_buf = NULL, *nonce = NULL, *token = NULL,
*eph_pub_key = NULL;
EAC_CTX *ctx = eac_ctx;
if (!card || !ctx) {
r = SC_ERROR_INVALID_ARGUMENTS;
goto err;
}
picc_pubkey_buf = BUF_MEM_create_init(picc_pubkey, picc_pubkey_len);
if (!picc_pubkey_buf) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not verify EF.CardSecurity.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
r = npa_mse_set_at_ca(card, ctx->ca_ctx->protocol);
if (r < 0) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not select protocol proberties "
"(MSE: Set AT failed).");
@ -1805,7 +1836,7 @@ int perform_chip_authentication(sc_card_t *card,
}
eph_pub_key = CA_STEP2_get_eph_pubkey(eacsmctx->ctx);
eph_pub_key = CA_STEP2_get_eph_pubkey(ctx);
if (!eph_pub_key) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not derive keys.");
ssl_error(card->ctx);
@ -1819,7 +1850,7 @@ int perform_chip_authentication(sc_card_t *card,
}
if (!CA_STEP4_compute_shared_secret(eacsmctx->ctx, picc_pubkey)) {
if (!CA_STEP4_compute_shared_secret(ctx, picc_pubkey_buf)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not compute shared secret.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
@ -1827,7 +1858,7 @@ int perform_chip_authentication(sc_card_t *card,
}
if (!CA_STEP6_derive_keys(eacsmctx->ctx, nonce, token)) {
if (!CA_STEP6_derive_keys(ctx, nonce, token)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not derive keys.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
@ -1836,15 +1867,19 @@ int perform_chip_authentication(sc_card_t *card,
/* Initialize secure channel */
if (!EAC_CTX_set_encryption_ctx(eacsmctx->ctx, EAC_ID_CA)) {
if (!EAC_CTX_set_encryption_ctx(ctx, EAC_ID_CA)) {
sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Could not initialize encryption.");
ssl_error(card->ctx);
r = SC_ERROR_INTERNAL;
goto err;
}
if (card->sm_ctx.sm_mode != SM_MODE_TRANSMIT) {
r = npa_sm_start(card, ctx, NULL, 0, NULL, 0);
}
err:
BUF_MEM_clear_free(picc_pubkey);
BUF_MEM_clear_free(picc_pubkey_buf);
BUF_MEM_clear_free(nonce);
BUF_MEM_clear_free(token);
BUF_MEM_clear_free(eph_pub_key);
@ -2371,6 +2406,12 @@ int perform_chip_authentication(sc_card_t *card,
return SC_ERROR_NOT_SUPPORTED;
}
int perform_chip_authentication_ex(sc_card_t *card, void *eac_ctx,
unsigned char *picc_pubkey, size_t picc_pubkey_len)
{
return SC_ERROR_NOT_SUPPORTED;
}
#endif
static const char *MRZ_name = "MRZ";

View File

@ -230,6 +230,8 @@ int perform_terminal_authentication(sc_card_t *card,
*/
int perform_chip_authentication(sc_card_t *card,
unsigned char **ef_cardsecurity, size_t *ef_cardsecurity_len);
int perform_chip_authentication_ex(sc_card_t *card, void *eacsmctx,
unsigned char *picc_pubkey, size_t picc_pubkey_len);
/**
* @brief Sends a reset retry counter APDU

View File

@ -14,7 +14,7 @@ $(TARGET): $(OBJECTS) $(LIBS)
echo LIBRARY $* > $*.def
echo EXPORTS >> $*.def
type $*.exports >> $*.def
link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib
link /dll $(LINKFLAGS) /def:$*.def /out:$(TARGET) $(OBJECTS) $(LIBS) $(ZLIB_LIB) $(OPENPACE_LIB) $(OPENSSL_LIB) ws2_32.lib gdi32.lib advapi32.lib Crypt32.lib User32.lib
if EXIST $(TARGET).manifest mt -manifest $(TARGET).manifest -outputresource:$(TARGET);2
!ELSE

View File

@ -486,7 +486,7 @@ main (int argc, char **argv)
} else if (cmdline.puk_given) {
pace_input.pin_id = PACE_PUK;
pace_input.pin_length = 10;
maxsecret = 9999999999LLU;
maxsecret = 9999999999;
if (puk) {
if (sscanf(puk, "%llu", &secret) != 1) {
fprintf(stderr, "%s is not an unsigned long long.\n",

View File

@ -1541,7 +1541,8 @@ static int unblock_pin(void)
u8 *pin, *puk;
int r, pinpad_present = 0;
pinpad_present = p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD;
pinpad_present = p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;
if (!(pin_obj = get_pin_info()))
return 2;
@ -1638,7 +1639,8 @@ static int change_pin(void)
u8 *pincode, *newpin;
int r, pinpad_present = 0;
pinpad_present = p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD;
pinpad_present = p15card->card->reader->capabilities & SC_READER_CAP_PIN_PAD
|| p15card->card->caps & SC_CARD_CAP_PROTECTED_AUTHENTICATION_PATH;
if (!(pin_obj = get_pin_info()))
return 2;

View File

@ -80,9 +80,10 @@ CANDLEFLAGS = -dzlib="C:\zlib-dll" $(CANDLEFLAGS)
# - set the OPENPACE_LIB below to your OpenPACE lib file
#OPENPACE_DEF= /DENABLE_OPENPACE
!IF "$(OPENPACE_DEF)" == "/DENABLE_OPENPACE"
OPENPACE_DIR = C:\OpenPACE
OPENPACE_INCL_DIR = /I$(OPENPACE_DIR)\include
OPENPACE_LIB = $(OPENPACE_DIR)\lib\libeac.lib
OPENPACE_DIR = C:\openpace
OPENPACE_INCL_DIR = /I$(OPENPACE_DIR)\src
OPENPACE_LIB = $(OPENPACE_DIR)\src\libeac.lib
CANDLEFLAGS = -dOpenPACE="$(OPENPACE_DIR)" $(CANDLEFLAGS)
!ENDIF

View File

@ -280,6 +280,16 @@
</Component>
</Directory>
<?endif ?>
<?ifdef OpenPACE ?>
<Directory Id="INSTALLDIR_CVC" Name="cvc">
<Component Id="UTSRCACC100001" Guid="*" Win64="$(var.Win64YesNo)">
<File Source="$(var.SOURCE_DIR)\etc\UTSRCACC100001"/>
</Component>
<Component Id="DESRCACC100001" Guid="*" Win64="$(var.Win64YesNo)">
<File Source="$(var.SOURCE_DIR)\etc\DESRCACC100001"/>
</Component>
</Directory>
<?endif ?>
</Directory>
</Directory>
</Directory>
@ -304,6 +314,10 @@
<?ifdef OpenSSL ?>
<ComponentRef Id="smm_local.dll"/>
<?endif ?>
<?ifdef OpenPACE ?>
<ComponentRef Id="UTSRCACC100001"/>
<ComponentRef Id="DESRCACC100001"/>
<?endif ?>
</Feature>
<Feature Id="OpenSC_pkcs11" Level="1" Title="OpenSC PKCS#11 module" Description="PKCS#11 module usd by most open source and cross-platform software (like Firefox, Putty, TrueCrypt, OpenVPN etc)" TypicalDefault="install">
<ComponentRef Id="opensc_pkcs11.dll"/>

View File

@ -74,6 +74,8 @@ MD_REGISTRATION minidriver_registration[] = {
24, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}},
{TEXT("SmartCard-HSM-CL"), {0x3B,0x8E,0x80,0x01,0x80,0x31,0x81,0x54,0x48,0x53,0x4D,0x31,0x73,0x80,0x21,0x40,0x81,0x07,0x18},
19, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff}},
{TEXT("SmartCard-HSM-FP"), {0x3B,0x80,0x80,0x01,0x01},
5, {0xff,0xff,0xff,0xff,0xff}},
/* from minidriver-westcos.reg */
{TEXT("CEV WESTCOS"), {0x3f,0x69,0x00,0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x80,0x90,0x00},
13, {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0xf0,0xff,0xff}},

View File

@ -118,6 +118,10 @@
#define OPENSC_VS_FF_PRODUCT_NAME "@OPENSC_VS_FF_PRODUCT_NAME@"
#endif
#ifndef CVCDIR
#define CVCDIR "%PROGRAMFILES%\\OpenSC Project\\OpenSC\\cvc"
#endif
#ifndef DEFAULT_PKCS11_PROVIDER
#define DEFAULT_PKCS11_PROVIDER "@DEFAULT_PKCS11_PROVIDER@"
#endif