Merge branch 'towards-opensc-0.16.0'
version.m4 updated for official release 0.16.0 coverity scan switched to 'master'
This commit is contained in:
commit
7eeba1fba8
|
@ -72,6 +72,7 @@ doc/tools/pkcs15-tool
|
|||
doc/tools/sc-hsm-tool
|
||||
doc/tools/westcos-tool
|
||||
doc/tools/dnie-tool
|
||||
doc/tools/gids-tool
|
||||
|
||||
etc/opensc.conf.win
|
||||
etc/opensc.conf
|
||||
|
@ -95,6 +96,7 @@ src/tools/cryptoflex-tool
|
|||
src/tools/netkey-tool
|
||||
src/tools/pkcs11-tool
|
||||
src/tools/dnie-tool
|
||||
src/tools/gids-tool
|
||||
|
||||
win32/OpenSC.iss
|
||||
win32/OpenSC.wxs
|
||||
|
|
|
@ -15,17 +15,30 @@ SDKS_PATH="$(xcode-select -p)/Platforms/MacOSX.platform/Developer/SDKs"
|
|||
SDK_PATH="${SDK_PATH:-$SDKS_PATH/$(ls -1 ${SDKS_PATH} | sort -n -k2 -t. -r | head -1)}"
|
||||
|
||||
# Set SDK path
|
||||
export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch i386 -arch x86_64 -mmacosx-version-min=10.10"
|
||||
|
||||
# OpenSSL is deprecated on OSX since 10.7 and that generates lots of
|
||||
# "false positive" warnings and there is no alternative option.
|
||||
# Just ignore these warning for now by silencing them.
|
||||
CFLAGS="$CFLAGS -Wno-deprecated-declarations"
|
||||
export CFLAGS="$CFLAGS -isysroot $SDK_PATH -arch x86_64 -mmacosx-version-min=10.10"
|
||||
|
||||
export SED=/usr/bin/sed
|
||||
PREFIX=/Library/OpenSC
|
||||
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
|
||||
|
||||
if ! pkg-config libcrypto --atleast-version=1.0.1; then
|
||||
# OpenSSL is not installed
|
||||
if ! test -e $BUILDPATH/openssl_bin/lib/pkgconfig; then
|
||||
# Build OpenSSL manually, because Apple's binaries are deprecated
|
||||
if ! test -e openssl; then
|
||||
git clone --depth=1 https://github.com/openssl/openssl.git -b OpenSSL_1_0_2-stable
|
||||
fi
|
||||
cd openssl
|
||||
KERNEL_BITS=64 ./config --prefix=$PREFIX -mmacosx-version-min=10.10
|
||||
make clean update depend
|
||||
make
|
||||
make INSTALL_PREFIX=$BUILDPATH/openssl_bin install_sw
|
||||
cd ..
|
||||
fi
|
||||
export OPENSSL_CFLAGS="`env PKG_CONFIG_PATH=$BUILDPATH/openssl_bin/$PREFIX/lib/pkgconfig PKG_CONFIG_SYSROOT_DIR=$BUILDPATH/openssl_bin pkg-config --static --cflags libcrypto`"
|
||||
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
|
||||
|
||||
./configure --prefix=$PREFIX \
|
||||
--sysconfdir=$PREFIX/etc \
|
||||
--disable-dependency-tracking \
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
|
||||
<p>OpenSC provides a set of libraries and utilities to work with smart cards. Its main focus is on cards that support cryptographic operations, and facilitate their use in security applications such as authentication, mail encryption and digital signatures.</p>
|
||||
|
||||
<p>OpenSC implements the <a href="http://www.rsa.com/rsalabs/node.asp?id=2133">PKCS#11 API</a> so applications supporting this API (such as Mozilla Firefox and Thunderbird) can use it. On the card OpenSC implements the <a href="http://www.rsa.com/rsalabs/node.asp?id=2141">PKCS#15</a> standard and aims to be compatible with every software/card that does so, too.</p>
|
||||
<p>OpenSC implements the <a href="https://www.oasis-open.org/committees/pkcs11/">PKCS#11 API</a> so applications supporting this API (such as Mozilla Firefox and Thunderbird) can use it. On the card OpenSC implements the <a href="http://www.emc.com/emc-plus/rsa-labs/standards-initiatives/pkcs-15-cryptographic-token-information-format.htm">PKCS#15</a> standard and aims to be compatible with every software/card that does so, too.</p>
|
||||
|
||||
<h2>Documentation:</h2>
|
||||
<p>The OpenSC Wiki is available at: <a href="http://www.opensc-project.org/opensc">http://www.opensc-project.org/opensc</a> and should be consulted for further documentation and support.</p>
|
||||
<p>The OpenSC Wiki is available at: <a href="https://github.com/OpenSC/OpenSC/wiki">https://github.com/OpenSC/OpenSC/wiki</a> and should be consulted for further documentation and support.</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
|
81
NEWS
81
NEWS
|
@ -1,4 +1,85 @@
|
|||
NEWS for OpenSC -- History of user visible changes
|
||||
New in 0.16.0; 2016-05-15
|
||||
* build
|
||||
link OpenSSL in static
|
||||
option: enable PKCS11 thread locking
|
||||
* configuration
|
||||
use one configuration file for all systems
|
||||
* tools:
|
||||
package revision as version
|
||||
** pkcs11-tool
|
||||
keygen mechanism in pkcs11 tools
|
||||
write GOST public key
|
||||
fix CKA_SENSITIVE attribute of public keys
|
||||
** opensc-explorer:
|
||||
added command find_tags
|
||||
allow ASN.1 decoding if the file seems incomplete
|
||||
** pkcs15-tool:
|
||||
handle record-based files when doing file caching
|
||||
option to prine raw data
|
||||
** sc-hsm-tool:
|
||||
status info support for SmartCard-HSM V2.0
|
||||
** doc: some missing options are documented, added documentation
|
||||
for gid tool
|
||||
* minidriver:
|
||||
support for ECC
|
||||
Windows x509 enrollment
|
||||
first implementation of CardDeleteContainer
|
||||
MD logs controlled by register and environment variable
|
||||
* reader-pcsc
|
||||
fixed unreleased locks with pcsc-lite
|
||||
honour PC/SC pt 10 dwMaxAPDUDataSize
|
||||
added call back for getting vendor/product id
|
||||
restrict access to card handles after fork
|
||||
SCardGetAttrib is used to initialize reader's metadata
|
||||
by default only short APDUs supported
|
||||
* pkcs11
|
||||
no slot reserved for hot plug
|
||||
no more slot created 'per-applications'
|
||||
atomic operation (TODO: expand)
|
||||
export all C_* symbols
|
||||
metadata initialized from package info
|
||||
fix registering pkcs11 mechanisms multiple times
|
||||
sloppy initialization for C_GetSlotInfo
|
||||
* pkcs15
|
||||
cache of on-card files extended to application paths
|
||||
configuration option to enable/disable application
|
||||
make file cache dir configurable
|
||||
in key info data type introduced 'auxiliary data' -- container
|
||||
for the non-pkc15 data.
|
||||
* OpenPGP
|
||||
support for Gnuk -- USB cryptographic token for GNU Privacy Guard
|
||||
build without OpenSSL
|
||||
implemented 'erase card'
|
||||
additional manufacturers
|
||||
* MyEID
|
||||
support for 521 bit ECC keys
|
||||
ATRs for the new cards
|
||||
* sc-hsm
|
||||
read/write support in minidriver
|
||||
* rtecp
|
||||
delete keys
|
||||
* GemSafeV1
|
||||
support for European Patent Office smart card
|
||||
sign with SHA256
|
||||
* Gids
|
||||
first support for Gids smart card
|
||||
* dnie
|
||||
* Feitian PKI card
|
||||
new ATRs
|
||||
* IsoApplet
|
||||
(fixes)
|
||||
* starcos
|
||||
initial support for STARCOS 3.4 (German D-Trust cards)
|
||||
* macosx
|
||||
install tokend to /Library/Security/ instead /System/Library/Security/
|
||||
fixed locking issue in pcsc reader
|
||||
* PIV
|
||||
allow using of cards where default application in not PIV
|
||||
support for the Yubikey NEO
|
||||
* italian-CNS
|
||||
italian-cns reg file for minidriver
|
||||
|
||||
New in 0.15.0; 2015-05-11
|
||||
* new card drivers
|
||||
AzeDIT 3.5
|
||||
|
|
33
appveyor.yml
33
appveyor.yml
|
@ -1,4 +1,10 @@
|
|||
version: 0.15.0.{build}
|
||||
version: 0.16.0.{build}
|
||||
|
||||
#init:
|
||||
# # Exclude combinations allowed to fail
|
||||
# - if "%Environment%" == "VSVER=14" (if "%Configuration%" == "Release" (exit /b 1))
|
||||
# - if "%Environment%" == "VSVER=14" (if "%Configuration%" == "Debug" (exit /b 1))
|
||||
# - if "%Environment%" == "VSVER=10" (if "%Platform%" == "x64" (exit /b 1))
|
||||
|
||||
platform:
|
||||
- x86
|
||||
|
@ -12,11 +18,12 @@ configuration:
|
|||
|
||||
environment:
|
||||
matrix:
|
||||
- VSVER: 14
|
||||
# - VSVER: 14
|
||||
- VSVER: 12
|
||||
- VSVER: 10
|
||||
# - VSVER: 10
|
||||
|
||||
matrix:
|
||||
fast_finish: true # set this flag to immediately finish build once one of the jobs fails.
|
||||
allow_failures:
|
||||
# not included in AppVeyor right now
|
||||
- platform: x64
|
||||
|
@ -38,19 +45,20 @@ install:
|
|||
- set OPENSSL_VER=1_0_2e
|
||||
- set ZLIB_VER=128
|
||||
- set ZLIB_VER_DOT=1.2.8
|
||||
- ps: $env:PACKAGE_NAME=(git describe --tags)
|
||||
- ps: >-
|
||||
If ($env:Platform -Match "x86") {
|
||||
$env:VCVARS_PLATFORM="x86"
|
||||
$env:ENV_PLATFORM="x86"
|
||||
$env:OPENSSL_PF="Win32"
|
||||
$env:NMAKE_ARCH=""
|
||||
$env:ARTIFACT="OpenSC-${env:APPVEYOR_BUILD_VERSION}-win32_vs${env:VSVER}-${env:CONFIGURATION}.msi"
|
||||
$env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}-win32_vs${env:VSVER}-${env:CONFIGURATION}.msi"
|
||||
} Else {
|
||||
$env:VCVARS_PLATFORM="amd64"
|
||||
$env:ENV_PLATFORM="x64"
|
||||
$env:OPENSSL_PF="Win64"
|
||||
$env:NMAKE_ARCH="BUILD_ON=WIN64 BUILD_FOR=WIN64"
|
||||
$env:ARTIFACT="OpenSC-${env:APPVEYOR_BUILD_VERSION}-win64_vs${env:VSVER}-${env:CONFIGURATION}.msi"
|
||||
$env:ARTIFACT="OpenSC-${env:PACKAGE_NAME}-win64_vs${env:VSVER}-${env:CONFIGURATION}.msi"
|
||||
}
|
||||
- ps: >-
|
||||
If ($env:Configuration -Like "*Debug*") {
|
||||
|
@ -75,6 +83,7 @@ install:
|
|||
- appveyor DownloadFile "http://download.microsoft.com/download/2/C/9/2C93059C-0532-42DF-8C24-9AEAFF00768E/cngsdk.msi"
|
||||
- cngsdk.msi /quiet
|
||||
- uname -a
|
||||
- set
|
||||
|
||||
build_script:
|
||||
# build zlib.lib as a static library
|
||||
|
@ -108,3 +117,17 @@ cache:
|
|||
- C:\OpenSSL-Win32 -> appveyor.yml
|
||||
- C:\OpenSSL-Win64 -> appveyor.yml
|
||||
- zlib.zip -> appveyor.yml
|
||||
|
||||
deploy:
|
||||
- provider: GitHub
|
||||
tag: $(APPVEYOR_REPO_TAG_NAME)
|
||||
release: OpenSC-$(APPVEYOR_REPO_TAG_NAME)
|
||||
description: 'release OpenSC $(APPVEYOR_REPO_TAG_NAME)'
|
||||
auth_token:
|
||||
secure: NGaTqWohBQa7fgE62rEm2sp9jkv6S9FRc3YEi3T5CpaoyIY6K89FJjqzaoPLr8vj
|
||||
artifact: /OpenSC-.*\.msi/
|
||||
draft: false
|
||||
prerelease: true
|
||||
on:
|
||||
branch: /0.16.0-rc.*/ # here branch is release tag
|
||||
appveyor_repo_tag: true # deploy on tag push only
|
||||
|
|
23
configure.ac
23
configure.ac
|
@ -6,7 +6,7 @@ define([PRODUCT_NAME], [OpenSC])
|
|||
define([PRODUCT_TARNAME], [opensc])
|
||||
define([PRODUCT_BUGREPORT], [https://github.com/OpenSC/OpenSC/issues])
|
||||
define([PACKAGE_VERSION_MAJOR], [0])
|
||||
define([PACKAGE_VERSION_MINOR], [15])
|
||||
define([PACKAGE_VERSION_MINOR], [16])
|
||||
define([PACKAGE_VERSION_FIX], [0])
|
||||
define([PACKAGE_SUFFIX], [])
|
||||
|
||||
|
@ -224,6 +224,13 @@ AC_ARG_ENABLE(
|
|||
[enable_dnie_ui="no"]
|
||||
)
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[werror-declaration-after-statement],
|
||||
[AS_HELP_STRING([--disable-werror-declaration-after-statement],[disable -Werror 'declaration-after-statement' @<:@enabled@:>@])],
|
||||
,
|
||||
[werror_declaration_after_statement="yes"]
|
||||
)
|
||||
|
||||
AC_ARG_WITH(
|
||||
[xsl-stylesheetsdir],
|
||||
[AS_HELP_STRING([--with-xsl-stylesheetsdir=PATH],[docbook xsl-stylesheets for svn build @<:@detect@:>@])],
|
||||
|
@ -244,6 +251,7 @@ AC_ARG_WITH(
|
|||
,
|
||||
[with_pkcs11_provider="detect"]
|
||||
)
|
||||
|
||||
dnl ./configure check
|
||||
reader_count=""
|
||||
for rdriver in "${enable_pcsc}" "${enable_openct}" "${enable_ctapi}"; do
|
||||
|
@ -549,10 +557,6 @@ if test "${enable_sm}" = "yes"; then
|
|||
*-mingw*|*-winnt*|*-cygwin*)
|
||||
DEFAULT_SM_MODULE_PATH="\# module_path = \"\";"
|
||||
;;
|
||||
*-apple-*)
|
||||
DEFAULT_SM_MODULE="libsmm-local.dylib"
|
||||
DEFAULT_SM_MODULE_PATH="module_path = \$(libdir);"
|
||||
;;
|
||||
*)
|
||||
DEFAULT_SM_MODULE="libsmm-local.so"
|
||||
DEFAULT_SM_MODULE_PATH="module_path = \$(libdir);"
|
||||
|
@ -635,11 +639,6 @@ case "${host}" in
|
|||
LIBDIR=""
|
||||
LIB_PRE=""
|
||||
;;
|
||||
*-apple-*)
|
||||
DYN_LIB_EXT=".dylib"
|
||||
LIBDIR="\$(libdir)/"
|
||||
LIB_PRE="lib"
|
||||
;;
|
||||
*)
|
||||
DYN_LIB_EXT=".so"
|
||||
LIBDIR="\$(libdir)/"
|
||||
|
@ -784,7 +783,9 @@ if test "$GCC" = "yes"; then
|
|||
CFLAGS="-fno-strict-aliasing ${CFLAGS}"
|
||||
fi
|
||||
|
||||
CFLAGS="${CFLAGS} -Werror=declaration-after-statement"
|
||||
if test "${werror_declaration_after_statement}" = "yes"; then
|
||||
CFLAGS="${CFLAGS} -Werror=declaration-after-statement"
|
||||
fi
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<refentry id="gids-tool">
|
||||
<refmeta>
|
||||
<refentrytitle>gids-tool</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
<refmiscinfo class="productname">OpenSC</refmiscinfo>
|
||||
<refmiscinfo class="manual">OpenSC Tools</refmiscinfo>
|
||||
<refmiscinfo class="source">opensc</refmiscinfo>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>gids-tool</refname>
|
||||
<refpurpose>smart card utility for GIDS cards</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<cmdsynopsis>
|
||||
<command>gids-tool</command>
|
||||
<arg choice="opt"><replaceable class="option">OPTIONS</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<para>
|
||||
The <command>gids-tool</command> utility can be used from the command line to perform
|
||||
miscellaneous smart card operations on a GIDS smart card.
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Options</title>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-X</option>,
|
||||
<option>--initialize</option>
|
||||
</term>
|
||||
<listitem><para>Initialize token.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--admin-key</option> <replaceable>argument</replaceable>
|
||||
</term>
|
||||
<listitem><para>Define the administrator key</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--pin</option> <replaceable>argument</replaceable>
|
||||
</term>
|
||||
<listitem><para>Define user PIN.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--serial-number</option> <replaceable>argument</replaceable>
|
||||
</term>
|
||||
<listitem><para>Define serial number.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-U</option>,
|
||||
<option>--unblock</option>
|
||||
</term>
|
||||
<listitem><para>Unblock the user PIN after an administrator
|
||||
authentication.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-C</option>,
|
||||
<option>--change-admin-key</option>
|
||||
</term>
|
||||
<listitem><para>Change the administrator key.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--new-admin-key</option> <replaceable>argument</replaceable>
|
||||
</term>
|
||||
<listitem><para>Define the new adminastrator key.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--reader</option> <replaceable>argument</replaceable>,
|
||||
<option>-r</option> <replaceable>argument</replaceable>
|
||||
</term>
|
||||
<listitem><para>Uses reader number
|
||||
<replaceable>argument</replaceable>.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-w</option>,
|
||||
<option>--wait</option>
|
||||
</term>
|
||||
<listitem><para>Wait for a card to be inserted.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>-v</option>,
|
||||
<option>--verbose</option>
|
||||
</term>
|
||||
<listitem><para>Verbose operation. Use several times to
|
||||
enable debug output.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>See also</title>
|
||||
<para>
|
||||
<citerefentry>
|
||||
<refentrytitle>opensc-tool</refentrytitle>
|
||||
<manvolnum>1</manvolnum>
|
||||
</citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
|
@ -54,6 +54,15 @@
|
|||
<listitem><para>Change the user PIN on the token</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--unlock-pin</option>
|
||||
</term>
|
||||
<listitem><para>Unlock User PIN (without <option>--login</option>
|
||||
unlock in logged in session; otherwise <option>--login-type</option>
|
||||
has to be 'context-specific').</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--hash</option>,
|
||||
|
@ -75,7 +84,7 @@
|
|||
<option>--init-pin</option>
|
||||
</term>
|
||||
<listitem><para>Initializes the user PIN. This option
|
||||
differs from --change-pin in that it sets the user PIN
|
||||
differs from <option>--change-pin</option> in that it sets the user PIN
|
||||
for the first time. Once set, the user PIN can be changed
|
||||
using <option>--change-pin</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
@ -105,6 +114,34 @@
|
|||
<listitem><para>Generate a new key pair (public and private pair.)</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--key-type</option> <replacement>specification</replacement>
|
||||
</term>
|
||||
<listitem><para>Specify the type and length of the key to create, for example rsa:1024 or EC:prime256v1.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--usage-sign</option>
|
||||
</term>
|
||||
<listitem><para>Specify 'sign' key usage flag (sets SIGN in privkey, sets VERIFY in pubkey).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--usage-decrypt</option>
|
||||
</term>
|
||||
<listitem><para>Specify 'decrypt' key usage flag (RSA only, set DECRYPT privkey, ENCRYPT in pubkey).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--usage-derive</option>
|
||||
</term>
|
||||
<listitem><para>Specify 'derive' key usage flag (EC only).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--label</option> <replaceable>name</replaceable>,
|
||||
|
@ -157,6 +194,14 @@
|
|||
provided on the command line.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--login-type</option>
|
||||
</term>
|
||||
<listitem><para>Specify login type ('so', 'user', 'context-specific';
|
||||
default:'user').</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--mechanism</option> <replaceable>mechanism</replaceable>,
|
||||
|
@ -212,6 +257,20 @@
|
|||
the <option>--login</option> option.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--puk</option> <replaceable>puk</replaceable>
|
||||
</term>
|
||||
<listitem><para>Supply User PUK on the command line.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--new-pin</option> <replaceable>pin</replaceable>
|
||||
</term>
|
||||
<listitem><para>Supply new User PIN on the command line.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--set-id</option> <replaceable>id</replaceable>,
|
||||
|
@ -243,6 +302,13 @@
|
|||
<listitem><para>Decrypt some data.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--derive</option>,
|
||||
</term>
|
||||
<listitem><para>Derive a secret key using another key and some data.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--slot</option> <replaceable>id</replaceable>
|
||||
|
@ -296,6 +362,38 @@
|
|||
or <option>--pin</option>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--test-hotplug</option>
|
||||
</term>
|
||||
<listitem><para>Test hotplug capabilities (C_GetSlotList +
|
||||
C_WaitForSlotEvent).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--private</option>
|
||||
</term>
|
||||
<listitem><para>Set the CKA_PRIVATE attribute (object is only
|
||||
viewable after a login).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--test-ec</option>
|
||||
</term>
|
||||
<listitem><para>Test EC (best used with the <option>--login</option>
|
||||
or <option>--pin</option> option).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--test-fork</option>
|
||||
</term>
|
||||
<listitem><para>Test forking and calling C_Initialize() in the
|
||||
child.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--type</option> <replaceable>type</replaceable>,
|
||||
|
@ -317,6 +415,63 @@
|
|||
non-zero number.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--read-object</option>,
|
||||
<option>-r</option>
|
||||
</term>
|
||||
<listitem><para>Get object's CKA_VALUE attribute (use with
|
||||
<option>--type</option>).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--delete-object</option>,
|
||||
<option>-b</option>
|
||||
</term>
|
||||
<listitem><para>Delete an object.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--application-label</option> <replaceable>label</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify the application label of the data object (use with
|
||||
<option>--type</option> data).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--application-id</option> <replaceable>id</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify the application ID of the data object (use with
|
||||
<option>--type</option> data).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--issuer</option> <replaceable>data</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify the issuer in hexadecimal format (use with
|
||||
<option>--type</option> cert).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--subject</option> <replaceable>data</replaceable>
|
||||
</term>
|
||||
<listitem><para>Specify the subject in hexadecimal format (use with
|
||||
<option>--type</option> cert/privkey/pubkey).</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--signature-format</option> <replaceable>format</replaceable>
|
||||
</term>
|
||||
<listitem><para>Format for ECDSA signature: 'rs' (default),
|
||||
'sequence', 'openssl'.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--write-object</option> <replaceable>id</replaceable>,
|
||||
|
|
|
@ -34,6 +34,12 @@
|
|||
<title>Options</title>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--version</option>,
|
||||
</term>
|
||||
<listitem><para>Print the OpenSC package release version.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--aid</option> <replaceable>aid</replaceable>
|
||||
|
|
|
@ -239,6 +239,12 @@
|
|||
<title>Options</title>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--version</option>,
|
||||
</term>
|
||||
<listitem><para>Print the OpenSC package release version.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--card-profile</option> <replaceable>name</replaceable>,
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
<title>Options</title>
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--version</option>,
|
||||
</term>
|
||||
<listitem><para>Print the OpenSC package release version.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>
|
||||
<option>--aid</option> <replaceable>aid</replaceable>
|
||||
|
|
|
@ -66,9 +66,9 @@ app default {
|
|||
# The following section shows definitions for PC/SC readers.
|
||||
reader_driver pcsc {
|
||||
# Limit command and response sizes.
|
||||
# Default: n/a
|
||||
# max_send_size = 255;
|
||||
# max_recv_size = 256;
|
||||
# Default: max_send_size = 255, max_recv_size = 256;
|
||||
# max_send_size = 0;
|
||||
# max_recv_size = 0;
|
||||
#
|
||||
# Connect to reader in exclusive mode?
|
||||
# Default: false
|
||||
|
@ -569,12 +569,6 @@ app default {
|
|||
# Parameters for the OpenSC PKCS11 module
|
||||
app opensc-pkcs11 {
|
||||
pkcs11 {
|
||||
# Should the module support hotplug of readers as per PKCS#11 v2.20?
|
||||
# This affects slot changes and PC/SC PnP, as v2.11 applications
|
||||
# are not allowed to change the length of the slot list.
|
||||
# Default: true
|
||||
# plug_and_play = false;
|
||||
|
||||
# Maximum Number of virtual slots.
|
||||
# If there are more slots than defined here,
|
||||
# the remaining slots will be hidden from PKCS#11.
|
||||
|
|
|
@ -143,31 +143,31 @@ struct list_dump_header_s {
|
|||
|
||||
|
||||
/* deletes tmp from list, with care wrt its position (head, tail, middle) */
|
||||
static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos);
|
||||
static int list_drop_elem(list_t *simclist_restrict l, struct list_entry_s *tmp, unsigned int pos);
|
||||
|
||||
/* set default values for initialized lists */
|
||||
static int list_attributes_setdefaults(list_t *restrict l);
|
||||
static int list_attributes_setdefaults(list_t *simclist_restrict l);
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* check whether the list internal REPresentation is valid -- Costs O(n) */
|
||||
static int list_repOk(const list_t *restrict l);
|
||||
static int list_repOk(const list_t *simclist_restrict l);
|
||||
|
||||
/* check whether the list attribute set is valid -- Costs O(1) */
|
||||
static int list_attrOk(const list_t *restrict l);
|
||||
static int list_attrOk(const list_t *simclist_restrict l);
|
||||
#endif
|
||||
|
||||
/* do not inline, this is recursive */
|
||||
static void list_sort_quicksort(list_t *restrict l, int versus,
|
||||
static void list_sort_quicksort(list_t *simclist_restrict l, int versus,
|
||||
unsigned int first, struct list_entry_s *fel,
|
||||
unsigned int last, struct list_entry_s *lel);
|
||||
|
||||
static inline void list_sort_selectionsort(list_t *restrict l, int versus,
|
||||
static simclist_inline void list_sort_selectionsort(list_t *simclist_restrict l, int versus,
|
||||
unsigned int first, struct list_entry_s *fel,
|
||||
unsigned int last, struct list_entry_s *lel);
|
||||
|
||||
static void *list_get_minmax(const list_t *restrict l, int versus);
|
||||
static void *list_get_minmax(const list_t *simclist_restrict l, int versus);
|
||||
|
||||
static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart);
|
||||
static simclist_inline struct list_entry_s *list_findpos(const list_t *simclist_restrict l, int posstart);
|
||||
|
||||
#ifdef SIMCLIST_DUMPRESTORE
|
||||
/* write() decorated with error checking logic */
|
||||
|
@ -210,12 +210,12 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po
|
|||
static unsigned random_seed = 0;
|
||||
|
||||
/* use local RNG */
|
||||
static inline void seed_random() {
|
||||
static simclist_inline void seed_random() {
|
||||
if (random_seed == 0)
|
||||
random_seed = (unsigned)getpid() ^ (unsigned)time(NULL);
|
||||
}
|
||||
|
||||
static inline long get_random() {
|
||||
static simclist_inline long get_random() {
|
||||
random_seed = (1664525 * random_seed + 1013904223);
|
||||
return random_seed;
|
||||
}
|
||||
|
@ -228,7 +228,7 @@ static inline long get_random() {
|
|||
|
||||
|
||||
/* list initialization */
|
||||
int list_init(list_t *restrict l) {
|
||||
int list_init(list_t *simclist_restrict l) {
|
||||
if (l == NULL) return -1;
|
||||
|
||||
seed_random();
|
||||
|
@ -264,7 +264,7 @@ int list_init(list_t *restrict l) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void list_destroy(list_t *restrict l) {
|
||||
void list_destroy(list_t *simclist_restrict l) {
|
||||
unsigned int i;
|
||||
|
||||
list_clear(l);
|
||||
|
@ -276,7 +276,7 @@ void list_destroy(list_t *restrict l) {
|
|||
free(l->tail_sentinel);
|
||||
}
|
||||
|
||||
int list_attributes_setdefaults(list_t *restrict l) {
|
||||
int list_attributes_setdefaults(list_t *simclist_restrict l) {
|
||||
l->attrs.comparator = NULL;
|
||||
l->attrs.seeker = NULL;
|
||||
|
||||
|
@ -296,7 +296,7 @@ int list_attributes_setdefaults(list_t *restrict l) {
|
|||
}
|
||||
|
||||
/* setting list properties */
|
||||
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) {
|
||||
int list_attributes_comparator(list_t *simclist_restrict l, element_comparator comparator_fun) {
|
||||
if (l == NULL) return -1;
|
||||
|
||||
l->attrs.comparator = comparator_fun;
|
||||
|
@ -306,7 +306,7 @@ int list_attributes_comparator(list_t *restrict l, element_comparator comparator
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) {
|
||||
int list_attributes_seeker(list_t *simclist_restrict l, element_seeker seeker_fun) {
|
||||
if (l == NULL) return -1;
|
||||
|
||||
l->attrs.seeker = seeker_fun;
|
||||
|
@ -315,7 +315,7 @@ int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) {
|
||||
int list_attributes_copy(list_t *simclist_restrict l, element_meter metric_fun, int copy_data) {
|
||||
if (l == NULL || (metric_fun == NULL && copy_data != 0)) return -1;
|
||||
|
||||
l->attrs.meter = metric_fun;
|
||||
|
@ -326,7 +326,7 @@ int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) {
|
||||
int list_attributes_hash_computer(list_t *simclist_restrict l, element_hash_computer hash_computer_fun) {
|
||||
if (l == NULL) return -1;
|
||||
|
||||
l->attrs.hasher = hash_computer_fun;
|
||||
|
@ -334,7 +334,7 @@ int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) {
|
||||
int list_attributes_serializer(list_t *simclist_restrict l, element_serializer serializer_fun) {
|
||||
if (l == NULL) return -1;
|
||||
|
||||
l->attrs.serializer = serializer_fun;
|
||||
|
@ -342,7 +342,7 @@ int list_attributes_serializer(list_t *restrict l, element_serializer serializer
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) {
|
||||
int list_attributes_unserializer(list_t *simclist_restrict l, element_unserializer unserializer_fun) {
|
||||
if (l == NULL) return -1;
|
||||
|
||||
l->attrs.unserializer = unserializer_fun;
|
||||
|
@ -350,19 +350,19 @@ int list_attributes_unserializer(list_t *restrict l, element_unserializer unseri
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_append(list_t *restrict l, const void *data) {
|
||||
int list_append(list_t *simclist_restrict l, const void *data) {
|
||||
return list_insert_at(l, data, l->numels);
|
||||
}
|
||||
|
||||
int list_prepend(list_t *restrict l, const void *data) {
|
||||
int list_prepend(list_t *simclist_restrict l, const void *data) {
|
||||
return list_insert_at(l, data, 0);
|
||||
}
|
||||
|
||||
void *list_fetch(list_t *restrict l) {
|
||||
void *list_fetch(list_t *simclist_restrict l) {
|
||||
return list_extract_at(l, 0);
|
||||
}
|
||||
|
||||
void *list_get_at(const list_t *restrict l, unsigned int pos) {
|
||||
void *list_get_at(const list_t *simclist_restrict l, unsigned int pos) {
|
||||
struct list_entry_s *tmp;
|
||||
|
||||
tmp = list_findpos(l, pos);
|
||||
|
@ -370,17 +370,17 @@ void *list_get_at(const list_t *restrict l, unsigned int pos) {
|
|||
return (tmp != NULL ? tmp->data : NULL);
|
||||
}
|
||||
|
||||
void *list_get_max(const list_t *restrict l) {
|
||||
void *list_get_max(const list_t *simclist_restrict l) {
|
||||
return list_get_minmax(l, +1);
|
||||
}
|
||||
|
||||
void *list_get_min(const list_t *restrict l) {
|
||||
void *list_get_min(const list_t *simclist_restrict l) {
|
||||
return list_get_minmax(l, -1);
|
||||
}
|
||||
|
||||
/* REQUIRES {list->numels >= 1}
|
||||
* return the min (versus < 0) or max value (v > 0) in l */
|
||||
static void *list_get_minmax(const list_t *restrict l, int versus) {
|
||||
static void *list_get_minmax(const list_t *simclist_restrict l, int versus) {
|
||||
void *curminmax;
|
||||
struct list_entry_s *s;
|
||||
|
||||
|
@ -397,7 +397,7 @@ static void *list_get_minmax(const list_t *restrict l, int versus) {
|
|||
}
|
||||
|
||||
/* set tmp to point to element at index posstart in l */
|
||||
static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart) {
|
||||
static simclist_inline struct list_entry_s *list_findpos(const list_t *simclist_restrict l, int posstart) {
|
||||
struct list_entry_s *ptr;
|
||||
float x;
|
||||
int i;
|
||||
|
@ -423,7 +423,7 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po
|
|||
return ptr;
|
||||
}
|
||||
|
||||
void *list_extract_at(list_t *restrict l, unsigned int pos) {
|
||||
void *list_extract_at(list_t *simclist_restrict l, unsigned int pos) {
|
||||
struct list_entry_s *tmp;
|
||||
void *data;
|
||||
|
||||
|
@ -441,7 +441,7 @@ void *list_extract_at(list_t *restrict l, unsigned int pos) {
|
|||
return data;
|
||||
}
|
||||
|
||||
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) {
|
||||
int list_insert_at(list_t *simclist_restrict l, const void *data, unsigned int pos) {
|
||||
struct list_entry_s *lent, *succ, *prec;
|
||||
|
||||
if (l->iter_active || pos > l->numels) return -1;
|
||||
|
@ -490,7 +490,7 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
int list_delete(list_t *restrict l, const void *data) {
|
||||
int list_delete(list_t *simclist_restrict l, const void *data) {
|
||||
int pos, r;
|
||||
|
||||
pos = list_locate(l, data);
|
||||
|
@ -506,7 +506,7 @@ int list_delete(list_t *restrict l, const void *data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_delete_at(list_t *restrict l, unsigned int pos) {
|
||||
int list_delete_at(list_t *simclist_restrict l, unsigned int pos) {
|
||||
struct list_entry_s *delendo;
|
||||
|
||||
|
||||
|
@ -524,7 +524,7 @@ int list_delete_at(list_t *restrict l, unsigned int pos) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) {
|
||||
int list_delete_range(list_t *simclist_restrict l, unsigned int posstart, unsigned int posend) {
|
||||
struct list_entry_s *lastvalid, *tmp, *tmp2;
|
||||
unsigned int i;
|
||||
int movedx;
|
||||
|
@ -586,7 +586,7 @@ int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int po
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_clear(list_t *restrict l) {
|
||||
int list_clear(list_t *simclist_restrict l) {
|
||||
struct list_entry_s *s;
|
||||
|
||||
if (l->iter_active) return -1;
|
||||
|
@ -628,15 +628,15 @@ int list_clear(list_t *restrict l) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
unsigned int list_size(const list_t *restrict l) {
|
||||
unsigned int list_size(const list_t *simclist_restrict l) {
|
||||
return l->numels;
|
||||
}
|
||||
|
||||
int list_empty(const list_t *restrict l) {
|
||||
int list_empty(const list_t *simclist_restrict l) {
|
||||
return (l->numels == 0);
|
||||
}
|
||||
|
||||
int list_locate(const list_t *restrict l, const void *data) {
|
||||
int list_locate(const list_t *simclist_restrict l, const void *data) {
|
||||
struct list_entry_s *el;
|
||||
int pos = 0;
|
||||
|
||||
|
@ -656,7 +656,7 @@ int list_locate(const list_t *restrict l, const void *data) {
|
|||
return pos;
|
||||
}
|
||||
|
||||
void *list_seek(list_t *restrict l, const void *indicator) {
|
||||
void *list_seek(list_t *simclist_restrict l, const void *indicator) {
|
||||
const struct list_entry_s *iter;
|
||||
|
||||
if (l->attrs.seeker == NULL) return NULL;
|
||||
|
@ -668,11 +668,11 @@ void *list_seek(list_t *restrict l, const void *indicator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int list_contains(const list_t *restrict l, const void *data) {
|
||||
int list_contains(const list_t *simclist_restrict l, const void *data) {
|
||||
return (list_locate(l, data) >= 0);
|
||||
}
|
||||
|
||||
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) {
|
||||
int list_concat(const list_t *l1, const list_t *l2, list_t *simclist_restrict dest) {
|
||||
struct list_entry_s *el, *srcel;
|
||||
unsigned int cnt;
|
||||
int err;
|
||||
|
@ -725,7 +725,7 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_sort(list_t *restrict l, int versus) {
|
||||
int list_sort(list_t *simclist_restrict l, int versus) {
|
||||
if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */
|
||||
return -1;
|
||||
|
||||
|
@ -738,7 +738,7 @@ int list_sort(list_t *restrict l, int versus) {
|
|||
|
||||
#ifdef SIMCLIST_WITH_THREADS
|
||||
struct list_sort_wrappedparams {
|
||||
list_t *restrict l;
|
||||
list_t *simclist_restrict l;
|
||||
int versus;
|
||||
unsigned int first, last;
|
||||
struct list_entry_s *fel, *lel;
|
||||
|
@ -753,7 +753,7 @@ static void *list_sort_quicksort_threadwrapper(void *wrapped_params) {
|
|||
}
|
||||
#endif
|
||||
|
||||
static inline void list_sort_selectionsort(list_t *restrict l, int versus,
|
||||
static simclist_inline void list_sort_selectionsort(list_t *simclist_restrict l, int versus,
|
||||
unsigned int first, struct list_entry_s *fel,
|
||||
unsigned int last, struct list_entry_s *lel) {
|
||||
struct list_entry_s *cursor, *toswap, *firstunsorted;
|
||||
|
@ -774,7 +774,7 @@ static inline void list_sort_selectionsort(list_t *restrict l, int versus,
|
|||
}
|
||||
}
|
||||
|
||||
static void list_sort_quicksort(list_t *restrict l, int versus,
|
||||
static void list_sort_quicksort(list_t *simclist_restrict l, int versus,
|
||||
unsigned int first, struct list_entry_s *fel,
|
||||
unsigned int last, struct list_entry_s *lel) {
|
||||
unsigned int pivotid;
|
||||
|
@ -897,7 +897,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus,
|
|||
#endif
|
||||
}
|
||||
|
||||
int list_iterator_start(list_t *restrict l) {
|
||||
int list_iterator_start(list_t *simclist_restrict l) {
|
||||
if (l->iter_active) return 0;
|
||||
l->iter_pos = 0;
|
||||
l->iter_active = 1;
|
||||
|
@ -905,7 +905,7 @@ int list_iterator_start(list_t *restrict l) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
void *list_iterator_next(list_t *restrict l) {
|
||||
void *list_iterator_next(list_t *simclist_restrict l) {
|
||||
void *toret;
|
||||
|
||||
if (! l->iter_active) return NULL;
|
||||
|
@ -917,19 +917,19 @@ void *list_iterator_next(list_t *restrict l) {
|
|||
return toret;
|
||||
}
|
||||
|
||||
int list_iterator_hasnext(const list_t *restrict l) {
|
||||
int list_iterator_hasnext(const list_t *simclist_restrict l) {
|
||||
if (! l->iter_active) return 0;
|
||||
return (l->iter_pos < l->numels);
|
||||
}
|
||||
|
||||
int list_iterator_stop(list_t *restrict l) {
|
||||
int list_iterator_stop(list_t *simclist_restrict l) {
|
||||
if (! l->iter_active) return 0;
|
||||
l->iter_pos = 0;
|
||||
l->iter_active = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int list_hash(const list_t *restrict l, list_hash_t *restrict hash) {
|
||||
int list_hash(const list_t *simclist_restrict l, list_hash_t *simclist_restrict hash) {
|
||||
struct list_entry_s *x;
|
||||
list_hash_t tmphash;
|
||||
|
||||
|
@ -976,7 +976,7 @@ int gettimeofday(struct timeval* tp, void* tzp) {
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) {
|
||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *simclist_restrict info) {
|
||||
int32_t terminator_head, terminator_tail;
|
||||
uint32_t elemlen;
|
||||
off_t hop;
|
||||
|
@ -1038,7 +1038,7 @@ int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) {
|
||||
int list_dump_getinfo_file(const char *simclist_restrict filename, list_dump_info_t *simclist_restrict info) {
|
||||
int fd, ret;
|
||||
|
||||
fd = open(filename, O_RDONLY, 0);
|
||||
|
@ -1050,7 +1050,7 @@ int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *rest
|
|||
return ret;
|
||||
}
|
||||
|
||||
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) {
|
||||
int list_dump_filedescriptor(const list_t *simclist_restrict l, int fd, size_t *simclist_restrict len) {
|
||||
struct list_entry_s *x;
|
||||
void *ser_buf;
|
||||
uint32_t bufsize;
|
||||
|
@ -1197,7 +1197,7 @@ int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) {
|
||||
int list_restore_filedescriptor(list_t *simclist_restrict l, int fd, size_t *simclist_restrict len) {
|
||||
struct list_dump_header_s header;
|
||||
unsigned long cnt;
|
||||
void *buf = NULL;
|
||||
|
@ -1318,7 +1318,7 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
|
|||
return 0;
|
||||
}
|
||||
|
||||
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) {
|
||||
int list_dump_file(const list_t *simclist_restrict l, const char *simclist_restrict filename, size_t *simclist_restrict len) {
|
||||
int fd, mode;
|
||||
size_t sizetoret;
|
||||
mode = O_RDWR | O_CREAT | O_TRUNC;
|
||||
|
@ -1334,7 +1334,7 @@ int list_dump_file(const list_t *restrict l, const char *restrict filename, size
|
|||
return sizetoret;
|
||||
}
|
||||
|
||||
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) {
|
||||
int list_restore_file(list_t *simclist_restrict l, const char *simclist_restrict filename, size_t *simclist_restrict len) {
|
||||
int fd;
|
||||
size_t totdata;
|
||||
|
||||
|
@ -1349,7 +1349,7 @@ int list_restore_file(list_t *restrict l, const char *restrict filename, size_t
|
|||
#endif /* ifdef SIMCLIST_DUMPRESTORE */
|
||||
|
||||
|
||||
static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos) {
|
||||
static int list_drop_elem(list_t *simclist_restrict l, struct list_entry_s *tmp, unsigned int pos) {
|
||||
if (tmp == NULL) return -1;
|
||||
|
||||
/* fix mid pointer. This is wrt the PRE situation */
|
||||
|
@ -1446,7 +1446,7 @@ list_hash_t list_hashcomputer_string(const void *el) {
|
|||
|
||||
|
||||
#ifndef NDEBUG
|
||||
static int list_repOk(const list_t *restrict l) {
|
||||
static int list_repOk(const list_t *simclist_restrict l) {
|
||||
int ok, i;
|
||||
struct list_entry_s *s;
|
||||
|
||||
|
@ -1478,7 +1478,7 @@ static int list_repOk(const list_t *restrict l) {
|
|||
return ok;
|
||||
}
|
||||
|
||||
static int list_attrOk(const list_t *restrict l) {
|
||||
static int list_attrOk(const list_t *simclist_restrict l) {
|
||||
int ok;
|
||||
|
||||
ok = (l->attrs.copy_data == 0 || l->attrs.meter != NULL);
|
||||
|
|
|
@ -44,12 +44,39 @@ typedef INT64 int64_t;
|
|||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* bases on OpenSSL's version in e_os2.h */
|
||||
#if !defined(inline)
|
||||
/* Be friend of both C90 and C99 compilers */
|
||||
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* "inline" and "restrict" are keywords */
|
||||
#else
|
||||
# define inline /* inline */
|
||||
# define restrict /* restrict */
|
||||
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* "inline" and "restrict" are keywords */
|
||||
# define simclist_inline inline
|
||||
# elif defined(__GNUC__) && __GNUC__>=2
|
||||
# define simclist_inline __inline__
|
||||
# elif defined(_MSC_VER)
|
||||
# define simclist_inline __inline
|
||||
# else
|
||||
# define simclist_inline
|
||||
# endif
|
||||
#else /* use what caller wants as inline may be from config.h */
|
||||
# define simclist_inline inline /* inline */
|
||||
#endif
|
||||
|
||||
/* bases on OpenSSL's version in e_os2.h */
|
||||
/* On MacOS C++ is used for tokend */
|
||||
#if !defined(restrict)
|
||||
/* Be friend of both C90 and C99 compilers */
|
||||
# if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||
/* "inline" and "restrict" are keywords */
|
||||
# define simclist_restrict restrict /* restrict */
|
||||
# elif defined(__GNUC__) && __GNUC__>=2
|
||||
# define simclist_restrict __restrict__
|
||||
# elif defined(_MSC_VER)
|
||||
# define simclist_restrict __restrict
|
||||
# else
|
||||
# define simclist_restrict
|
||||
# endif
|
||||
#else /* use what caller wants as restrict may be from config.h */
|
||||
# define simclist_restrict restrict
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -136,7 +163,7 @@ typedef list_hash_t (*element_hash_computer)(const void *el);
|
|||
* @param serialize_buffer reference to fill with the length of the buffer
|
||||
* @return reference to the buffer with the serialized data
|
||||
*/
|
||||
typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len);
|
||||
typedef void *(*element_serializer)(const void *simclist_restrict el, uint32_t *simclist_restrict serializ_len);
|
||||
|
||||
/**
|
||||
* a function for un-serializing an element.
|
||||
|
@ -153,7 +180,7 @@ typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict
|
|||
* @param data_len reference to the location where to store the length of the data in the buffer returned
|
||||
* @return reference to a buffer with the original, unserialized representation of the element
|
||||
*/
|
||||
typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len);
|
||||
typedef void *(*element_unserializer)(const void *simclist_restrict data, uint32_t *simclist_restrict data_len);
|
||||
|
||||
/* [private-use] list entry -- olds actual user datum */
|
||||
struct list_entry_s {
|
||||
|
@ -213,7 +240,7 @@ typedef struct {
|
|||
* @param l must point to a user-provided memory location
|
||||
* @return 0 for success. -1 for failure
|
||||
*/
|
||||
int list_init(list_t *restrict l);
|
||||
int list_init(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* completely remove the list from memory.
|
||||
|
@ -224,7 +251,7 @@ int list_init(list_t *restrict l);
|
|||
*
|
||||
* @param l list to destroy
|
||||
*/
|
||||
void list_destroy(list_t *restrict l);
|
||||
void list_destroy(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* set the comparator function for list elements.
|
||||
|
@ -238,7 +265,7 @@ void list_destroy(list_t *restrict l);
|
|||
*
|
||||
* @see element_comparator()
|
||||
*/
|
||||
int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun);
|
||||
int list_attributes_comparator(list_t *simclist_restrict l, element_comparator comparator_fun);
|
||||
|
||||
/**
|
||||
* set a seeker function for list elements.
|
||||
|
@ -252,7 +279,7 @@ int list_attributes_comparator(list_t *restrict l, element_comparator comparator
|
|||
*
|
||||
* @see element_seeker()
|
||||
*/
|
||||
int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
|
||||
int list_attributes_seeker(list_t *simclist_restrict l, element_seeker seeker_fun);
|
||||
|
||||
/**
|
||||
* require to free element data when list entry is removed (default: don't free).
|
||||
|
@ -284,7 +311,7 @@ int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun);
|
|||
* @see list_meter_double()
|
||||
* @see list_meter_string()
|
||||
*/
|
||||
int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data);
|
||||
int list_attributes_copy(list_t *simclist_restrict l, element_meter metric_fun, int copy_data);
|
||||
|
||||
/**
|
||||
* set the element hash computing function for the list elements.
|
||||
|
@ -304,7 +331,7 @@ int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_
|
|||
*
|
||||
* @see element_hash_computer()
|
||||
*/
|
||||
int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun);
|
||||
int list_attributes_hash_computer(list_t *simclist_restrict l, element_hash_computer hash_computer_fun);
|
||||
|
||||
/**
|
||||
* set the element serializer function for the list elements.
|
||||
|
@ -325,7 +352,7 @@ int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash
|
|||
* @see list_dump_filedescriptor()
|
||||
* @see list_restore_filedescriptor()
|
||||
*/
|
||||
int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun);
|
||||
int list_attributes_serializer(list_t *simclist_restrict l, element_serializer serializer_fun);
|
||||
|
||||
/**
|
||||
* set the element unserializer function for the list elements.
|
||||
|
@ -347,7 +374,7 @@ int list_attributes_serializer(list_t *restrict l, element_serializer serializer
|
|||
* @see list_dump_filedescriptor()
|
||||
* @see list_restore_filedescriptor()
|
||||
*/
|
||||
int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun);
|
||||
int list_attributes_unserializer(list_t *simclist_restrict l, element_unserializer unserializer_fun);
|
||||
|
||||
/**
|
||||
* append data at the end of the list.
|
||||
|
@ -359,7 +386,7 @@ int list_attributes_unserializer(list_t *restrict l, element_unserializer unseri
|
|||
*
|
||||
* @return 1 for success. < 0 for failure
|
||||
*/
|
||||
int list_append(list_t *restrict l, const void *data);
|
||||
int list_append(list_t *simclist_restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* insert data in the head of the list.
|
||||
|
@ -371,7 +398,7 @@ int list_append(list_t *restrict l, const void *data);
|
|||
*
|
||||
* @return 1 for success. < 0 for failure
|
||||
*/
|
||||
int list_prepend(list_t *restrict l, const void *restrict data);
|
||||
int list_prepend(list_t *simclist_restrict l, const void *simclist_restrict data);
|
||||
|
||||
/**
|
||||
* extract the element in the top of the list.
|
||||
|
@ -381,7 +408,7 @@ int list_prepend(list_t *restrict l, const void *restrict data);
|
|||
* @param l list to operate
|
||||
* @return reference to user datum, or NULL on errors
|
||||
*/
|
||||
void *list_fetch(list_t *restrict l);
|
||||
void *list_fetch(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* retrieve an element at a given position.
|
||||
|
@ -390,7 +417,7 @@ void *list_fetch(list_t *restrict l);
|
|||
* @param pos [0,size-1] position index of the element wanted
|
||||
* @return reference to user datum, or NULL on errors
|
||||
*/
|
||||
void *list_get_at(const list_t *restrict l, unsigned int pos);
|
||||
void *list_get_at(const list_t *simclist_restrict l, unsigned int pos);
|
||||
|
||||
/**
|
||||
* return the maximum element of the list.
|
||||
|
@ -404,7 +431,7 @@ void *list_get_at(const list_t *restrict l, unsigned int pos);
|
|||
* @param l list to operate
|
||||
* @return the reference to the element, or NULL
|
||||
*/
|
||||
void *list_get_max(const list_t *restrict l);
|
||||
void *list_get_max(const list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* return the minimum element of the list.
|
||||
|
@ -418,7 +445,7 @@ void *list_get_max(const list_t *restrict l);
|
|||
* @param l list to operate
|
||||
* @return the reference to the element, or NULL
|
||||
*/
|
||||
void *list_get_min(const list_t *restrict l);
|
||||
void *list_get_min(const list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* retrieve and remove from list an element at a given position.
|
||||
|
@ -427,7 +454,7 @@ void *list_get_min(const list_t *restrict l);
|
|||
* @param pos [0,size-1] position index of the element wanted
|
||||
* @return reference to user datum, or NULL on errors
|
||||
*/
|
||||
void *list_extract_at(list_t *restrict l, unsigned int pos);
|
||||
void *list_extract_at(list_t *simclist_restrict l, unsigned int pos);
|
||||
|
||||
/**
|
||||
* insert an element at a given position.
|
||||
|
@ -437,7 +464,7 @@ void *list_extract_at(list_t *restrict l, unsigned int pos);
|
|||
* @param pos [0,size-1] position index to insert the element at
|
||||
* @return positive value on success. Negative on failure
|
||||
*/
|
||||
int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
|
||||
int list_insert_at(list_t *simclist_restrict l, const void *data, unsigned int pos);
|
||||
|
||||
/**
|
||||
* expunge the first found given element from the list.
|
||||
|
@ -454,7 +481,7 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos);
|
|||
* @see list_attributes_comparator()
|
||||
* @see list_delete_at()
|
||||
*/
|
||||
int list_delete(list_t *restrict l, const void *data);
|
||||
int list_delete(list_t *simclist_restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* expunge an element at a given position from the list.
|
||||
|
@ -463,7 +490,7 @@ int list_delete(list_t *restrict l, const void *data);
|
|||
* @param pos [0,size-1] position index of the element to be deleted
|
||||
* @return 0 on success. Negative value on failure
|
||||
*/
|
||||
int list_delete_at(list_t *restrict l, unsigned int pos);
|
||||
int list_delete_at(list_t *simclist_restrict l, unsigned int pos);
|
||||
|
||||
/**
|
||||
* expunge an array of elements from the list, given their position range.
|
||||
|
@ -473,7 +500,7 @@ int list_delete_at(list_t *restrict l, unsigned int pos);
|
|||
* @param posend [posstart,size-1] position of the last element to be deleted
|
||||
* @return the number of elements successfully removed
|
||||
*/
|
||||
int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend);
|
||||
int list_delete_range(list_t *simclist_restrict l, unsigned int posstart, unsigned int posend);
|
||||
|
||||
/**
|
||||
* clear all the elements off of the list.
|
||||
|
@ -486,7 +513,7 @@ int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int po
|
|||
* @param l list to operate
|
||||
* @return the number of elements in the list before cleaning
|
||||
*/
|
||||
int list_clear(list_t *restrict l);
|
||||
int list_clear(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* inspect the number of elements in the list.
|
||||
|
@ -494,7 +521,7 @@ int list_clear(list_t *restrict l);
|
|||
* @param l list to operate
|
||||
* @return number of elements currently held by the list
|
||||
*/
|
||||
unsigned int list_size(const list_t *restrict l);
|
||||
unsigned int list_size(const list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* inspect whether the list is empty.
|
||||
|
@ -504,7 +531,7 @@ unsigned int list_size(const list_t *restrict l);
|
|||
*
|
||||
* @see list_size()
|
||||
*/
|
||||
int list_empty(const list_t *restrict l);
|
||||
int list_empty(const list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* find the position of an element in a list.
|
||||
|
@ -523,7 +550,7 @@ int list_empty(const list_t *restrict l);
|
|||
* @see list_attributes_comparator()
|
||||
* @see list_get_at()
|
||||
*/
|
||||
int list_locate(const list_t *restrict l, const void *data);
|
||||
int list_locate(const list_t *simclist_restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* returns an element given an indicator.
|
||||
|
@ -538,7 +565,7 @@ int list_locate(const list_t *restrict l, const void *data);
|
|||
* @param indicator indicator data to pass to the seeker along with elements
|
||||
* @return reference to the element accepted by the seeker, or NULL if none found
|
||||
*/
|
||||
void *list_seek(list_t *restrict l, const void *indicator);
|
||||
void *list_seek(list_t *simclist_restrict l, const void *indicator);
|
||||
|
||||
/**
|
||||
* inspect whether some data is member of the list.
|
||||
|
@ -559,7 +586,7 @@ void *list_seek(list_t *restrict l, const void *indicator);
|
|||
*
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_contains(const list_t *restrict l, const void *data);
|
||||
int list_contains(const list_t *simclist_restrict l, const void *data);
|
||||
|
||||
/**
|
||||
* concatenate two lists
|
||||
|
@ -578,7 +605,7 @@ int list_contains(const list_t *restrict l, const void *data);
|
|||
* @param dest reference to the destination list
|
||||
* @return 0 for success, -1 for errors
|
||||
*/
|
||||
int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
|
||||
int list_concat(const list_t *l1, const list_t *l2, list_t *simclist_restrict dest);
|
||||
|
||||
/**
|
||||
* sort list elements.
|
||||
|
@ -595,7 +622,7 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest);
|
|||
*
|
||||
* @see list_attributes_comparator()
|
||||
*/
|
||||
int list_sort(list_t *restrict l, int versus);
|
||||
int list_sort(list_t *simclist_restrict l, int versus);
|
||||
|
||||
/**
|
||||
* start an iteration session.
|
||||
|
@ -607,7 +634,7 @@ int list_sort(list_t *restrict l, int versus);
|
|||
*
|
||||
* @see list_iterator_stop()
|
||||
*/
|
||||
int list_iterator_start(list_t *restrict l);
|
||||
int list_iterator_start(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* return the next element in the iteration session.
|
||||
|
@ -615,7 +642,7 @@ int list_iterator_start(list_t *restrict l);
|
|||
* @param l list to operate
|
||||
* @return element datum, or NULL on errors
|
||||
*/
|
||||
void *list_iterator_next(list_t *restrict l);
|
||||
void *list_iterator_next(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* inspect whether more elements are available in the iteration session.
|
||||
|
@ -623,7 +650,7 @@ void *list_iterator_next(list_t *restrict l);
|
|||
* @param l list to operate
|
||||
* @return 0 iff no more elements are available.
|
||||
*/
|
||||
int list_iterator_hasnext(const list_t *restrict l);
|
||||
int list_iterator_hasnext(const list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* end an iteration session.
|
||||
|
@ -631,7 +658,7 @@ int list_iterator_hasnext(const list_t *restrict l);
|
|||
* @param l list to operate
|
||||
* @return 0 iff the iteration session cannot be stopped
|
||||
*/
|
||||
int list_iterator_stop(list_t *restrict l);
|
||||
int list_iterator_stop(list_t *simclist_restrict l);
|
||||
|
||||
/**
|
||||
* return the hash of the current status of the list.
|
||||
|
@ -641,7 +668,7 @@ int list_iterator_stop(list_t *restrict l);
|
|||
*
|
||||
* @return 0 for success; <0 for failure
|
||||
*/
|
||||
int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
|
||||
int list_hash(const list_t *simclist_restrict l, list_hash_t *simclist_restrict hash);
|
||||
|
||||
#ifdef SIMCLIST_DUMPRESTORE
|
||||
/**
|
||||
|
@ -659,7 +686,7 @@ int list_hash(const list_t *restrict l, list_hash_t *restrict hash);
|
|||
*
|
||||
* @see list_dump_filedescriptor()
|
||||
*/
|
||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
|
||||
int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *simclist_restrict info);
|
||||
|
||||
/**
|
||||
* get meta informations on a list dump on file.
|
||||
|
@ -674,7 +701,7 @@ int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info);
|
|||
*
|
||||
* @see list_dump_filedescriptor()
|
||||
*/
|
||||
int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info);
|
||||
int list_dump_getinfo_file(const char *simclist_restrict filename, list_dump_info_t *simclist_restrict info);
|
||||
|
||||
/**
|
||||
* dump the list into an open, writable file descriptor.
|
||||
|
@ -710,7 +737,7 @@ int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *rest
|
|||
* @see list_attributes_copy()
|
||||
* @see list_attributes_serializer()
|
||||
*/
|
||||
int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len);
|
||||
int list_dump_filedescriptor(const list_t *simclist_restrict l, int fd, size_t *simclist_restrict len);
|
||||
|
||||
/**
|
||||
* dump the list to a file name.
|
||||
|
@ -733,7 +760,7 @@ int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict
|
|||
*
|
||||
* This function stores a representation of the list
|
||||
*/
|
||||
int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len);
|
||||
int list_dump_file(const list_t *simclist_restrict l, const char *simclist_restrict filename, size_t *simclist_restrict len);
|
||||
|
||||
/**
|
||||
* restore the list from an open, readable file descriptor to memory.
|
||||
|
@ -753,7 +780,7 @@ int list_dump_file(const list_t *restrict l, const char *restrict filename, size
|
|||
* @param len location to store the length of the dump read (bytes), or NULL
|
||||
* @return 0 if successful; -1 otherwise
|
||||
*/
|
||||
int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len);
|
||||
int list_restore_filedescriptor(list_t *simclist_restrict l, int fd, size_t *simclist_restrict len);
|
||||
|
||||
/**
|
||||
* restore the list from a file name.
|
||||
|
@ -771,7 +798,7 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len
|
|||
* @param len location to store the length of the dump read (bytes), or NULL
|
||||
* @return 0 if successful; -1 otherwise
|
||||
*/
|
||||
int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len);
|
||||
int list_restore_file(list_t *simclist_restrict l, const char *simclist_restrict filename, size_t *len);
|
||||
#endif
|
||||
|
||||
/* ready-made comparators, meters and hash computers */
|
||||
|
|
|
@ -6,12 +6,12 @@ EXTRA_DIST = Makefile.mak
|
|||
|
||||
lib_LTLIBRARIES = libopensc.la
|
||||
noinst_HEADERS = cards.h ctbcs.h internal.h esteid.h muscle.h muscle-filesystem.h \
|
||||
internal-winscard.h p15card-helper.h \
|
||||
internal-winscard.h p15card-helper.h pkcs15-syn.h \
|
||||
opensc.h pkcs15.h \
|
||||
cardctl.h asn1.h log.h \
|
||||
errors.h types.h compression.h itacns.h iso7816.h \
|
||||
authentic.h iasecc.h iasecc-sdo.h sm.h card-sc-hsm.h \
|
||||
pace.h cwa14890.h cwa-dnie.h card-gids.h
|
||||
pace.h cwa14890.h cwa-dnie.h card-gids.h aux-data.h
|
||||
|
||||
AM_CPPFLAGS = -DOPENSC_CONF_PATH=\"$(sysconfdir)/opensc.conf\" \
|
||||
-I$(top_srcdir)/src
|
||||
|
@ -48,8 +48,9 @@ libopensc_la_SOURCES = \
|
|||
pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \
|
||||
pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c pkcs15-oberthur.c \
|
||||
pkcs15-itacns.c pkcs15-gemsafeV1.c pkcs15-sc-hsm.c \
|
||||
pkcs15-dnie.c pkcs15-gids.c \
|
||||
pkcs15-dnie.c pkcs15-gids.c pkcs15-iasecc.c \
|
||||
compression.c p15card-helper.c sm.c \
|
||||
aux-data.c \
|
||||
libopensc.exports
|
||||
if WIN32
|
||||
libopensc_la_SOURCES += $(top_builddir)/win32/versioninfo.rc
|
||||
|
|
|
@ -31,8 +31,9 @@ OBJECTS = \
|
|||
pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \
|
||||
pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-oberthur.obj \
|
||||
pkcs15-itacns.obj pkcs15-gemsafeV1.obj pkcs15-sc-hsm.obj \
|
||||
pkcs15-dnie.obj pkcs15-gids.obj \
|
||||
pkcs15-dnie.obj pkcs15-gids.obj pkcs15-iasecc.obj \
|
||||
compression.obj p15card-helper.obj sm.obj \
|
||||
aux-data.obj \
|
||||
$(TOPDIR)\win32\versioninfo.res
|
||||
|
||||
all: $(TOPDIR)\win32\versioninfo.res $(TARGET)
|
||||
|
|
|
@ -256,9 +256,11 @@ int
|
|||
sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
|
||||
{
|
||||
if ((apdu->cse & ~SC_APDU_SHORT_MASK) == 0) {
|
||||
/* length check for short APDU */
|
||||
if (apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0))
|
||||
/* length check for short APDU */
|
||||
if (apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0)) {
|
||||
sc_log(card->ctx, "failed length check for short APDU");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if ((apdu->cse & SC_APDU_EXT) != 0) {
|
||||
/* check if the card supports extended APDUs */
|
||||
|
@ -267,8 +269,10 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
|
|||
goto error;
|
||||
}
|
||||
/* length check for extended APDU */
|
||||
if (apdu->le > 65536 || apdu->lc > 65535)
|
||||
if (apdu->le > 65536 || apdu->lc > 65535) {
|
||||
sc_log(card->ctx, "failed length check for extended APDU");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
goto error;
|
||||
|
@ -281,7 +285,7 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
|
|||
goto error;
|
||||
break;
|
||||
case SC_APDU_CASE_2_SHORT:
|
||||
/* no data is sent */
|
||||
/* no data is sent */
|
||||
if (apdu->datalen != 0 || apdu->lc != 0)
|
||||
goto error;
|
||||
/* data is expected */
|
||||
|
@ -293,7 +297,7 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
|
|||
goto error;
|
||||
break;
|
||||
case SC_APDU_CASE_3_SHORT:
|
||||
/* data is sent */
|
||||
/* data is sent */
|
||||
if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
|
||||
goto error;
|
||||
/* no data is expected */
|
||||
|
@ -304,7 +308,7 @@ sc_check_apdu(sc_card_t *card, const sc_apdu_t *apdu)
|
|||
goto error;
|
||||
break;
|
||||
case SC_APDU_CASE_4_SHORT:
|
||||
/* data is sent */
|
||||
/* data is sent */
|
||||
if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
|
||||
goto error;
|
||||
/* data is expected */
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* aux-data.c: Auxiliary data help functions
|
||||
*
|
||||
* Copyright (C) 2016 Viktor Tarasov <viktor.tarasov@gmail.com>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "common/compat_strlcat.h"
|
||||
|
||||
#include <libopensc/errors.h>
|
||||
#include <libopensc/types.h>
|
||||
#include <libopensc/log.h>
|
||||
#include <libopensc/aux-data.h>
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_allocate(struct sc_context *ctx, struct sc_auxiliary_data **dst, struct sc_auxiliary_data *src)
|
||||
{
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if (!dst)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot allocate auxiliary data");
|
||||
|
||||
if (*dst == NULL) {
|
||||
*dst = calloc(1, sizeof(struct sc_auxiliary_data));
|
||||
if (*dst == NULL)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "Cannot allocate aux. data");
|
||||
}
|
||||
|
||||
if ((src == NULL) || (src->type == SC_AUX_DATA_TYPE_NO_DATA))
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
switch(src->type) {
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
**dst = *src;
|
||||
rv = SC_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid aux-data type %X", src->type);
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unknown aux-data type");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_set_md_guid(struct sc_context *ctx, struct sc_auxiliary_data *aux_data, char *guid)
|
||||
{
|
||||
struct sc_md_cmap_record *rec;
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if (!aux_data || !guid || strlen(guid) > SC_MD_MAX_CONTAINER_NAME_LEN)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot set guid for MD container");
|
||||
|
||||
switch(aux_data->type) {
|
||||
case SC_AUX_DATA_TYPE_NO_DATA:
|
||||
memset(aux_data, 0, sizeof(*aux_data));
|
||||
aux_data->type = SC_AUX_DATA_TYPE_MD_CMAP_RECORD;
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
rec = &aux_data->data.cmap_record;
|
||||
memcpy(rec->guid, guid, strlen(guid));
|
||||
rec->guid_len = strlen(guid);
|
||||
sc_log(ctx, "set MD container GUID '%s'", aux_data->data.cmap_record.guid);
|
||||
rv = SC_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid aux-data type %X", aux_data->type);
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unknown aux-data type");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_set_md_flags(struct sc_context *ctx, struct sc_auxiliary_data *aux_data, unsigned char flags)
|
||||
{
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if (!aux_data)
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Cannot set flags of MD container");
|
||||
|
||||
switch(aux_data->type) {
|
||||
case SC_AUX_DATA_TYPE_NO_DATA:
|
||||
memset(aux_data, 0, sizeof(*aux_data));
|
||||
aux_data->type = SC_AUX_DATA_TYPE_MD_CMAP_RECORD;
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
aux_data->data.cmap_record.flags = flags;
|
||||
sc_log(ctx, "set MD container flags '0x%X'", flags);
|
||||
rv = SC_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
sc_log(ctx, "Invalid aux-data type %X", aux_data->type);
|
||||
LOG_TEST_RET(ctx, SC_ERROR_INVALID_ARGUMENTS, "Unknown aux-data type");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_get_md_guid(struct sc_context *ctx, struct sc_auxiliary_data *aux_data,
|
||||
unsigned flags, unsigned char *out, size_t *out_size)
|
||||
{
|
||||
struct sc_md_cmap_record *cmap_record = NULL;
|
||||
char guid[SC_MD_MAX_CONTAINER_NAME_LEN + 3];
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if(!aux_data || !out || !out_size)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
cmap_record = &aux_data->data.cmap_record;
|
||||
|
||||
/* Ignore silently request of '{}' frame is output buffer is too small */
|
||||
if (!flags && *out_size < strlen((char *)cmap_record->guid) + 2)
|
||||
flags = 1;
|
||||
|
||||
*guid = '\0';
|
||||
if (!flags)
|
||||
strcpy(guid, "{");
|
||||
strlcat(guid, (char *)cmap_record->guid, sizeof(guid)-1);
|
||||
if (!flags)
|
||||
strlcat(guid, "}", sizeof(guid));
|
||||
|
||||
if (*out_size < strlen(guid)) {
|
||||
sc_log(ctx, "aux-data: buffer too small: out_size:%i < guid-length:%i", *out_size, strlen(guid));
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_BUFFER_TOO_SMALL);
|
||||
}
|
||||
|
||||
memset(out, 0, *out_size);
|
||||
memcpy(out, guid, strlen(guid));
|
||||
*out_size = strlen(guid);
|
||||
|
||||
sc_log(ctx, "aux-data: returns guid '%s'", (char *)out);
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_aux_data_get_md_flags(struct sc_context *ctx, struct sc_auxiliary_data *aux_data,
|
||||
unsigned char *flags)
|
||||
{
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if(!aux_data || !flags)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
*flags = aux_data->data.cmap_record.flags;
|
||||
|
||||
sc_log(ctx, "aux-data: returns flags '0x%X'", *flags);
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sc_aux_data_free(struct sc_auxiliary_data **data)
|
||||
{
|
||||
if (data == NULL || *data == NULL)
|
||||
return;
|
||||
|
||||
switch((*data)->type) {
|
||||
case SC_AUX_DATA_TYPE_MD_CMAP_RECORD:
|
||||
free(*data);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
*data = NULL;
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* aux-data.h: Non PKCS#15, non ISO7816 data
|
||||
* Used to pass auxiliary data from non PKCS#15, non ISO7816 appliations (like minidriver)
|
||||
* to card specific part through the standard PKCS#15 and ISO7816 frameworks
|
||||
*
|
||||
* Copyright (C) 2016 Viktor Tarasov <viktor.tarasov@gmail.com>
|
||||
*
|
||||
* 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 _AUX_DATA_H
|
||||
#define _AUX_DATA_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "cardctl.h"
|
||||
#include "internal.h"
|
||||
#include "errors.h"
|
||||
#include "asn1.h"
|
||||
#include "types.h"
|
||||
|
||||
#define SC_AUX_DATA_TYPE_NO_DATA 0x00
|
||||
#define SC_AUX_DATA_TYPE_MD_CMAP_RECORD 0x01
|
||||
|
||||
/* From Windows Smart Card Minidriver Specification
|
||||
* Version 7.06
|
||||
*
|
||||
* #define MAX_CONTAINER_NAME_LEN 39
|
||||
* #define CONTAINER_MAP_VALID_CONTAINER 1
|
||||
* #define CONTAINER_MAP_DEFAULT_CONTAINER 2
|
||||
* typedef struct _CONTAINER_MAP_RECORD
|
||||
* {
|
||||
* WCHAR wszGuid [MAX_CONTAINER_NAME_LEN + 1];
|
||||
* BYTE bFlags;
|
||||
* BYTE bReserved;
|
||||
* WORD wSigKeySizeBits;
|
||||
* WORD wKeyExchangeKeySizeBits;
|
||||
* } CONTAINER_MAP_RECORD, *PCONTAINER_MAP_RECORD;
|
||||
*/
|
||||
#define SC_MD_MAX_CONTAINER_NAME_LEN 39
|
||||
#define SC_MD_CONTAINER_MAP_VALID_CONTAINER 0x01
|
||||
#define SC_MD_CONTAINER_MAP_DEFAULT_CONTAINER 0x02
|
||||
|
||||
struct sc_md_cmap_record {
|
||||
unsigned char guid[SC_MD_MAX_CONTAINER_NAME_LEN + 1];
|
||||
size_t guid_len;
|
||||
unsigned flags;
|
||||
unsigned keysize_sign;
|
||||
unsigned keysize_keyexchange;
|
||||
};
|
||||
|
||||
struct sc_auxiliary_data {
|
||||
unsigned type;
|
||||
union {
|
||||
struct sc_md_cmap_record cmap_record;
|
||||
} data;
|
||||
};
|
||||
|
||||
int sc_aux_data_set_md_flags(struct sc_context *, struct sc_auxiliary_data *, unsigned char);
|
||||
int sc_aux_data_allocate(struct sc_context *, struct sc_auxiliary_data **, struct sc_auxiliary_data *);
|
||||
int sc_aux_data_set_md_guid(struct sc_context *, struct sc_auxiliary_data *, char *);
|
||||
void sc_aux_data_free(struct sc_auxiliary_data **);
|
||||
int sc_aux_data_get_md_guid(struct sc_context *, struct sc_auxiliary_data *, unsigned,
|
||||
unsigned char *, size_t *);
|
||||
int sc_aux_data_get_md_flags(struct sc_context *, struct sc_auxiliary_data *, unsigned char *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ifndef _AUX_DATA_H */
|
|
@ -687,7 +687,7 @@ static void dnie_clear_cache(dnie_private_data_t * data)
|
|||
*
|
||||
* @param card pointer to card data
|
||||
*/
|
||||
static inline void init_flags(struct sc_card *card)
|
||||
static void init_flags(struct sc_card *card)
|
||||
{
|
||||
unsigned long algoflags;
|
||||
/* set up flags according documentation */
|
||||
|
|
|
@ -66,7 +66,6 @@ static struct sc_card_driver epass2003_drv = {
|
|||
|
||||
#define KEY_TYPE_AES 0x01 /* FIPS mode */
|
||||
#define KEY_TYPE_DES 0x02 /* Non-FIPS mode */
|
||||
static unsigned char g_smtype; /* sm cryption algorithm type */
|
||||
|
||||
#define KEY_LEN_AES 16
|
||||
#define KEY_LEN_DES 8
|
||||
|
@ -78,7 +77,6 @@ static unsigned char PIN_ID[2] = { ENTERSAFE_USER_PIN_ID, ENTERSAFE_SO_PIN_ID };
|
|||
/*0x00:plain; 0x01:scp01 sm*/
|
||||
#define SM_PLAIN 0x00
|
||||
#define SM_SCP01 0x01
|
||||
static unsigned char g_sm; /* if perform sm or not */
|
||||
|
||||
static unsigned char g_init_key_enc[16] = {
|
||||
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C,
|
||||
|
@ -94,9 +92,13 @@ static unsigned char g_random[8] = {
|
|||
0xBF, 0xC3, 0x29, 0x11, 0xC7, 0x18, 0xC3, 0x40
|
||||
};
|
||||
|
||||
static unsigned char g_sk_enc[16] = { 0 }; /* encrypt session key */
|
||||
static unsigned char g_sk_mac[16] = { 0 }; /* mac session key */
|
||||
static unsigned char g_icv_mac[16] = { 0 }; /* instruction counter vector(for sm) */
|
||||
typedef struct epass2003_exdata_st {
|
||||
unsigned char sm; /* SM_PLAIN or SM_SCP01 */
|
||||
unsigned char smtype; /* KEY_TYPE_AES or KEY_TYPE_DES */
|
||||
unsigned char sk_enc[16]; /* encrypt session key */
|
||||
unsigned char sk_mac[16]; /* mac session key */
|
||||
unsigned char icv_mac[16]; /* instruction counter vector(for sm) */
|
||||
} epass2003_exdata;
|
||||
|
||||
#define REVERSE_ORDER4(x) ( \
|
||||
((unsigned long)x & 0xFF000000)>> 24 | \
|
||||
|
@ -106,6 +108,19 @@ static unsigned char g_icv_mac[16] = { 0 }; /* instruction counter vector(for sm
|
|||
|
||||
static int epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu);
|
||||
static int epass2003_select_file(struct sc_card *card, const sc_path_t * in_path, sc_file_t ** file_out);
|
||||
int epass2003_refresh(struct sc_card *card);
|
||||
|
||||
static int
|
||||
sc_transmit_apdu_t(sc_card_t *card, sc_apdu_t *apdu)
|
||||
{
|
||||
int r = sc_transmit_apdu(card, apdu);
|
||||
if ( ((0x69 == apdu->sw1) && (0x85 == apdu->sw2)) || ((0x69 == apdu->sw1) && (0x88 == apdu->sw2)))
|
||||
{
|
||||
epass2003_refresh(card);
|
||||
r = sc_transmit_apdu(card, apdu);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static int
|
||||
openssl_enc(const EVP_CIPHER * cipher, const unsigned char *key, const unsigned char *iv,
|
||||
|
@ -301,6 +316,7 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma
|
|||
unsigned long blocksize = 0;
|
||||
unsigned char cryptogram[256] = { 0 }; /* host cryptogram */
|
||||
unsigned char iv[16] = { 0 };
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
|
@ -311,10 +327,10 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma
|
|||
apdu.le = apdu.resplen = 28;
|
||||
apdu.resp = result; /* card random is result[12~19] */
|
||||
|
||||
tmp_sm = g_sm;
|
||||
g_sm = SM_PLAIN;
|
||||
tmp_sm = exdata->sm;
|
||||
exdata->sm = SM_PLAIN;
|
||||
r = epass2003_transmit_apdu(card, &apdu);
|
||||
g_sm = tmp_sm;
|
||||
exdata->sm = tmp_sm;
|
||||
LOG_TEST_RET(card->ctx, r, "APDU gen_init_key failed");
|
||||
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
@ -328,12 +344,12 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma
|
|||
|
||||
/* Step 2,3 - Create S-ENC/S-MAC Session Key */
|
||||
if (KEY_TYPE_AES == key_type) {
|
||||
aes128_encrypt_ecb(key_enc, 16, data, 16, g_sk_enc);
|
||||
aes128_encrypt_ecb(key_mac, 16, data, 16, g_sk_mac);
|
||||
aes128_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc);
|
||||
aes128_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac);
|
||||
}
|
||||
else {
|
||||
des3_encrypt_ecb(key_enc, 16, data, 16, g_sk_enc);
|
||||
des3_encrypt_ecb(key_mac, 16, data, 16, g_sk_mac);
|
||||
des3_encrypt_ecb(key_enc, 16, data, 16, exdata->sk_enc);
|
||||
des3_encrypt_ecb(key_mac, 16, data, 16, exdata->sk_mac);
|
||||
}
|
||||
|
||||
memcpy(data, g_random, 8);
|
||||
|
@ -344,9 +360,9 @@ gen_init_key(struct sc_card *card, unsigned char *key_enc, unsigned char *key_ma
|
|||
|
||||
/* calculate host cryptogram */
|
||||
if (KEY_TYPE_AES == key_type)
|
||||
aes128_encrypt_cbc(g_sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
|
||||
aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
|
||||
else
|
||||
des3_encrypt_cbc(g_sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
|
||||
des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize, cryptogram);
|
||||
|
||||
/* verify card cryptogram */
|
||||
if (0 != memcmp(&cryptogram[16], &result[20], 8))
|
||||
|
@ -368,6 +384,7 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_
|
|||
unsigned char mac[256] = { 0 };
|
||||
unsigned long i;
|
||||
unsigned char tmp_sm;
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
|
@ -379,10 +396,10 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_
|
|||
|
||||
/* calculate host cryptogram */
|
||||
if (KEY_TYPE_AES == key_type) {
|
||||
aes128_encrypt_cbc(g_sk_enc, 16, iv, data, 16 + blocksize,
|
||||
aes128_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,
|
||||
cryptogram);
|
||||
} else {
|
||||
des3_encrypt_cbc(g_sk_enc, 16, iv, data, 16 + blocksize,
|
||||
des3_encrypt_cbc(exdata->sk_enc, 16, iv, data, 16 + blocksize,
|
||||
cryptogram);
|
||||
}
|
||||
|
||||
|
@ -394,15 +411,15 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_
|
|||
/* calculate mac icv */
|
||||
memset(iv, 0x00, 16);
|
||||
if (KEY_TYPE_AES == key_type) {
|
||||
aes128_encrypt_cbc(g_sk_mac, 16, iv, data, 16, mac);
|
||||
aes128_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac);
|
||||
i = 0;
|
||||
} else {
|
||||
des3_encrypt_cbc(g_sk_mac, 16, iv, data, 16, mac);
|
||||
des3_encrypt_cbc(exdata->sk_mac, 16, iv, data, 16, mac);
|
||||
i = 8;
|
||||
}
|
||||
/* save mac icv */
|
||||
memset(g_icv_mac, 0x00, 16);
|
||||
memcpy(g_icv_mac, &mac[i], 8);
|
||||
memset(exdata->icv_mac, 0x00, 16);
|
||||
memcpy(exdata->icv_mac, &mac[i], 8);
|
||||
|
||||
/* verify host cryptogram */
|
||||
memcpy(data, &cryptogram[16], 8);
|
||||
|
@ -411,10 +428,10 @@ verify_init_key(struct sc_card *card, unsigned char *ran_key, unsigned char key_
|
|||
apdu.cla = 0x84;
|
||||
apdu.lc = apdu.datalen = 16;
|
||||
apdu.data = data;
|
||||
tmp_sm = g_sm;
|
||||
g_sm = SM_PLAIN;
|
||||
tmp_sm = exdata->sm;
|
||||
exdata->sm = SM_PLAIN;
|
||||
r = epass2003_transmit_apdu(card, &apdu);
|
||||
g_sm = tmp_sm;
|
||||
exdata->sm = tmp_sm;
|
||||
LOG_TEST_RET(card->ctx, r,
|
||||
"APDU verify_init_key failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
@ -432,14 +449,15 @@ mutual_auth(struct sc_card *card, unsigned char *key_enc,
|
|||
int r;
|
||||
unsigned char result[256] = { 0 };
|
||||
unsigned char ran_key[8] = { 0 };
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
r = gen_init_key(card, key_enc, key_mac, result, g_smtype);
|
||||
r = gen_init_key(card, key_enc, key_mac, result, exdata->smtype);
|
||||
LOG_TEST_RET(ctx, r, "gen_init_key failed");
|
||||
memcpy(ran_key, &result[12], 8);
|
||||
|
||||
r = verify_init_key(card, ran_key, g_smtype);
|
||||
r = verify_init_key(card, ran_key, exdata->smtype);
|
||||
LOG_TEST_RET(ctx, r, "verify_init_key failed");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
|
@ -450,8 +468,9 @@ int
|
|||
epass2003_refresh(struct sc_card *card)
|
||||
{
|
||||
int r = SC_SUCCESS;
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
if (g_sm) {
|
||||
if (exdata->sm) {
|
||||
card->sm_ctx.sm_mode = 0;
|
||||
r = mutual_auth(card, g_init_key_enc, g_init_key_mac);
|
||||
card->sm_ctx.sm_mode = SM_MODE_TRANSMIT;
|
||||
|
@ -464,7 +483,7 @@ epass2003_refresh(struct sc_card *card)
|
|||
|
||||
/* Data(TLV)=0x87|L|0x01+Cipher */
|
||||
static int
|
||||
construct_data_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf,
|
||||
construct_data_tlv(struct sc_card *card, struct sc_apdu *apdu, unsigned char *apdu_buf,
|
||||
unsigned char *data_tlv, size_t * data_tlv_len, const unsigned char key_type)
|
||||
{
|
||||
size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
|
||||
|
@ -472,6 +491,7 @@ construct_data_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf,
|
|||
size_t pad_len;
|
||||
size_t tlv_more; /* increased tlv length */
|
||||
unsigned char iv[16] = { 0 };
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
/* padding */
|
||||
apdu_buf[block_size] = 0x87;
|
||||
|
@ -500,9 +520,9 @@ construct_data_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf,
|
|||
|
||||
/* encrypt Data */
|
||||
if (KEY_TYPE_AES == key_type)
|
||||
aes128_encrypt_cbc(g_sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
|
||||
aes128_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
|
||||
else
|
||||
des3_encrypt_cbc(g_sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
|
||||
des3_encrypt_cbc(exdata->sk_enc, 16, iv, pad, pad_len, apdu_buf + block_size + tlv_more);
|
||||
|
||||
memcpy(data_tlv + tlv_more, apdu_buf + block_size + tlv_more, pad_len);
|
||||
*data_tlv_len = tlv_more + pad_len;
|
||||
|
@ -538,7 +558,7 @@ construct_le_tlv(struct sc_apdu *apdu, unsigned char *apdu_buf, size_t data_tlv_
|
|||
|
||||
/* MAC(TLV)=0x8e|0x08|MAC */
|
||||
static int
|
||||
construct_mac_tlv(unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
|
||||
construct_mac_tlv(struct sc_card *card, unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_len,
|
||||
unsigned char *mac_tlv, size_t * mac_tlv_len, const unsigned char key_type)
|
||||
{
|
||||
size_t block_size = (KEY_TYPE_AES == key_type ? 16 : 8);
|
||||
|
@ -546,6 +566,7 @@ construct_mac_tlv(unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_le
|
|||
size_t mac_len;
|
||||
unsigned char icv[16] = { 0 };
|
||||
int i = (KEY_TYPE_AES == key_type ? 15 : 7);
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
if (0 == data_tlv_len && 0 == le_tlv_len) {
|
||||
mac_len = block_size;
|
||||
|
@ -566,29 +587,29 @@ construct_mac_tlv(unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_le
|
|||
|
||||
/* increase icv */
|
||||
for (; i >= 0; i--) {
|
||||
if (g_icv_mac[i] == 0xff) {
|
||||
g_icv_mac[i] = 0;
|
||||
if (exdata->icv_mac[i] == 0xff) {
|
||||
exdata->icv_mac[i] = 0;
|
||||
}
|
||||
else {
|
||||
g_icv_mac[i]++;
|
||||
exdata->icv_mac[i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate MAC */
|
||||
memset(icv, 0, sizeof(icv));
|
||||
memcpy(icv, g_icv_mac, 16);
|
||||
memcpy(icv, exdata->icv_mac, 16);
|
||||
if (KEY_TYPE_AES == key_type) {
|
||||
aes128_encrypt_cbc(g_sk_mac, 16, icv, apdu_buf, mac_len, mac);
|
||||
aes128_encrypt_cbc(exdata->sk_mac, 16, icv, apdu_buf, mac_len, mac);
|
||||
memcpy(mac_tlv + 2, &mac[mac_len - 16], 8);
|
||||
}
|
||||
else {
|
||||
unsigned char iv[8] = { 0 };
|
||||
unsigned char tmp[8] = { 0 };
|
||||
des_encrypt_cbc(g_sk_mac, 8, icv, apdu_buf, mac_len, mac);
|
||||
des_decrypt_cbc(&g_sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
|
||||
des_encrypt_cbc(exdata->sk_mac, 8, icv, apdu_buf, mac_len, mac);
|
||||
des_decrypt_cbc(&exdata->sk_mac[8], 8, iv, &mac[mac_len - 8], 8, tmp);
|
||||
memset(iv, 0x00, 8);
|
||||
des_encrypt_cbc(g_sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
|
||||
des_encrypt_cbc(exdata->sk_mac, 8, iv, tmp, 8, mac_tlv + 2);
|
||||
}
|
||||
|
||||
*mac_tlv_len = 2 + 8;
|
||||
|
@ -604,10 +625,11 @@ construct_mac_tlv(unsigned char *apdu_buf, size_t data_tlv_len, size_t le_tlv_le
|
|||
* where
|
||||
* Data'=Data(TLV)+Le(TLV)+MAC(TLV) */
|
||||
static int
|
||||
encode_apdu(struct sc_apdu *plain, struct sc_apdu *sm,
|
||||
encode_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_apdu *sm,
|
||||
unsigned char *apdu_buf, size_t * apdu_buf_len)
|
||||
{
|
||||
size_t block_size = (KEY_TYPE_DES == g_smtype ? 16 : 8);
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
size_t block_size = (KEY_TYPE_DES == exdata->smtype ? 16 : 8);
|
||||
unsigned char dataTLV[4096] = { 0 };
|
||||
size_t data_tlv_len = 0;
|
||||
unsigned char le_tlv[256] = { 0 };
|
||||
|
@ -635,15 +657,15 @@ encode_apdu(struct sc_apdu *plain, struct sc_apdu *sm,
|
|||
|
||||
/* Data -> Data' */
|
||||
if (plain->lc != 0)
|
||||
if (0 != construct_data_tlv(plain, apdu_buf, dataTLV, &data_tlv_len, g_smtype))
|
||||
if (0 != construct_data_tlv(card, plain, apdu_buf, dataTLV, &data_tlv_len, exdata->smtype))
|
||||
return -1;
|
||||
|
||||
if (plain->le != 0 || (plain->le == 0 && plain->resplen != 0))
|
||||
if (0 != construct_le_tlv(plain, apdu_buf, data_tlv_len, le_tlv,
|
||||
&le_tlv_len, g_smtype))
|
||||
&le_tlv_len, exdata->smtype))
|
||||
return -1;
|
||||
|
||||
if (0 != construct_mac_tlv(apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, g_smtype))
|
||||
if (0 != construct_mac_tlv(card, apdu_buf, data_tlv_len, le_tlv_len, mac_tlv, &mac_tlv_len, exdata->smtype))
|
||||
return -1;
|
||||
|
||||
memset(apdu_buf + 4, 0, *apdu_buf_len - 4);
|
||||
|
@ -688,10 +710,11 @@ epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_ap
|
|||
{
|
||||
unsigned char buf[4096] = { 0 }; /* APDU buffer */
|
||||
size_t buf_len = sizeof(buf);
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
if (g_sm)
|
||||
if (exdata->sm)
|
||||
plain->cla |= 0x0C;
|
||||
|
||||
sm->cse = plain->cse;
|
||||
|
@ -714,7 +737,7 @@ epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_ap
|
|||
break;
|
||||
case 0x0C:
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (0 != encode_apdu(plain, sm, buf, &buf_len))
|
||||
if (0 != encode_apdu(card, plain, sm, buf, &buf_len))
|
||||
return SC_ERROR_CARD_CMD_FAILED;
|
||||
break;
|
||||
default:
|
||||
|
@ -737,12 +760,13 @@ epass2003_sm_wrap_apdu(struct sc_card *card, struct sc_apdu *plain, struct sc_ap
|
|||
* SW12(TLV)=0x99|0x02|SW1+SW2
|
||||
* MAC(TLV)=0x8e|0x08|MAC */
|
||||
static int
|
||||
decrypt_response(unsigned char *in, unsigned char *out, size_t * out_len)
|
||||
decrypt_response(struct sc_card *card, unsigned char *in, unsigned char *out, size_t * out_len)
|
||||
{
|
||||
size_t in_len;
|
||||
size_t i;
|
||||
unsigned char iv[16] = { 0 };
|
||||
unsigned char plaintext[4096] = { 0 };
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
/* no cipher */
|
||||
if (in[0] == 0x99)
|
||||
|
@ -767,10 +791,10 @@ decrypt_response(unsigned char *in, unsigned char *out, size_t * out_len)
|
|||
}
|
||||
|
||||
/* decrypt */
|
||||
if (KEY_TYPE_AES == g_smtype)
|
||||
aes128_decrypt_cbc(g_sk_enc, 16, iv, &in[i], in_len - 1, plaintext);
|
||||
if (KEY_TYPE_AES == exdata->smtype)
|
||||
aes128_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], in_len - 1, plaintext);
|
||||
else
|
||||
des3_decrypt_cbc(g_sk_enc, 16, iv, &in[i], in_len - 1, plaintext);
|
||||
des3_decrypt_cbc(exdata->sk_enc, 16, iv, &in[i], in_len - 1, plaintext);
|
||||
|
||||
/* unpadding */
|
||||
while (0x80 != plaintext[in_len - 2] && (in_len - 2 > 0))
|
||||
|
@ -790,13 +814,14 @@ epass2003_sm_unwrap_apdu(struct sc_card *card, struct sc_apdu *sm, struct sc_apd
|
|||
{
|
||||
int r;
|
||||
size_t len = 0;
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
r = sc_check_sw(card, sm->sw1, sm->sw2);
|
||||
if (r == SC_SUCCESS) {
|
||||
if (g_sm) {
|
||||
if (0 != decrypt_response(sm->resp, plain->resp, &len))
|
||||
if (exdata->sm) {
|
||||
if (0 != decrypt_response(card, sm->resp, plain->resp, &len))
|
||||
return SC_ERROR_CARD_CMD_FAILED;
|
||||
}
|
||||
else {
|
||||
|
@ -899,7 +924,7 @@ epass2003_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
|
|||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
r = sc_transmit_apdu(card, apdu);
|
||||
r = sc_transmit_apdu_t(card, apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
|
||||
return r;
|
||||
|
@ -913,6 +938,7 @@ get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t d
|
|||
struct sc_apdu apdu;
|
||||
unsigned char resp[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
|
||||
size_t resplen = SC_MAX_APDU_BUFFER_SIZE;
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
|
@ -922,13 +948,13 @@ get_data(struct sc_card *card, unsigned char type, unsigned char *data, size_t d
|
|||
apdu.resplen = resplen;
|
||||
if (0x86 == type) {
|
||||
/* No SM temporarily */
|
||||
unsigned char tmp_sm = g_sm;
|
||||
g_sm = SM_PLAIN;
|
||||
unsigned char tmp_sm = exdata->sm;
|
||||
exdata->sm = SM_PLAIN;
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
g_sm = tmp_sm;
|
||||
exdata->sm = tmp_sm;
|
||||
}
|
||||
else {
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
}
|
||||
LOG_TEST_RET(card->ctx, r, "APDU get_data failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
@ -959,24 +985,27 @@ epass2003_init(struct sc_card *card)
|
|||
unsigned int flags;
|
||||
unsigned char data[SC_MAX_APDU_BUFFER_SIZE] = { 0 };
|
||||
size_t datalen = SC_MAX_APDU_BUFFER_SIZE;
|
||||
epass2003_exdata *exdata = NULL;
|
||||
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
|
||||
card->name = "epass2003";
|
||||
card->cla = 0x00;
|
||||
card->drv_data = NULL;
|
||||
|
||||
g_sm = SM_SCP01;
|
||||
/* g_sm = SM_PLAIN; */
|
||||
exdata = (epass2003_exdata *)calloc(1, sizeof(epass2003_exdata));
|
||||
if (!exdata)
|
||||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
card->drv_data = exdata;
|
||||
|
||||
exdata->sm = SM_SCP01;
|
||||
|
||||
/* decide FIPS/Non-FIPS mode */
|
||||
if (SC_SUCCESS != get_data(card, 0x86, data, datalen))
|
||||
return SC_ERROR_CARD_CMD_FAILED;
|
||||
|
||||
if (0x01 == data[2])
|
||||
g_smtype = KEY_TYPE_AES;
|
||||
exdata->smtype = KEY_TYPE_AES;
|
||||
else
|
||||
g_smtype = KEY_TYPE_DES;
|
||||
exdata->smtype = KEY_TYPE_DES;
|
||||
|
||||
/* mutual authentication */
|
||||
card->max_recv_size = 0xD8;
|
||||
|
@ -1003,6 +1032,15 @@ epass2003_init(struct sc_card *card)
|
|||
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
epass2003_finish(sc_card_t *card)
|
||||
{
|
||||
epass2003_exdata *exdata = (epass2003_exdata *)card->drv_data;
|
||||
|
||||
if (exdata)
|
||||
free(exdata);
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
/* COS implement SFI as lower 5 bits of FID, and not allow same SFI at the
|
||||
* same DF, so use hook functions to increase/decrease FID by 0x20 */
|
||||
|
@ -1096,7 +1134,7 @@ epass2003_select_fid_(struct sc_card *card, sc_path_t * in_path, sc_file_t ** fi
|
|||
apdu.sw2 = 0x00;
|
||||
}
|
||||
else {
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
}
|
||||
|
||||
|
@ -1390,7 +1428,7 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env,
|
|||
locked = 1;
|
||||
}
|
||||
if (apdu.datalen != 0) {
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
if (r) {
|
||||
sc_log(card->ctx, "%s: APDU transmit failed", sc_strerror(r));
|
||||
goto err;
|
||||
|
@ -1406,7 +1444,7 @@ epass2003_set_security_env(struct sc_card *card, const sc_security_env_t * env,
|
|||
return 0;
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF2, se_num);
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
sc_unlock(card);
|
||||
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
|
@ -1445,7 +1483,7 @@ static int epass2003_decipher(struct sc_card *card, const u8 * data, size_t data
|
|||
apdu.lc = datalen;
|
||||
apdu.datalen = datalen;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
|
||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||
|
@ -1805,7 +1843,7 @@ epass2003_create_file(struct sc_card *card, sc_file_t * file)
|
|||
apdu.datalen = len;
|
||||
apdu.data = sbuf;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU sw1/2 wrong");
|
||||
|
@ -1838,7 +1876,7 @@ epass2003_delete_file(struct sc_card *card, const sc_path_t * path)
|
|||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "Delete file failed");
|
||||
|
@ -1860,7 +1898,7 @@ epass2003_list_files(struct sc_card *card, unsigned char *buf, size_t buflen)
|
|||
apdu.resplen = sizeof(rbuf);
|
||||
apdu.resp = rbuf;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
|
@ -1896,7 +1934,7 @@ internal_write_rsa_key_factor(struct sc_card *card, unsigned short fid, u8 facto
|
|||
apdu.lc = apdu.datalen = 2 + data.len;
|
||||
apdu.data = sbuff;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "Write rsa key factor failed");
|
||||
|
@ -1969,7 +2007,7 @@ install_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
|
|||
apdu.lc = apdu.datalen = 10 + dataLen;
|
||||
apdu.data = tmp_data;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU install_secret_key failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "install_secret_key failed");
|
||||
|
@ -2071,7 +2109,7 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
|
|||
apdu.lc = apdu.datalen = 7;
|
||||
apdu.data = sbuf;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "generate keypair failed");
|
||||
|
@ -2085,7 +2123,7 @@ epass2003_gen_key(struct sc_card *card, sc_epass2003_gen_key_data * data)
|
|||
apdu.resplen = sizeof(rbuf);
|
||||
apdu.le = 0x00;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "get pukey failed");
|
||||
|
@ -2207,7 +2245,7 @@ get_external_key_retries(struct sc_card *card, unsigned char kid, unsigned char
|
|||
apdu.resp = NULL;
|
||||
apdu.resplen = 0;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU get_external_key_retries failed");
|
||||
|
||||
if (retries && ((0x63 == (apdu.sw1 & 0xff)) && (0xC0 == (apdu.sw2 & 0xf0)))) {
|
||||
|
@ -2245,7 +2283,7 @@ external_key_auth(struct sc_card *card, unsigned char kid,
|
|||
apdu.lc = apdu.datalen = 8;
|
||||
apdu.data = tmp_data;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU external_key_auth failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "external_key_auth failed");
|
||||
|
@ -2277,7 +2315,7 @@ update_secret_key(struct sc_card *card, unsigned char ktype, unsigned char kid,
|
|||
apdu.lc = apdu.datalen = 1 + HASH_LEN;
|
||||
apdu.data = tmp_data;
|
||||
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
r = sc_transmit_apdu_t(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU update_secret_key failed");
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "update_secret_key failed");
|
||||
|
@ -2351,6 +2389,7 @@ static struct sc_card_driver *sc_get_driver(void)
|
|||
|
||||
epass2003_ops.match_card = epass2003_match_card;
|
||||
epass2003_ops.init = epass2003_init;
|
||||
epass2003_ops.finish = epass2003_finish;
|
||||
epass2003_ops.write_binary = NULL;
|
||||
epass2003_ops.write_record = NULL;
|
||||
epass2003_ops.select_file = epass2003_select_file;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -546,6 +546,11 @@ static int sc_hsm_compute_signature(sc_card_t *card,
|
|||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_OBJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
// check if datalen exceeds the buffer size
|
||||
if (datalen > SC_MAX_APDU_BUFFER_SIZE) {
|
||||
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
}
|
||||
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_4, 0x68, priv->env->key_ref[0], priv->algorithm);
|
||||
apdu.cla = 0x80;
|
||||
apdu.resp = rbuf;
|
||||
|
|
|
@ -215,6 +215,7 @@ static int setcos_init(sc_card_t *card)
|
|||
_sc_card_add_rsa_alg(card, 512, flags, 0);
|
||||
_sc_card_add_rsa_alg(card, 768, flags, 0);
|
||||
_sc_card_add_rsa_alg(card, 1024, flags, 0);
|
||||
_sc_card_add_rsa_alg(card, 2048, flags, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1229,8 +1229,6 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo
|
|||
#ifdef _WIN32
|
||||
char temp_path[PATH_MAX];
|
||||
int temp_len;
|
||||
long rc;
|
||||
HKEY hKey;
|
||||
const char path_delim = '\\';
|
||||
#else
|
||||
const char path_delim = '/';
|
||||
|
@ -1243,25 +1241,12 @@ sc_card_sm_load(struct sc_card *card, const char *module_path, const char *in_mo
|
|||
return sc_card_sm_unload(card);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!module_path) {
|
||||
rc = RegOpenKeyExA( HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey );
|
||||
if( rc == ERROR_SUCCESS ) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueExA( hKey, "SmDir", NULL, NULL, (LPBYTE) temp_path, &temp_len);
|
||||
if( (rc == ERROR_SUCCESS) && (temp_len < PATH_MAX) )
|
||||
module_path = temp_path;
|
||||
RegCloseKey( hKey );
|
||||
}
|
||||
}
|
||||
if (!module_path) {
|
||||
rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey );
|
||||
if( rc == ERROR_SUCCESS ) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueExA( hKey, "SmDir", NULL, NULL, (LPBYTE) temp_path, &temp_len);
|
||||
if(rc == ERROR_SUCCESS && temp_len < PATH_MAX)
|
||||
module_path = temp_path;
|
||||
RegCloseKey( hKey );
|
||||
}
|
||||
if (!module_path) {
|
||||
temp_len = PATH_MAX;
|
||||
rv = sc_ctx_win32_get_config_value(NULL, "SmDir", "Software\\OpenSC Project\\OpenSC",
|
||||
temp_path, &temp_len);
|
||||
if (rv == SC_SUCCESS)
|
||||
module_path = temp_path;
|
||||
}
|
||||
#endif
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "SM module '%s' located in '%s'", in_module, module_path);
|
||||
|
|
|
@ -54,6 +54,8 @@ int _sc_delete_reader(sc_context_t *ctx, sc_reader_t *reader)
|
|||
reader->ops->release(reader);
|
||||
if (reader->name)
|
||||
free(reader->name);
|
||||
if (reader->vendor)
|
||||
free(reader->vendor);
|
||||
list_delete(&ctx->readers, reader);
|
||||
free(reader);
|
||||
return SC_SUCCESS;
|
||||
|
@ -129,6 +131,72 @@ struct _sc_ctx_options {
|
|||
};
|
||||
|
||||
|
||||
int
|
||||
sc_ctx_win32_get_config_value(char *name_env, char *name_reg, char *name_key,
|
||||
char *out, size_t *out_len)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
char temp[PATH_MAX + 1];
|
||||
char *value = NULL;
|
||||
int temp_len = PATH_MAX;
|
||||
int rv = SC_ERROR_INTERNAL;
|
||||
long rc;
|
||||
HKEY hKey;
|
||||
|
||||
if (!out || !out_len)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
if (name_env) {
|
||||
value = getenv(name_env);
|
||||
if (value)
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!name_reg)
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
if (!name_key)
|
||||
name_key = "Software\\OpenSC Project\\OpenSC";
|
||||
|
||||
rc = RegOpenKeyExA(HKEY_CURRENT_USER, name_key, 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueEx( hKey, name_reg, NULL, NULL, (LPBYTE) temp, &temp_len);
|
||||
if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
|
||||
value = temp;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
|
||||
if (!value) {
|
||||
rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, name_key, 0, KEY_QUERY_VALUE, &hKey );
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueEx( hKey, name_reg, NULL, NULL, (LPBYTE) temp, &temp_len);
|
||||
if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
|
||||
value = temp;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
if (value) {
|
||||
if (strlen(value) >= *out_len)
|
||||
return SC_ERROR_BUFFER_TOO_SMALL;
|
||||
strcpy(out, value);
|
||||
*out_len = strlen(out);
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
memset(out, 0, *out_len);
|
||||
*out_len = 0;
|
||||
|
||||
return SC_ERROR_OBJECT_NOT_FOUND;
|
||||
#else
|
||||
return SC_ERROR_NOT_SUPPORTED;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Simclist helper to locate readers by name */
|
||||
static int reader_list_seeker(const void *el, const void *key) {
|
||||
const struct sc_reader *reader = (struct sc_reader *)el;
|
||||
|
@ -290,34 +358,6 @@ load_parameters(sc_context_t *ctx, scconf_block *block, struct _sc_ctx_options *
|
|||
return err;
|
||||
}
|
||||
|
||||
static void load_reader_driver_options(sc_context_t *ctx)
|
||||
{
|
||||
struct sc_reader_driver *driver = ctx->reader_driver;
|
||||
scconf_block *conf_block = NULL;
|
||||
sc_reader_t *reader;
|
||||
int max_send_size;
|
||||
int max_recv_size;
|
||||
|
||||
conf_block = sc_get_conf_block(ctx, "reader_driver", driver->short_name, 1);
|
||||
|
||||
if (conf_block != NULL) {
|
||||
max_send_size = scconf_get_int(conf_block, "max_send_size", -1);
|
||||
max_recv_size = scconf_get_int(conf_block, "max_recv_size", -1);
|
||||
if (max_send_size >= 0 || max_recv_size >= 0) {
|
||||
if (list_iterator_start(&ctx->readers)) {
|
||||
reader = list_iterator_next(&ctx->readers);
|
||||
while (reader) {
|
||||
if (max_send_size >= 0)
|
||||
reader->max_send_size = max_send_size;
|
||||
if (max_recv_size >= 0)
|
||||
reader->max_recv_size = max_recv_size;
|
||||
reader = list_iterator_next(&ctx->readers);
|
||||
}
|
||||
list_iterator_stop(&ctx->readers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* find library module for provided driver in configuration file
|
||||
|
@ -325,8 +365,8 @@ static void load_reader_driver_options(sc_context_t *ctx)
|
|||
*/
|
||||
static const char *find_library(sc_context_t *ctx, const char *name)
|
||||
{
|
||||
int i, log_warning;
|
||||
const char *libname = NULL;
|
||||
int i, log_warning;
|
||||
const char *libname = NULL;
|
||||
scconf_block **blocks, *blk;
|
||||
|
||||
for (i = 0; ctx->conf_blocks[i]; i++) {
|
||||
|
@ -403,7 +443,7 @@ static void *load_dynamic_driver(sc_context_t *ctx, void **dll, const char *name
|
|||
}
|
||||
|
||||
static int load_card_driver_options(sc_context_t *ctx,
|
||||
struct sc_card_driver *driver)
|
||||
struct sc_card_driver *driver)
|
||||
{
|
||||
scconf_block **blocks, *blk;
|
||||
int i;
|
||||
|
@ -566,8 +606,6 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
|
|||
#ifdef _WIN32
|
||||
char temp_path[PATH_MAX];
|
||||
DWORD temp_len;
|
||||
long rc;
|
||||
HKEY hKey;
|
||||
#endif
|
||||
|
||||
/* Takes effect even when no config around */
|
||||
|
@ -577,34 +615,14 @@ static void process_config_file(sc_context_t *ctx, struct _sc_ctx_options *opts)
|
|||
|
||||
memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks));
|
||||
#ifdef _WIN32
|
||||
conf_path = getenv("OPENSC_CONF");
|
||||
if (!conf_path) {
|
||||
rc = RegOpenKeyExA(HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueEx( hKey, "ConfigFile", NULL, NULL, (LPBYTE) temp_path, &temp_len);
|
||||
if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
|
||||
conf_path = temp_path;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (!conf_path) {
|
||||
rc = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey );
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueEx( hKey, "ConfigFile", NULL, NULL, (LPBYTE) temp_path, &temp_len);
|
||||
if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
|
||||
conf_path = temp_path;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
|
||||
if (!conf_path) {
|
||||
temp_len = PATH_MAX;
|
||||
r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\OpenSC Project\\OpenSC",
|
||||
temp_path, &temp_len);
|
||||
if (r) {
|
||||
sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key.");
|
||||
return;
|
||||
}
|
||||
|
||||
conf_path = temp_path;
|
||||
#else
|
||||
conf_path = getenv("OPENSC_CONF");
|
||||
if (!conf_path)
|
||||
|
@ -780,7 +798,6 @@ int sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm)
|
|||
}
|
||||
del_drvs(&opts);
|
||||
sc_ctx_detect_readers(ctx);
|
||||
load_reader_driver_options(ctx);
|
||||
*ctx_out = ctx;
|
||||
|
||||
return SC_SUCCESS;
|
||||
|
|
|
@ -892,6 +892,9 @@ iso7816_compute_signature(struct sc_card *card,
|
|||
struct sc_apdu apdu;
|
||||
|
||||
assert(card != NULL && data != NULL && out != NULL);
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
sc_log(card->ctx, "ISO7816 compute signature: in-len %i, out-len %i",
|
||||
datalen, outlen);
|
||||
|
||||
/* INS: 0x2A PERFORM SECURITY OPERATION
|
||||
* P1: 0x9E Resp: Digital Signature
|
||||
|
@ -908,9 +911,8 @@ iso7816_compute_signature(struct sc_card *card,
|
|||
fixup_transceive_length(card, &apdu);
|
||||
r = sc_transmit_apdu(card, &apdu);
|
||||
LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
|
||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
|
||||
if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
|
||||
LOG_FUNC_RETURN(card->ctx, apdu.resplen);
|
||||
}
|
||||
|
||||
r = sc_check_sw(card, apdu.sw1, apdu.sw2);
|
||||
LOG_TEST_RET(card->ctx, r, "Card returned error");
|
||||
|
@ -924,12 +926,13 @@ iso7816_decipher(struct sc_card *card,
|
|||
const u8 * crgram, size_t crgram_len,
|
||||
u8 * out, size_t outlen)
|
||||
{
|
||||
int r;
|
||||
int r;
|
||||
struct sc_apdu apdu;
|
||||
u8 *sbuf = NULL;
|
||||
u8 *sbuf = NULL;
|
||||
|
||||
assert(card != NULL && crgram != NULL && out != NULL);
|
||||
SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_NORMAL);
|
||||
LOG_FUNC_CALLED(card->ctx);
|
||||
sc_log(card->ctx, "ISO7816 decipher: in-len %i, out-len %i", crgram_len, outlen);
|
||||
|
||||
sbuf = malloc(crgram_len + 1);
|
||||
if (sbuf == NULL)
|
||||
|
|
|
@ -53,6 +53,11 @@ sc_asn1_verify_tag
|
|||
sc_asn1_write_element
|
||||
sc_asn1_sig_value_sequence_to_rs
|
||||
sc_asn1_sig_value_rs_to_sequence
|
||||
sc_aux_data_set_md_flags
|
||||
sc_aux_data_allocate
|
||||
sc_aux_data_set_md_guid
|
||||
sc_aux_data_free
|
||||
sc_aux_data_get_md_guid
|
||||
sc_base64_decode
|
||||
sc_base64_encode
|
||||
sc_bin_to_hex
|
||||
|
@ -77,6 +82,7 @@ sc_ctx_get_reader_by_name
|
|||
sc_ctx_get_reader_count
|
||||
sc_ctx_log_to_file
|
||||
sc_ctx_use_reader
|
||||
sc_ctx_win32_get_config_value
|
||||
_sc_delete_reader
|
||||
sc_decipher
|
||||
sc_delete_file
|
||||
|
|
|
@ -294,6 +294,10 @@ struct sc_reader_driver {
|
|||
#define SC_READER_CAP_PACE_DESTROY_CHANNEL 0x00000010
|
||||
#define SC_READER_CAP_PACE_GENERIC 0x00000020
|
||||
|
||||
/* reader send/receive length of short APDU */
|
||||
#define SC_READER_SHORT_APDU_MAX_SEND_SIZE 255
|
||||
#define SC_READER_SHORT_APDU_MAX_RECV_SIZE 256
|
||||
|
||||
typedef struct sc_reader {
|
||||
struct sc_context *ctx;
|
||||
const struct sc_reader_driver *driver;
|
||||
|
@ -776,6 +780,16 @@ int sc_release_context(sc_context_t *ctx);
|
|||
*/
|
||||
int sc_ctx_detect_readers(sc_context_t *ctx);
|
||||
|
||||
/**
|
||||
* In windows: get configuration option from environment or from registers.
|
||||
* @param env name of environment variable
|
||||
* @param reg name of register value
|
||||
* @param key path of register key
|
||||
* @return SC_SUCCESS on success and an error code otherwise.
|
||||
*/
|
||||
int sc_ctx_win32_get_config_value(char *env, char *reg, char *key, char *out,
|
||||
size_t *out_size);
|
||||
|
||||
/**
|
||||
* Returns a pointer to the specified sc_reader_t object
|
||||
* @param ctx OpenSC context
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "libopensc/pkcs15.h"
|
||||
#include "libopensc/log.h"
|
||||
|
||||
int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, int);
|
||||
|
||||
|
@ -306,7 +306,8 @@ static int actalis_detect_card(sc_pkcs15_card_t * p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t * p15card,
|
||||
sc_pkcs15emu_opt_t * opts)
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t * opts)
|
||||
{
|
||||
if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
|
||||
return sc_pkcs15emu_actalis_init(p15card);
|
||||
|
|
|
@ -421,7 +421,7 @@ static struct sc_asn1_pkcs15_algorithm_info algorithm_table[] = {
|
|||
asn1_encode_ec_params,
|
||||
asn1_free_ec_params },
|
||||
#endif
|
||||
/* TODO: -DEE Not clear of we need the next five or not */
|
||||
/* TODO: -DEE Not clear if we need the next five or not */
|
||||
#ifdef SC_ALGORITHM_ECDSA_SHA1
|
||||
/* Note RFC 3279 says no ecParameters */
|
||||
{ SC_ALGORITHM_ECDSA_SHA1, {{ 1, 2, 840, 10045, 4, 1, -1}}, NULL, NULL, NULL},
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
#define MANU_ID "A-Trust"
|
||||
#define CARD_LABEL "a.sign Premium a"
|
||||
|
||||
int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *, struct sc_aid *aid, sc_pkcs15emu_opt_t *);
|
||||
|
||||
typedef struct cdata_st {
|
||||
const char *label;
|
||||
|
@ -127,7 +127,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card)
|
|||
};
|
||||
|
||||
const prdata prkeys[] = {
|
||||
{ "1", "SK.CH.EKEY", 1536,
|
||||
{ "01", "SK.CH.EKEY", 1536,
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
"", /* do not specify file here to prevent reset of security state */
|
||||
0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
|
@ -265,6 +265,7 @@ static int sc_pkcs15emu_atrust_acos_init(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
|
||||
|
|
|
@ -261,6 +261,7 @@ static int sc_pkcs15emu_dnie_init(sc_pkcs15_card_t * p15card)
|
|||
/* public functions for in-built module */
|
||||
/****************************************/
|
||||
int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t * p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t * opts)
|
||||
{
|
||||
int r=SC_SUCCESS;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
#define MANU_ID "entersafe"
|
||||
|
||||
int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int entersafe_detect_card( sc_pkcs15_card_t *p15card)
|
||||
{
|
||||
|
@ -77,6 +77,7 @@ static int sc_pkcs15emu_entersafe_init( sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
SC_FUNC_CALLED(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE);
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "pkcs15.h"
|
||||
#include "esteid.h"
|
||||
|
||||
int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static void
|
||||
set_string (char **strp, const char *value)
|
||||
|
@ -269,6 +269,7 @@ static int esteid_detect_card(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#define MANU_ID "GemSAFE on GPK16000"
|
||||
|
||||
int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int (*pin_cmd_save)(struct sc_card *, struct sc_pin_cmd_data *,
|
||||
int *tries_left);
|
||||
|
@ -182,7 +182,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
|
|||
};
|
||||
|
||||
const pindata pins[] = {
|
||||
{ "1", "pin", "3F000200", 0x00,
|
||||
{ "01", "pin", "3F000200", 0x00,
|
||||
SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
|
||||
8, 4, 8, SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
|
||||
SC_PKCS15_PIN_FLAG_LOCAL, -1, 0x00,
|
||||
|
@ -191,8 +191,8 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
|
|||
};
|
||||
|
||||
const prdata prkeys[] = {
|
||||
{ "1", "AUTH key", 1024, USAGE_AUT, "I0009",
|
||||
0x00, "1", 0},
|
||||
{ "01", "AUTH key", 1024, USAGE_AUT, "I0009",
|
||||
0x00, "01", 0},
|
||||
{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
|
@ -283,7 +283,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
kinfo[num_keyinfo].fileid = i;
|
||||
sc_pkcs15_format_id("NONE", &kinfo[num_keyinfo].id);
|
||||
sc_pkcs15_format_id("", &kinfo[num_keyinfo].id);
|
||||
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL,"reading modulus");
|
||||
r = sc_read_record(card, 2, modulus_buf,
|
||||
|
@ -506,7 +506,7 @@ static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
|
|||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card,
|
||||
int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
sc_card_t *card = p15card->card;
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#define GEMSAFE_READ_QUANTUM 248
|
||||
#define GEMSAFE_MAX_OBJLEN 28672
|
||||
|
||||
int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *, struct sc_aid *,sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int
|
||||
sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card,
|
||||
|
@ -434,6 +434,7 @@ static int sc_pkcs15emu_gemsafeV1_init( sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_gemsafeV1_init_ex( sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
|
||||
|
|
|
@ -221,6 +221,7 @@ static int sc_pkcs15emu_gids_init (sc_pkcs15_card_t * p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
if (opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
|
||||
|
@ -236,6 +237,7 @@ int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card,
|
|||
#else
|
||||
|
||||
int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
return SC_ERROR_WRONG_CARD;
|
||||
|
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* PKCS15 emulation layer for IAS/ECC card.
|
||||
*
|
||||
* Copyright (C) 2016, Viktor Tarasov <viktor.tarasov@gmail.com>
|
||||
* Copyright (C) 2004, Bud P. Bruegger <bud@comune.grosseto.it>
|
||||
* Copyright (C) 2004, Antonino Iacono <ant_iacono@tin.it>
|
||||
* Copyright (C) 2003, Olaf Kirch <okir@suse.de>
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#ifdef ENABLE_OPENSSL
|
||||
#include <openssl/x509v3.h>
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
#include "pkcs15.h"
|
||||
#include "iasecc.h"
|
||||
#include "aux-data.h"
|
||||
|
||||
#define IASECC_GEMALTO_MD_APPLICAITON_NAME "CSP"
|
||||
#define IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL "Default Key Container"
|
||||
|
||||
static int
|
||||
_iasecc_md_update_keyinfo(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *dobj, int default_cont)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_prkey_info *prkey_info = NULL;
|
||||
struct sc_pkcs15_object *prkey_object = NULL;
|
||||
struct sc_pkcs15_data *ddata = NULL;
|
||||
struct sc_pkcs15_id id;
|
||||
int rv, offs;
|
||||
unsigned flags;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if (!dobj)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobj->data, &ddata);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to read container DATA object data");
|
||||
|
||||
offs = 0;
|
||||
rv = SC_ERROR_INVALID_DATA;
|
||||
if (*(ddata->data + offs++) != 0x01) {
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
id.len = *(ddata->data + offs++);
|
||||
memcpy(id.value, ddata->data + offs, id.len);
|
||||
offs += (int) id.len;
|
||||
|
||||
if (*(ddata->data + offs++) != 0x02) {
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
|
||||
}
|
||||
if (*(ddata->data + offs++) != 0x01) {
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
|
||||
}
|
||||
|
||||
flags = *(ddata->data + offs);
|
||||
if (default_cont)
|
||||
flags |= SC_MD_CONTAINER_MAP_DEFAULT_CONTAINER;
|
||||
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
|
||||
rv = sc_pkcs15_find_prkey_by_id(p15card, &id, &prkey_object);
|
||||
LOG_TEST_RET(ctx, rv, "Find related PrKey error");
|
||||
|
||||
prkey_info = (struct sc_pkcs15_prkey_info *)prkey_object->data;
|
||||
if (prkey_info->aux_data == NULL) {
|
||||
rv = sc_aux_data_allocate(ctx, &prkey_info->aux_data, NULL);
|
||||
LOG_TEST_RET(ctx, rv, "Cannot allocate MD auxiliary data");
|
||||
}
|
||||
|
||||
rv = sc_aux_data_set_md_guid(ctx, prkey_info->aux_data, dobj->label);
|
||||
LOG_TEST_RET(ctx, rv, "Cannot set MD CMAP Guid");
|
||||
|
||||
rv = sc_aux_data_set_md_flags(ctx, prkey_info->aux_data, flags);
|
||||
LOG_TEST_RET(ctx, rv, "Cannot set MD CMAP record flags");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_iasecc_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_object *dobjs[32];
|
||||
struct sc_pkcs15_data *default_guid = NULL;
|
||||
int rv, ii, count;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if (!df)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (df->enumerated)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
rv = sc_pkcs15_parse_df(p15card, df);
|
||||
LOG_TEST_RET(ctx, rv, "DF parse error");
|
||||
|
||||
if (p15card->card->type != SC_CARD_TYPE_IASECC_GEMALTO)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
if (df->type != SC_PKCS15_PRKDF)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
sc_log(ctx, "parse of SC_PKCS15_PRKDF");
|
||||
|
||||
rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_DATA_OBJECT, dobjs, sizeof(dobjs)/sizeof(dobjs[0]));
|
||||
LOG_TEST_RET(ctx, rv, "Cannot get DATA objects list");
|
||||
|
||||
count = rv;
|
||||
for(ii=0; ii<count; ii++) {
|
||||
struct sc_pkcs15_data_info *dinfo = (struct sc_pkcs15_data_info *)dobjs[ii]->data;
|
||||
|
||||
if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICAITON_NAME))
|
||||
continue;
|
||||
|
||||
if (!strcmp(dobjs[ii]->label, IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL)) {
|
||||
rv = sc_pkcs15_read_data_object(p15card, (struct sc_pkcs15_data_info *)dobjs[ii]->data, &default_guid);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to read 'default container' DATA object data");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(ii=0; ii<count; ii++) {
|
||||
struct sc_pkcs15_data_info *dinfo = (struct sc_pkcs15_data_info *)dobjs[ii]->data;
|
||||
int default_cont = 0;
|
||||
|
||||
if (strcmp(dinfo->app_label, IASECC_GEMALTO_MD_APPLICAITON_NAME))
|
||||
continue;
|
||||
|
||||
if (!strcmp(dobjs[ii]->label, IASECC_GEMALTO_MD_DEFAULT_CONT_LABEL))
|
||||
continue;
|
||||
|
||||
if (default_guid)
|
||||
if (strlen(dobjs[ii]->label) == default_guid->data_len)
|
||||
if (!memcmp(dobjs[ii]->label, default_guid->data, default_guid->data_len))
|
||||
default_cont = 1;
|
||||
|
||||
rv = _iasecc_md_update_keyinfo(p15card, dobjs[ii], default_cont);
|
||||
LOG_TEST_RET(ctx, rv, "Cannot update key MD info");
|
||||
}
|
||||
|
||||
sc_pkcs15_free_data_object(default_guid);
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
iasecc_pkcs15emu_detect_card(sc_pkcs15_card_t *p15card)
|
||||
{
|
||||
if (p15card->card->type < SC_CARD_TYPE_IASECC_BASE)
|
||||
return SC_ERROR_WRONG_CARD;
|
||||
|
||||
if (p15card->card->type > SC_CARD_TYPE_IASECC_BASE + 10)
|
||||
return SC_ERROR_WRONG_CARD;
|
||||
|
||||
return SC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sc_pkcs15emu_iasecc_init (struct sc_pkcs15_card *p15card, struct sc_aid *aid)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
rv = sc_pkcs15_bind_internal(p15card, aid);
|
||||
|
||||
p15card->ops.parse_df = _iasecc_parse_df;
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sc_pkcs15emu_iasecc_init_ex(struct sc_pkcs15_card *p15card, struct sc_aid *aid, struct sc_pkcs15emu_opt *opts)
|
||||
{
|
||||
if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
|
||||
return sc_pkcs15emu_iasecc_init(p15card, aid);
|
||||
|
||||
if (iasecc_pkcs15emu_detect_card(p15card))
|
||||
return SC_ERROR_WRONG_CARD;
|
||||
|
||||
return sc_pkcs15emu_iasecc_init(p15card, aid);
|
||||
}
|
|
@ -36,7 +36,7 @@
|
|||
#include "pkcs15.h"
|
||||
#include "log.h"
|
||||
|
||||
int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *,
|
||||
int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *, struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int (*set_security_env) (sc_card_t *, const sc_security_env_t *,
|
||||
|
@ -321,7 +321,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
|
|||
memset(&cert_info, 0, sizeof(cert_info));
|
||||
memset(&cert_obj, 0, sizeof(cert_obj));
|
||||
|
||||
sc_pkcs15_format_id("1", &cert_info.id);
|
||||
sc_pkcs15_format_id("01", &cert_info.id);
|
||||
cert_info.authority = authority;
|
||||
cert_info.path = path;
|
||||
strlcpy(cert_obj.label, authlabel, sizeof(cert_obj.label));
|
||||
|
@ -338,7 +338,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
|
|||
|
||||
sc_format_path(infocamere_auth_path[ef_gdo[len_iccsn+6]-2], &path);
|
||||
|
||||
sc_pkcs15_format_id("1", &id);
|
||||
sc_pkcs15_format_id("01", &id);
|
||||
sc_pkcs15emu_add_pin(p15card, &id,
|
||||
authPIN, &path, infocamere_idpin_auth_obj[ef_gdo[len_iccsn+6]-2],
|
||||
SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
|
||||
|
@ -377,7 +377,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
|
|||
memset(&cert_info, 0, sizeof(cert_info));
|
||||
memset(&cert_obj, 0, sizeof(cert_obj));
|
||||
|
||||
sc_pkcs15_format_id("2", &cert_info.id);
|
||||
sc_pkcs15_format_id("02", &cert_info.id);
|
||||
|
||||
cert_info.authority = authority;
|
||||
cert_info.path = path;
|
||||
|
@ -411,7 +411,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
|
|||
memset(&cert_info, 0, sizeof(cert_info));
|
||||
memset(&cert_obj, 0, sizeof(cert_obj));
|
||||
|
||||
sc_pkcs15_format_id("3", &cert_info.id);
|
||||
sc_pkcs15_format_id("03", &cert_info.id);
|
||||
cert_info.authority = authority;
|
||||
cert_info.path = path;
|
||||
strlcpy(cert_obj.label, calabel, sizeof(cert_obj.label));
|
||||
|
@ -427,7 +427,7 @@ static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
|
|||
|
||||
sc_format_path(infocamere_nrepud_path[ef_gdo[len_iccsn+6]-2], &path);
|
||||
|
||||
sc_pkcs15_format_id("2", &id);
|
||||
sc_pkcs15_format_id("02", &id);
|
||||
sc_pkcs15emu_add_pin(p15card, &id,
|
||||
nonrepPIN, &path, infocamere_idpin_nrepud_obj[ef_gdo[len_iccsn+6]-2],
|
||||
SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, 3, 0,
|
||||
|
@ -822,6 +822,7 @@ static int infocamere_detect_card(sc_pkcs15_card_t * p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t * p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t * opts)
|
||||
{
|
||||
|
||||
|
|
|
@ -44,8 +44,7 @@
|
|||
#include <openssl/x509v3.h>
|
||||
#endif
|
||||
|
||||
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static const char path_serial[] = "10001003";
|
||||
|
||||
|
@ -847,8 +846,8 @@ static int itacns_init(sc_pkcs15_card_t *p15card)
|
|||
return r;
|
||||
}
|
||||
|
||||
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
sc_card_t *card = p15card->card;
|
||||
SC_FUNC_CALLED(card->ctx, 1);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -33,7 +33,7 @@
|
|||
#include "pkcs15.h"
|
||||
#include "log.h"
|
||||
|
||||
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
static int sc_pkcs15emu_openpgp_add_data(sc_pkcs15_card_t *);
|
||||
|
||||
|
||||
|
@ -429,7 +429,7 @@ static int openpgp_detect_card(sc_pkcs15_card_t *p15card)
|
|||
return SC_ERROR_WRONG_CARD;
|
||||
}
|
||||
|
||||
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *p15card,
|
||||
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#define MANU_ID "piv_II "
|
||||
|
||||
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *, struct sc_aid *aid, sc_pkcs15emu_opt_t *);
|
||||
|
||||
typedef struct objdata_st {
|
||||
const char *id;
|
||||
|
@ -246,23 +246,23 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
/* Note: pkcs11 objects do not have CK_ID values */
|
||||
|
||||
static const objdata objects[] = {
|
||||
{"1", "Card Capability Container",
|
||||
{"01", "Card Capability Container",
|
||||
"2.16.840.1.101.3.7.1.219.0", NULL, "DB00", 0},
|
||||
{"2", "Card Holder Unique Identifier",
|
||||
{"02", "Card Holder Unique Identifier",
|
||||
"2.16.840.1.101.3.7.2.48.0", NULL, "3000", 0},
|
||||
{"3", "Unsigned Card Holder Unique Identifier",
|
||||
{"03", "Unsigned Card Holder Unique Identifier",
|
||||
"2.16.840.1.101.3.7.2.48.2", NULL, "3010", 0},
|
||||
{"4", "X.509 Certificate for PIV Authentication",
|
||||
{"04", "X.509 Certificate for PIV Authentication",
|
||||
"2.16.840.1.101.3.7.2.1.1", NULL, "0101", 0},
|
||||
{"5", "Cardholder Fingerprints",
|
||||
"2.16.840.1.101.3.7.2.96.16", "1", "6010", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{"6", "Printed Information",
|
||||
"2.16.840.1.101.3.7.2.48.1", "1", "3001", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{"7", "Cardholder Facial Image",
|
||||
"2.16.840.1.101.3.7.2.96.48", "1", "6030", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{"8", "X.509 Certificate for Digital Signature",
|
||||
{"05", "Cardholder Fingerprints",
|
||||
"2.16.840.1.101.3.7.2.96.16", "01", "6010", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{"06", "Printed Information",
|
||||
"2.16.840.1.101.3.7.2.48.1", "01", "3001", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{"07", "Cardholder Facial Image",
|
||||
"2.16.840.1.101.3.7.2.96.48", "01", "6030", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{"08", "X.509 Certificate for Digital Signature",
|
||||
"2.16.840.1.101.3.7.2.1.0", NULL, "0100", 0},
|
||||
{"9", "X.509 Certificate for Key Management",
|
||||
{"09", "X.509 Certificate for Key Management",
|
||||
"2.16.840.1.101.3.7.2.1.2", NULL, "0102", 0},
|
||||
{"10","X.509 Certificate for Card Authentication",
|
||||
"2.16.840.1.101.3.7.2.5.0", NULL, "0500", 0},
|
||||
|
@ -328,15 +328,15 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
#define PIV_NUM_CERTS_AND_KEYS 24
|
||||
|
||||
static const cdata certs[PIV_NUM_CERTS_AND_KEYS] = {
|
||||
{"1", "Certificate for PIV Authentication", 0, "0101cece", 0},
|
||||
{"2", "Certificate for Digital Signature", 0, "0100cece", 0},
|
||||
{"3", "Certificate for Key Management", 0, "0102cece", 0},
|
||||
{"4", "Certificate for Card Authentication", 0, "0500cece", 0},
|
||||
{"5", "Retired Certificate for Key Management 1", 0, "1001cece", 0},
|
||||
{"6", "Retired Certificate for Key Management 2", 0, "1002cece", 0},
|
||||
{"7", "Retired Certificate for Key Management 3", 0, "1003cece", 0},
|
||||
{"8", "Retired Certificate for Key Management 4", 0, "1004cece", 0},
|
||||
{"9", "Retired Certificate for Key Management 5", 0, "1005cece", 0},
|
||||
{"01", "Certificate for PIV Authentication", 0, "0101cece", 0},
|
||||
{"02", "Certificate for Digital Signature", 0, "0100cece", 0},
|
||||
{"03", "Certificate for Key Management", 0, "0102cece", 0},
|
||||
{"04", "Certificate for Card Authentication", 0, "0500cece", 0},
|
||||
{"05", "Retired Certificate for Key Management 1", 0, "1001cece", 0},
|
||||
{"06", "Retired Certificate for Key Management 2", 0, "1002cece", 0},
|
||||
{"07", "Retired Certificate for Key Management 3", 0, "1003cece", 0},
|
||||
{"08", "Retired Certificate for Key Management 4", 0, "1004cece", 0},
|
||||
{"09", "Retired Certificate for Key Management 5", 0, "1005cece", 0},
|
||||
{"10", "Retired Certificate for Key Management 6", 0, "1006cece", 0},
|
||||
{"11", "Retired Certificate for Key Management 7", 0, "1007cece", 0},
|
||||
{"12", "Retired Certificate for Key Management 8", 0, "1008cece", 0},
|
||||
|
@ -355,7 +355,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
};
|
||||
|
||||
static const pindata pins[] = {
|
||||
{ "1", "PIV Card Holder pin", "", 0x80,
|
||||
{ "01", "PIV Card Holder pin", "", 0x80,
|
||||
/* label, flag and ref will change if using global pin */
|
||||
SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
|
||||
8, 4, 8,
|
||||
|
@ -364,7 +364,7 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
SC_PKCS15_PIN_FLAG_LOCAL,
|
||||
-1, 0xFF,
|
||||
SC_PKCS15_CO_FLAG_PRIVATE },
|
||||
{ "2", "PIV PUK", "", 0x81,
|
||||
{ "02", "PIV PUK", "", 0x81,
|
||||
SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
|
||||
8, 4, 8,
|
||||
SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
|
||||
|
@ -386,14 +386,14 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
*/
|
||||
static const pubdata pubkeys[PIV_NUM_CERTS_AND_KEYS] = {
|
||||
|
||||
{ "1", "PIV AUTH pubkey",
|
||||
{ "01", "PIV AUTH pubkey",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
|
||||
SC_PKCS15_PRKEY_USAGE_WRAP |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFY |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY,
|
||||
"9A06", 0x9A, NULL, 0, "PIV_9A_KEY"},
|
||||
{ "2", "SIGN pubkey",
|
||||
{ "02", "SIGN pubkey",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFY |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER |
|
||||
|
@ -401,33 +401,33 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
/*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
|
||||
"9C06", 0x9C, NULL, 0, "PIV_9C_KEY"},
|
||||
{ "3", "KEY MAN pubkey",
|
||||
{ "03", "KEY MAN pubkey",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT| SC_PKCS15_PRKEY_USAGE_WRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"9D06", 0x9D, NULL, 0, "PIV_9D_KEY"},
|
||||
{ "4", "CARD AUTH pubkey",
|
||||
{ "04", "CARD AUTH pubkey",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_VERIFY |
|
||||
SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_VERIFY,
|
||||
"9E06", 0x9E, NULL, 0, "PIV_9E_KEY"}, /* no pin, and avail in contactless */
|
||||
|
||||
{ "5", "Retired KEY MAN 1",
|
||||
{ "05", "Retired KEY MAN 1",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"8206", 0x82, NULL, 0, NULL},
|
||||
{ "6", "Retired KEY MAN 2",
|
||||
{ "06", "Retired KEY MAN 2",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"8306", 0x83, NULL, 0, NULL},
|
||||
{ "7", "Retired KEY MAN 3",
|
||||
{ "07", "Retired KEY MAN 3",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"8406", 0x84, NULL, 0, NULL},
|
||||
{ "8", "Retired KEY MAN 4",
|
||||
{ "08", "Retired KEY MAN 4",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"8506", 0x85, NULL, 0, NULL},
|
||||
{ "9", "Retired KEY MAN 5",
|
||||
{ "09", "Retired KEY MAN 5",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_ENCRYPT | SC_PKCS15_PRKEY_USAGE_WRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"8606", 0x86, NULL, 0, NULL},
|
||||
|
@ -497,110 +497,110 @@ static int sc_pkcs15emu_piv_init(sc_pkcs15_card_t *p15card)
|
|||
* on the key algorithm, and will be reset.
|
||||
*/
|
||||
static const prdata prkeys[PIV_NUM_CERTS_AND_KEYS] = {
|
||||
{ "1", "PIV AUTH key",
|
||||
{ "01", "PIV AUTH key",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT |
|
||||
SC_PKCS15_PRKEY_USAGE_UNWRAP |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_SIGN,
|
||||
"", 0x9A, "1", SC_PKCS15_CO_FLAG_PRIVATE, 0},
|
||||
{ "2", "SIGN key",
|
||||
"", 0x9A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
|
||||
{ "02", "SIGN key",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGN |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_SIGN |
|
||||
SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
|
||||
"", 0x9C, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "3", "KEY MAN key",
|
||||
"", 0x9C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "03", "KEY MAN key",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x9D, "1", SC_PKCS15_CO_FLAG_PRIVATE, 0},
|
||||
{ "4", "CARD AUTH key",
|
||||
"", 0x9D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 0},
|
||||
{ "04", "CARD AUTH key",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_SIGN |
|
||||
SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_SIGN,
|
||||
"", 0x9E, NULL, 0, 0}, /* no PIN needed, works with wireless */
|
||||
{ "5", "Retired KEY MAN 1",
|
||||
{ "05", "Retired KEY MAN 1",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x82, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "6", "Retired KEY MAN 2",
|
||||
"", 0x82, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "06", "Retired KEY MAN 2",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x83, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "7", "Retired KEY MAN 3",
|
||||
"", 0x83, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "07", "Retired KEY MAN 3",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x84, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "8", "Retired KEY MAN 4",
|
||||
"", 0x84, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "08", "Retired KEY MAN 4",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x85, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "9", "Retired KEY MAN 5",
|
||||
"", 0x85, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "09", "Retired KEY MAN 5",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x86, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x86, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "10", "Retired KEY MAN 6",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x87, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x87, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "11", "Retired KEY MAN 7",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x88, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x88, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "12", "Retired KEY MAN 8",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x89, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x89, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "13", "Retired KEY MAN 9",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x8A, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x8A, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "14", "Retired KEY MAN 10",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x8B, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x8B, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "15", "Retired KEY MAN 11",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x8C, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x8C, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "16", "Retired KEY MAN 12",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x8D, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x8D, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "17", "Retired KEY MAN 13",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x8E, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x8E, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "18", "Retired KEY MAN 14",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x8F, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x8F, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "19", "Retired KEY MAN 15",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x90, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x90, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "20", "Retired KEY MAN 16",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x91, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x91, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "21", "Retired KEY MAN 17",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x92, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x92, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "22", "Retired KEY MAN 18",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x93, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x93, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "23", "Retired KEY MAN 19",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x94, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
"", 0x94, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1},
|
||||
{ "24", "Retired KEY MAN 20",
|
||||
/*RSA*/SC_PKCS15_PRKEY_USAGE_DECRYPT | SC_PKCS15_PRKEY_USAGE_UNWRAP,
|
||||
/*EC*/SC_PKCS15_PRKEY_USAGE_DERIVE,
|
||||
"", 0x95, "1", SC_PKCS15_CO_FLAG_PRIVATE, 1}
|
||||
"", 0x95, "01", SC_PKCS15_CO_FLAG_PRIVATE, 1}
|
||||
};
|
||||
|
||||
int r, i;
|
||||
|
@ -999,7 +999,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label);
|
|||
prkey_info.modulus_length= ckis[i].pubkey_len;
|
||||
r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
|
||||
break;
|
||||
case SC_ALGORITHM_EC:
|
||||
case SC_ALGORITHM_EC:
|
||||
prkey_info.usage |= prkeys[i].usage_ec;
|
||||
prkey_info.field_length = ckis[i].pubkey_len;
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE added key_alg %2.2x prkey_obj.flags %8.8x",
|
||||
|
@ -1020,7 +1020,7 @@ sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "DEE Adding pin %d label=%s",i, label);
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
struct sc_aid *aid, sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
sc_card_t *card = p15card->card;
|
||||
sc_context_t *ctx = card->ctx;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "pkcs15.h"
|
||||
#include "log.h"
|
||||
|
||||
int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int (*set_security_env) (sc_card_t *, const sc_security_env_t *, int);
|
||||
|
||||
|
@ -354,6 +354,7 @@ static int postecert_detect_card(sc_pkcs15_card_t * p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t * p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t * opts)
|
||||
{
|
||||
if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "asn1.h"
|
||||
#include "pkcs15.h"
|
||||
#include "common/compat_strlcpy.h"
|
||||
#include "aux-data.h"
|
||||
|
||||
#ifdef ENABLE_OPENSSL
|
||||
#include <openssl/x509.h>
|
||||
|
@ -597,6 +598,8 @@ void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key)
|
|||
|
||||
sc_pkcs15_free_key_params(&key->params);
|
||||
|
||||
sc_aux_data_free(&key->aux_data);
|
||||
|
||||
free(key);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#define IAS_CARD 0
|
||||
#define GEMSAFE_CARD 1
|
||||
|
||||
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card)
|
||||
{
|
||||
|
@ -227,11 +227,11 @@ static int sc_pkcs15emu_pteid_init(sc_pkcs15_card_t * p15card)
|
|||
|
||||
/* Add objects */
|
||||
for (i = 0; i < 3; i++) {
|
||||
static const char *object_ids[3] = {"1", "2", "3"};
|
||||
static const char *object_ids[3] = {"01", "02", "03"};
|
||||
static const char *object_labels[3] = {"Citizen Data",
|
||||
"Citizen Address Data",
|
||||
"Citizen Notepad"};
|
||||
static const char *object_authids[3] = {NULL, "3", "1"};
|
||||
static const char *object_authids[3] = {NULL, "03", "01"};
|
||||
static const char *object_paths[3] = {"3f005f00ef02",
|
||||
"3f005f00ef05",
|
||||
"3f005f00ef07"};
|
||||
|
@ -275,7 +275,7 @@ static int pteid_detect_card(sc_pkcs15_card_t *p15card)
|
|||
return SC_ERROR_WRONG_CARD;
|
||||
}
|
||||
|
||||
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, sc_pkcs15emu_opt_t *opts)
|
||||
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *aid, sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
if (opts != NULL && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
|
||||
return sc_pkcs15emu_pteid_init(p15card);
|
||||
|
|
|
@ -732,7 +732,7 @@ sc_pkcs15_decode_pubkey_ec(sc_context_t *ctx,
|
|||
/*
|
||||
* Only get here if raw point is stored in pkcs15 without curve name
|
||||
* spki has the curvename, so we can get the field_length
|
||||
* Following only true for curves that are multiple of 8
|
||||
* Following only true for curves that are multiple of 8
|
||||
*/
|
||||
key->params.field_length = (ecpoint_len - 1)/2 * 8;
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
@ -824,7 +824,7 @@ sc_pkcs15_encode_pubkey_as_spki(sc_context_t *ctx, struct sc_pkcs15_pubkey *pubk
|
|||
pkey.value = pubkey->u.ec.ecpointQ.value;
|
||||
pkey.len = 0; /* flag as do not delete */
|
||||
|
||||
if (pubkey->u.ec.params.named_curve || pubkey->u.ec.params.der.value) {
|
||||
if (pubkey->u.ec.params.named_curve || pubkey->u.ec.params.der.value) {
|
||||
struct sc_ec_parameters *ec_params = NULL;
|
||||
|
||||
r = sc_pkcs15_fix_ec_parameters(ctx, &pubkey->u.ec.params);
|
||||
|
@ -1209,16 +1209,21 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename,
|
|||
{
|
||||
int r;
|
||||
int f = -1;
|
||||
size_t len;
|
||||
size_t len, offs;
|
||||
u8 tagbuf[16]; /* enough to read in the tag and length */
|
||||
u8 * rbuf = NULL;
|
||||
size_t rbuflen;
|
||||
const u8 * body;
|
||||
size_t rbuflen = 0;
|
||||
const u8 * body = NULL;
|
||||
size_t bodylen;
|
||||
unsigned int cla_out, tag_out;
|
||||
*buf = NULL;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if (!buf || !buflen)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
*buf = NULL;
|
||||
*buflen = 0;
|
||||
|
||||
f = open(filename, O_RDONLY);
|
||||
if (f < 0) {
|
||||
r = SC_ERROR_FILE_NOT_FOUND;
|
||||
|
@ -1232,14 +1237,24 @@ sc_pkcs15_read_der_file(sc_context_t *ctx, char * filename,
|
|||
goto out;
|
||||
}
|
||||
len = r;
|
||||
|
||||
body = tagbuf;
|
||||
if (sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen) != SC_SUCCESS) {
|
||||
sc_log(ctx, "DER problem");
|
||||
r = sc_asn1_read_tag(&body, len, &cla_out, &tag_out, &bodylen);
|
||||
if (r != SC_SUCCESS)
|
||||
goto out;
|
||||
|
||||
if (tag_out == SC_ASN1_TAG_EOC || body == NULL) {
|
||||
r = SC_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
offs = body - tagbuf;
|
||||
if (offs > len || offs < 2) {
|
||||
r = SC_ERROR_INVALID_ASN1_OBJECT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
rbuflen = body - tagbuf + bodylen;
|
||||
rbuflen = offs + bodylen;
|
||||
rbuf = malloc(rbuflen);
|
||||
if (rbuf == NULL) {
|
||||
r = SC_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -1328,7 +1343,7 @@ sc_pkcs15_pubkey_from_spki_fields(struct sc_context *ctx, struct sc_pkcs15_pubke
|
|||
/* EC public key is not encapsulated into BIT STRING -- it's a BIT STRING */
|
||||
/*
|
||||
* sc_pkcs15_fix_ec_parameters below will set field_length from curve.
|
||||
* if no alg_id->params, assume field_length is multiple of 8
|
||||
* if no alg_id->params, assume field_length is multiple of 8
|
||||
*/
|
||||
pubkey->u.ec.params.field_length = (pk.len - 1) / 2 * 8;
|
||||
|
||||
|
|
|
@ -524,10 +524,12 @@ static int sc_pkcs15emu_sc_hsm_add_pubkey(sc_pkcs15_card_t *p15card, sc_pkcs15_p
|
|||
|
||||
if (pubkey.algorithm == SC_ALGORITHM_RSA) {
|
||||
pubkey_info.modulus_length = pubkey.u.rsa.modulus.len << 3;
|
||||
pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_ENCRYPT|SC_PKCS15_PRKEY_USAGE_VERIFY|SC_PKCS15_PRKEY_USAGE_WRAP;
|
||||
r = sc_pkcs15emu_add_rsa_pubkey(p15card, &pubkey_obj, &pubkey_info);
|
||||
} else {
|
||||
/* TODO fix if support of non multiple of 8 curves are added */
|
||||
pubkey_info.field_length = cvc.primeOrModuluslen << 3;
|
||||
pubkey_info.usage = SC_PKCS15_PRKEY_USAGE_VERIFY;
|
||||
r = sc_pkcs15emu_add_ec_pubkey(p15card, &pubkey_obj, &pubkey_info);
|
||||
}
|
||||
LOG_TEST_RET(ctx, r, "Could not add public key");
|
||||
|
@ -933,6 +935,7 @@ static int sc_pkcs15emu_sc_hsm_init (sc_pkcs15_card_t * p15card)
|
|||
|
||||
|
||||
int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
if (opts && (opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#define MANU_ID "Giesecke & Devrient GmbH"
|
||||
#define STARCERT "StarCertV2201"
|
||||
|
||||
int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *,sc_pkcs15emu_opt_t *);
|
||||
|
||||
typedef struct cdata_st {
|
||||
const char *label;
|
||||
|
@ -146,11 +146,11 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card)
|
|||
};
|
||||
|
||||
const prdata prkeys[] = {
|
||||
{ "1", "DS key", 1024, USAGE_NONREP, "3F00DF01",
|
||||
{ "01", "DS key", 1024, USAGE_NONREP, "3F00DF01",
|
||||
0x84, "99", SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{ "3", "KE key", 1024, USAGE_KE, "3F00DF01",
|
||||
{ "03", "KE key", 1024, USAGE_KE, "3F00DF01",
|
||||
0x85, NULL, SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{ "4", "AUT key", 1024, USAGE_AUT, "3F00DF01",
|
||||
{ "04", "AUT key", 1024, USAGE_AUT, "3F00DF01",
|
||||
0x82, NULL, SC_PKCS15_CO_FLAG_PRIVATE},
|
||||
{ NULL, NULL, 0, 0, NULL, 0, NULL, 0}
|
||||
};
|
||||
|
@ -270,6 +270,7 @@ static int sc_pkcs15emu_starcert_init(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/*
|
||||
* pkcs15-syn.c: PKCS #15 emulation of non-pkcs15 cards
|
||||
*
|
||||
* Copyright (C) 2003 Olaf Kirch <okir@suse.de>
|
||||
* 2004 Nils Larsch <nlarsch@betrusted.com>
|
||||
* Copyright (C) 2003 Olaf Kirch <okir@suse.de>
|
||||
* 2004 Nils Larsch <nlarsch@betrusted.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -32,52 +32,9 @@
|
|||
#include "internal.h"
|
||||
#include "asn1.h"
|
||||
#include "pkcs15.h"
|
||||
#include "pkcs15-syn.h"
|
||||
|
||||
extern int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
extern int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
extern int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
extern int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
extern int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
extern int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
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 *);
|
||||
extern int sc_pkcs15emu_oberthur_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t *,
|
||||
sc_pkcs15emu_opt_t *);
|
||||
extern int sc_pkcs15emu_gids_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 *);
|
||||
} builtin_emulators[] = {
|
||||
struct sc_pkcs15_emulator_handler builtin_emulators[] = {
|
||||
{ "westcos", sc_pkcs15emu_westcos_init_ex },
|
||||
{ "openpgp", sc_pkcs15emu_openpgp_init_ex },
|
||||
{ "infocamere", sc_pkcs15emu_infocamere_init_ex },
|
||||
|
@ -86,7 +43,7 @@ static struct {
|
|||
{ "esteid", sc_pkcs15emu_esteid_init_ex },
|
||||
{ "itacns", sc_pkcs15emu_itacns_init_ex },
|
||||
{ "postecert", sc_pkcs15emu_postecert_init_ex },
|
||||
{ "PIV-II", sc_pkcs15emu_piv_init_ex },
|
||||
{ "PIV-II", sc_pkcs15emu_piv_init_ex },
|
||||
{ "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex },
|
||||
{ "gemsafeV1", sc_pkcs15emu_gemsafeV1_init_ex },
|
||||
{ "actalis", sc_pkcs15emu_actalis_init_ex },
|
||||
|
@ -95,13 +52,14 @@ static struct {
|
|||
{ "entersafe", sc_pkcs15emu_entersafe_init_ex },
|
||||
{ "pteid", sc_pkcs15emu_pteid_init_ex },
|
||||
{ "oberthur", sc_pkcs15emu_oberthur_init_ex },
|
||||
{ "sc-hsm", sc_pkcs15emu_sc_hsm_init_ex },
|
||||
{ "sc-hsm", sc_pkcs15emu_sc_hsm_init_ex },
|
||||
{ "dnie", sc_pkcs15emu_dnie_init_ex },
|
||||
{ "gids", sc_pkcs15emu_gids_init_ex },
|
||||
{ "iasecc", sc_pkcs15emu_iasecc_init_ex },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
static int parse_emu_block(sc_pkcs15_card_t *, scconf_block *);
|
||||
static int parse_emu_block(sc_pkcs15_card_t *, struct sc_aid *, scconf_block *);
|
||||
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
|
||||
unsigned int type);
|
||||
|
||||
|
@ -114,7 +72,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
|
|||
{
|
||||
switch (card->type) {
|
||||
case SC_CARD_TYPE_MCRD_ESTEID_V10:
|
||||
case SC_CARD_TYPE_MCRD_ESTEID_V11:
|
||||
case SC_CARD_TYPE_MCRD_ESTEID_V11:
|
||||
case SC_CARD_TYPE_MCRD_ESTEID_V30:
|
||||
case SC_CARD_TYPE_IAS_PTEID:
|
||||
case SC_CARD_TYPE_GEMSAFEV1_PTEID:
|
||||
|
@ -127,6 +85,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
|
|||
case SC_CARD_TYPE_DNIE_ADMIN:
|
||||
case SC_CARD_TYPE_DNIE_USER:
|
||||
case SC_CARD_TYPE_DNIE_TERMINATED:
|
||||
case SC_CARD_TYPE_IASECC_GEMALTO:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
|
@ -134,7 +93,7 @@ int sc_pkcs15_is_emulation_only(sc_card_t *card)
|
|||
}
|
||||
|
||||
int
|
||||
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
||||
sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card, struct sc_aid *aid)
|
||||
{
|
||||
sc_context_t *ctx = p15card->card->ctx;
|
||||
scconf_block *conf_block, **blocks, *blk;
|
||||
|
@ -149,17 +108,17 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
|||
|
||||
if (!conf_block) {
|
||||
/* no conf file found => try bultin drivers */
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no conf file (or section), trying all builtin emulators\n");
|
||||
sc_log(ctx, "no conf file (or section), trying all builtin emulators");
|
||||
for (i = 0; builtin_emulators[i].name; i++) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", builtin_emulators[i].name);
|
||||
r = builtin_emulators[i].handler(p15card, &opts);
|
||||
sc_log(ctx, "trying %s", builtin_emulators[i].name);
|
||||
r = builtin_emulators[i].handler(p15card, aid, &opts);
|
||||
if (r == SC_SUCCESS)
|
||||
/* we got a hit */
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
/* we have a conf file => let's use it */
|
||||
int builtin_enabled;
|
||||
int builtin_enabled;
|
||||
const scconf_list *list, *item;
|
||||
|
||||
builtin_enabled = scconf_get_bool(conf_block, "enable_builtin_emulation", 1);
|
||||
|
@ -171,10 +130,10 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
|||
/* go through the list of builtin drivers */
|
||||
const char *name = item->data;
|
||||
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", name);
|
||||
sc_log(ctx, "trying %s", name);
|
||||
for (i = 0; builtin_emulators[i].name; i++)
|
||||
if (!strcmp(builtin_emulators[i].name, name)) {
|
||||
r = builtin_emulators[i].handler(p15card, &opts);
|
||||
r = builtin_emulators[i].handler(p15card, aid, &opts);
|
||||
if (r == SC_SUCCESS)
|
||||
/* we got a hit */
|
||||
goto out;
|
||||
|
@ -182,10 +141,10 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
}
|
||||
else if (builtin_enabled) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "no emulator list in config file, trying all builtin emulators\n");
|
||||
sc_log(ctx, "no emulator list in config file, trying all builtin emulators");
|
||||
for (i = 0; builtin_emulators[i].name; i++) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying %s\n", builtin_emulators[i].name);
|
||||
r = builtin_emulators[i].handler(p15card, &opts);
|
||||
sc_log(ctx, "trying %s", builtin_emulators[i].name);
|
||||
r = builtin_emulators[i].handler(p15card, aid, &opts);
|
||||
if (r == SC_SUCCESS)
|
||||
/* we got a hit */
|
||||
goto out;
|
||||
|
@ -193,13 +152,13 @@ sc_pkcs15_bind_synthetic(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
/* search for 'emulate foo { ... }' entries in the conf file */
|
||||
sc_log(ctx, "searching for 'emulate foo { ... }' blocks\n");
|
||||
sc_log(ctx, "searching for 'emulate foo { ... }' blocks");
|
||||
blocks = scconf_find_blocks(ctx->conf, conf_block, "emulate", NULL);
|
||||
sc_log(ctx, "Blocks: %p", blocks);
|
||||
for (i = 0; blocks && (blk = blocks[i]) != NULL; i++) {
|
||||
const char *name = blk->name->data;
|
||||
sc_log(ctx, "trying %s", name);
|
||||
r = parse_emu_block(p15card, blk);
|
||||
r = parse_emu_block(p15card, aid, blk);
|
||||
if (r == SC_SUCCESS) {
|
||||
free(blocks);
|
||||
goto out;
|
||||
|
@ -222,14 +181,14 @@ out:
|
|||
}
|
||||
|
||||
|
||||
static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
|
||||
static int parse_emu_block(sc_pkcs15_card_t *p15card, struct sc_aid *aid, scconf_block *conf)
|
||||
{
|
||||
sc_card_t *card = p15card->card;
|
||||
sc_context_t *ctx = card->ctx;
|
||||
sc_pkcs15emu_opt_t opts;
|
||||
void *handle = NULL;
|
||||
int (*init_func)(sc_pkcs15_card_t *);
|
||||
int (*init_func_ex)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int (*init_func_ex)(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int r;
|
||||
const char *driver, *module_name;
|
||||
|
||||
|
@ -260,13 +219,13 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
|
|||
void *address;
|
||||
unsigned int major = 0, minor = 0, fix = 0;
|
||||
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Loading %s\n", module_name);
|
||||
|
||||
sc_log(ctx, "Loading %s", module_name);
|
||||
|
||||
/* try to open dynamic library */
|
||||
handle = sc_dlopen(module_name);
|
||||
if (!handle) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "unable to open dynamic library '%s': %s\n",
|
||||
module_name, sc_dlerror());
|
||||
sc_log(ctx, "unable to open dynamic library '%s': %s",
|
||||
module_name, sc_dlerror());
|
||||
return SC_ERROR_INTERNAL;
|
||||
}
|
||||
|
||||
|
@ -274,8 +233,7 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
|
|||
get_version = (const char *(*)(void)) sc_dlsym(handle, "sc_driver_version");
|
||||
if (get_version) {
|
||||
if (3 != sscanf(get_version(), "%u.%u.%u", &major, &minor, &fix)) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
|
||||
"unable to get modules version number\n");
|
||||
sc_log(ctx, "unable to get modules version number");
|
||||
sc_dlclose(handle);
|
||||
return SC_ERROR_INTERNAL;
|
||||
}
|
||||
|
@ -296,24 +254,22 @@ static int parse_emu_block(sc_pkcs15_card_t *p15card, scconf_block *conf)
|
|||
|
||||
address = sc_dlsym(handle, name);
|
||||
if (address)
|
||||
init_func_ex = (int (*)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *)) address;
|
||||
init_func_ex = (int (*)(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *)) address;
|
||||
}
|
||||
}
|
||||
/* try to initialize the pkcs15 structures */
|
||||
if (init_func_ex)
|
||||
r = init_func_ex(p15card, &opts);
|
||||
r = init_func_ex(p15card, aid, &opts);
|
||||
else if (init_func)
|
||||
r = init_func(p15card);
|
||||
else
|
||||
r = SC_ERROR_WRONG_CARD;
|
||||
|
||||
if (r >= 0) {
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s succeeded, card bound\n",
|
||||
module_name);
|
||||
sc_log(card->ctx, "%s succeeded, card bound", module_name);
|
||||
p15card->dll_handle = handle;
|
||||
} else {
|
||||
sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "%s failed: %s\n",
|
||||
module_name, sc_strerror(r));
|
||||
sc_log(card->ctx, "%s failed: %s", module_name, sc_strerror(r));
|
||||
/* clear pkcs15 card */
|
||||
sc_pkcs15_card_clear(p15card);
|
||||
if (handle)
|
||||
|
@ -405,7 +361,7 @@ int sc_pkcs15emu_add_ec_pubkey(sc_pkcs15_card_t *p15card,
|
|||
const sc_pkcs15_object_t *obj, const sc_pkcs15_pubkey_info_t *in_key)
|
||||
{
|
||||
sc_pkcs15_pubkey_info_t key = *in_key;
|
||||
|
||||
|
||||
if (key.access_flags == 0)
|
||||
key.access_flags = SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
|
||||
|
||||
|
@ -459,8 +415,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_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,
|
||||
"Unknown PKCS15 object type %d\n", type);
|
||||
sc_log(p15card->card->ctx, "Unknown PKCS15 object type %d", type);
|
||||
free(obj);
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* pkcs15-syn.c: PKCS #15 emulation of non-pkcs15 cards
|
||||
*
|
||||
* Copyright (C) 2003 Olaf Kirch <okir@suse.de>
|
||||
* 2004 Nils Larsch <nlarsch@betrusted.com>
|
||||
*
|
||||
* 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 PKCS15_SYN_H
|
||||
#define PKCS15_SYN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <libopensc/types.h>
|
||||
#include <libopensc/pkcs15.h>
|
||||
|
||||
int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||
int sc_pkcs15emu_openpgp_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_starcert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_tcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_esteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_postecert_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_piv_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||
int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||
int sc_pkcs15emu_gemsafeV1_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||
int sc_pkcs15emu_actalis_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||
int sc_pkcs15emu_atrust_acos_init_ex(sc_pkcs15_card_t *p15card, struct sc_aid *, sc_pkcs15emu_opt_t *opts);
|
||||
int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_entersafe_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_oberthur_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_sc_hsm_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_dnie_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_gids_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_iasecc_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
struct sc_pkcs15_emulator_handler {
|
||||
const char *name;
|
||||
int (*handler)(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -42,6 +42,7 @@
|
|||
#define TC_CARDOS_PIN_MASK 0x3000
|
||||
|
||||
int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
|
||||
static int read_file(struct sc_card *card, const char *file, u8 *buf,
|
||||
|
@ -348,6 +349,7 @@ static int sc_pkcs15_tccardos_init_func(sc_pkcs15_card_t *p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_tccardos_init_ex(sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts)
|
||||
{
|
||||
return sc_pkcs15_tccardos_init_func(p15card);
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
int sc_pkcs15emu_tcos_init_ex(
|
||||
sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *,
|
||||
sc_pkcs15emu_opt_t *opts);
|
||||
|
||||
static int insert_cert(
|
||||
|
@ -488,6 +489,7 @@ static int detect_unicard(
|
|||
|
||||
int sc_pkcs15emu_tcos_init_ex(
|
||||
sc_pkcs15_card_t *p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t *opts
|
||||
){
|
||||
sc_card_t *card = p15card->card;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "cardctl.h"
|
||||
#include "common/compat_strlcpy.h"
|
||||
|
||||
int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
|
||||
int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t *, struct sc_aid *, sc_pkcs15emu_opt_t *);
|
||||
|
||||
static int sc_pkcs15emu_westcos_init(sc_pkcs15_card_t * p15card)
|
||||
{
|
||||
|
@ -239,6 +239,7 @@ static int westcos_detect_card(sc_pkcs15_card_t * p15card)
|
|||
}
|
||||
|
||||
int sc_pkcs15emu_westcos_init_ex(sc_pkcs15_card_t * p15card,
|
||||
struct sc_aid *aid,
|
||||
sc_pkcs15emu_opt_t * opts)
|
||||
{
|
||||
int r;
|
||||
|
|
|
@ -88,7 +88,7 @@ static const struct sc_asn1_entry c_asn1_profile_indication[C_ASN1_PROFILE_INDIC
|
|||
|
||||
#define C_ASN1_TOKI_ATTRS_SIZE 15
|
||||
static const struct sc_asn1_entry c_asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE] = {
|
||||
{ "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
|
||||
{ "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
|
||||
{ "serialNumber", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "manufacturerID", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
{ "label", SC_ASN1_UTF8STRING, SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
|
||||
|
@ -111,9 +111,11 @@ static const struct sc_asn1_entry c_asn1_tokeninfo[] = {
|
|||
{ NULL, 0, 0, 0, NULL, NULL }
|
||||
};
|
||||
|
||||
static void sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *p15card);
|
||||
static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *p15card);
|
||||
static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *p15card);
|
||||
static void sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *);
|
||||
static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *);
|
||||
static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *);
|
||||
static int sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
|
||||
unsigned, unsigned char *, size_t *);
|
||||
|
||||
int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
|
||||
sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen)
|
||||
|
@ -132,7 +134,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
|
|||
u8 preferred_language[3];
|
||||
size_t lang_length = sizeof(preferred_language);
|
||||
struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
|
||||
asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7];
|
||||
asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7];
|
||||
size_t reference_len = sizeof(ti->supported_algos[0].reference);
|
||||
size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
|
||||
size_t operations_len = sizeof(ti->supported_algos[0].operations);
|
||||
|
@ -201,6 +203,7 @@ int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
|
|||
sprintf(byte, "%02X", serial[ii]);
|
||||
strcat(ti->serial_number, byte);
|
||||
}
|
||||
sc_log(ctx, "TokenInfo.serialNunmber '%s'", ti->serial_number);
|
||||
}
|
||||
|
||||
if (ti->manufacturer_id == NULL) {
|
||||
|
@ -267,7 +270,7 @@ sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti,
|
|||
struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE];
|
||||
struct sc_asn1_entry asn1_tokeninfo[2];
|
||||
struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
|
||||
asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7];
|
||||
asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7];
|
||||
size_t reference_len = sizeof(ti->supported_algos[0].reference);
|
||||
size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
|
||||
size_t operations_len = sizeof(ti->supported_algos[0].operations);
|
||||
|
@ -407,7 +410,7 @@ fix_authentic_ddo(struct sc_pkcs15_card *p15card)
|
|||
sc_file_free(p15card->file_odf);
|
||||
p15card->file_odf = NULL;
|
||||
}
|
||||
if (p15card->file_tokeninfo != NULL) {
|
||||
if (p15card->file_tokeninfo != NULL) {
|
||||
sc_file_free(p15card->file_tokeninfo);
|
||||
p15card->file_tokeninfo = NULL;
|
||||
}
|
||||
|
@ -1205,8 +1208,8 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
|
|||
p15card->opts.pin_cache_ignore_user_consent);
|
||||
}
|
||||
sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d",
|
||||
p15card->opts.use_file_cache, p15card->opts.use_pin_cache,
|
||||
p15card->opts.pin_cache_counter, p15card->opts.pin_cache_ignore_user_consent);
|
||||
p15card->opts.use_file_cache, p15card->opts.use_pin_cache,p15card->opts.pin_cache_counter,
|
||||
p15card->opts.pin_cache_ignore_user_consent);
|
||||
|
||||
r = sc_lock(card);
|
||||
if (r) {
|
||||
|
@ -1220,7 +1223,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
|
|||
sc_log(ctx, "PKCS#15 emulation enabled");
|
||||
emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
|
||||
if (emu_first || sc_pkcs15_is_emulation_only(card)) {
|
||||
r = sc_pkcs15_bind_synthetic(p15card);
|
||||
r = sc_pkcs15_bind_synthetic(p15card, aid);
|
||||
if (r == SC_SUCCESS)
|
||||
goto done;
|
||||
r = sc_pkcs15_bind_internal(p15card, aid);
|
||||
|
@ -1230,7 +1233,7 @@ sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
|
|||
r = sc_pkcs15_bind_internal(p15card, aid);
|
||||
if (r == SC_SUCCESS)
|
||||
goto done;
|
||||
r = sc_pkcs15_bind_synthetic(p15card);
|
||||
r = sc_pkcs15_bind_synthetic(p15card, aid);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
}
|
||||
|
@ -1276,6 +1279,7 @@ __sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, unsigned int class_ma
|
|||
struct sc_pkcs15_df *df = NULL;
|
||||
unsigned int df_mask = 0;
|
||||
size_t match_count = 0;
|
||||
int r;
|
||||
|
||||
if (type)
|
||||
class_mask |= SC_PKCS15_TYPE_TO_CLASS(type);
|
||||
|
@ -1312,9 +1316,12 @@ __sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, unsigned int class_ma
|
|||
}
|
||||
if (df->enumerated)
|
||||
continue;
|
||||
/* Enumerate the DF's, so p15card->obj_list is
|
||||
* populated. */
|
||||
if (SC_SUCCESS != sc_pkcs15_parse_df(p15card, df))
|
||||
/* Enumerate the DF's, so p15card->obj_list is populated. */
|
||||
if (p15card->ops.parse_df)
|
||||
r = p15card->ops.parse_df(p15card, df);
|
||||
else
|
||||
r = sc_pkcs15_parse_df(p15card, df);
|
||||
if (r != SC_SUCCESS)
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1563,9 +1570,8 @@ sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, struct sc_pkcs15_search
|
|||
|
||||
int
|
||||
sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *p15card, unsigned int type,
|
||||
int (* func)(struct sc_pkcs15_object *, void *),
|
||||
void *func_arg,
|
||||
struct sc_pkcs15_object **ret, size_t ret_size)
|
||||
int (* func)(struct sc_pkcs15_object *, void *),
|
||||
void *func_arg, struct sc_pkcs15_object **ret, size_t ret_size)
|
||||
{
|
||||
return __sc_pkcs15_search_objects(p15card, 0, type,
|
||||
func, func_arg, ret, ret_size);
|
||||
|
@ -1788,8 +1794,7 @@ sc_pkcs15_find_data_object_by_name(struct sc_pkcs15_card *p15card, const char *a
|
|||
|
||||
int
|
||||
sc_pkcs15_find_prkey_by_id_usage(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
|
||||
unsigned int usage,
|
||||
struct sc_pkcs15_object **out)
|
||||
unsigned int usage, struct sc_pkcs15_object **out)
|
||||
{
|
||||
struct sc_pkcs15_search_key sk;
|
||||
|
||||
|
@ -2021,11 +2026,6 @@ sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df)
|
|||
|
||||
sc_log(ctx, "called; path=%s, type=%d, enum=%d", sc_print_path(&df->path), df->type, df->enumerated);
|
||||
|
||||
if (p15card->ops.parse_df) {
|
||||
r = p15card->ops.parse_df(p15card, df);
|
||||
LOG_FUNC_RETURN(ctx, r);
|
||||
}
|
||||
|
||||
if (df->enumerated)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
|
@ -2424,9 +2424,15 @@ sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1, const struct sc_pkcs15_id *
|
|||
void
|
||||
sc_pkcs15_format_id(const char *str, struct sc_pkcs15_id *id)
|
||||
{
|
||||
size_t len = sizeof(id->value);
|
||||
size_t len;
|
||||
|
||||
if (sc_hex_to_bin(str, id->value, &len) >= 0)
|
||||
if (!id)
|
||||
return;
|
||||
len = sizeof(id->value);
|
||||
|
||||
if (sc_hex_to_bin(str, id->value, &len) != SC_SUCCESS)
|
||||
id->len = 0;
|
||||
else
|
||||
id->len = len;
|
||||
}
|
||||
|
||||
|
@ -2703,7 +2709,7 @@ sc_pkcs15_serialize_guid(unsigned char *in, size_t in_size, unsigned flags,
|
|||
|
||||
int
|
||||
sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
|
||||
unsigned flags, unsigned char *out, size_t *out_size)
|
||||
unsigned flags, unsigned char *out, size_t *out_size)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_serial_number serialnr;
|
||||
|
@ -2720,6 +2726,12 @@ sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15
|
|||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
rv = sc_pkcs15_aux_get_md_guid(p15card, obj, flags, out, out_size);
|
||||
if (rv == SC_SUCCESS)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
else if (rv != SC_ERROR_NOT_SUPPORTED)
|
||||
LOG_TEST_RET(ctx, rv, "Failed to get alternative object GUID");
|
||||
|
||||
memset(out, 0, *out_size);
|
||||
|
||||
rv = sc_pkcs15_get_object_id(obj, &id);
|
||||
|
@ -2750,9 +2762,9 @@ sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15
|
|||
memcpy(guid_bin + id.len, serialnr.value, serialnr.len);
|
||||
guid_bin_size = id.len + serialnr.len;
|
||||
|
||||
/*
|
||||
/*
|
||||
* If OpenSSL is available (SHA1), then rather use the hash of the data
|
||||
* - this also protects against data being too short
|
||||
* - this also protects against data being too short
|
||||
*/
|
||||
#ifdef ENABLE_OPENSSL
|
||||
SHA1(guid_bin, guid_bin_size, guid_bin);
|
||||
|
@ -2774,6 +2786,31 @@ sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
|
||||
unsigned flags,
|
||||
unsigned char *out, size_t *out_size)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_prkey_info *prkey_info = NULL;
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
if(!out || !out_size)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
prkey_info = (struct sc_pkcs15_prkey_info *)obj->data;
|
||||
if (!prkey_info->aux_data || prkey_info->aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
|
||||
rv = sc_aux_data_get_md_guid(ctx, prkey_info->aux_data, flags, out, out_size);
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params)
|
||||
{
|
||||
|
|
|
@ -26,6 +26,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "libopensc/opensc.h"
|
||||
#include "libopensc/aux-data.h"
|
||||
|
||||
#define SC_PKCS15_CACHE_DIR ".eid"
|
||||
|
||||
|
@ -388,8 +389,8 @@ struct sc_pkcs15_prkey_info {
|
|||
|
||||
struct sc_path path;
|
||||
|
||||
/* Used by minidriver and its on-card support */
|
||||
/*struct sc_md_cmap_record cmap_record;*/
|
||||
/* Non-pkcs15 data, like MD CMAP record */
|
||||
struct sc_auxiliary_data *aux_data;
|
||||
};
|
||||
typedef struct sc_pkcs15_prkey_info sc_pkcs15_prkey_info_t;
|
||||
|
||||
|
@ -944,7 +945,7 @@ typedef struct sc_pkcs15emu_opt {
|
|||
|
||||
#define SC_PKCS15EMU_FLAGS_NO_CHECK 0x00000001
|
||||
|
||||
extern int sc_pkcs15_bind_synthetic(struct sc_pkcs15_card *);
|
||||
extern int sc_pkcs15_bind_synthetic(struct sc_pkcs15_card *, struct sc_aid *);
|
||||
extern int sc_pkcs15_is_emulation_only(sc_card_t *);
|
||||
|
||||
int sc_pkcs15emu_object_add(struct sc_pkcs15_card *, unsigned int,
|
||||
|
|
|
@ -98,11 +98,11 @@ static int ctapi_reset(sc_reader_t *reader)
|
|||
|
||||
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
|
||||
if (rv || (lr < 2)) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error getting status of terminal: %d, using defaults\n", rv);
|
||||
sc_log(reader->ctx, "Error getting status of terminal: %d, using defaults", rv);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
if (rbuf[lr-2] != 0x90) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "SW1/SW2: 0x%x/0x%x\n", rbuf[lr-2], rbuf[lr-1]);
|
||||
sc_log(reader->ctx, "SW1/SW2: 0x%x/0x%x", rbuf[lr-2], rbuf[lr-1]);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
return 0;
|
||||
|
@ -132,7 +132,7 @@ static int refresh_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_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error getting status of terminal: %d/%d/0x%x\n", rv, lr, rbuf[lr-2]);
|
||||
sc_log(reader->ctx, "Error getting status of terminal: %d/%d/0x%x", rv, lr, rbuf[lr-2]);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
if (lr < 4) {
|
||||
|
@ -141,11 +141,11 @@ static int refresh_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_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x\n", rbuf[0]);
|
||||
sc_log(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_ICC: 0x%x", rbuf[0]);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
/* Fixme - should not be reached */
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Returned status for %d slots\n", rbuf[1]);
|
||||
sc_log(reader->ctx, "Returned status for %d slots", rbuf[1]);
|
||||
reader->flags = SC_READER_CARD_PRESENT;
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ static int ctapi_internal_transmit(sc_reader_t *reader,
|
|||
|
||||
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, (unsigned short)sendsize, (u8 *) sendbuf, &lr, recvbuf);
|
||||
if (rv != 0) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error transmitting APDU: %d\n", rv);
|
||||
sc_log(reader->ctx, "Error transmitting APDU: %d", rv);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
*recvsize = lr;
|
||||
|
@ -185,9 +185,9 @@ static int ctapi_internal_transmit(sc_reader_t *reader,
|
|||
|
||||
static int ctapi_transmit(sc_reader_t *reader, sc_apdu_t *apdu)
|
||||
{
|
||||
size_t ssize, rsize, rbuflen = 0;
|
||||
u8 *sbuf = NULL, *rbuf = NULL;
|
||||
int r;
|
||||
size_t ssize, rsize, rbuflen = 0;
|
||||
u8 *sbuf = NULL, *rbuf = NULL;
|
||||
int r;
|
||||
|
||||
rsize = rbuflen = apdu->resplen + 2;
|
||||
rbuf = malloc(rbuflen);
|
||||
|
@ -204,7 +204,7 @@ static int ctapi_transmit(sc_reader_t *reader, sc_apdu_t *apdu)
|
|||
rbuf, &rsize, apdu->control);
|
||||
if (r < 0) {
|
||||
/* unable to transmit ... most likely a reader problem */
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "unable to transmit");
|
||||
sc_log(reader->ctx, "unable to transmit");
|
||||
goto out;
|
||||
}
|
||||
sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0);
|
||||
|
@ -255,7 +255,7 @@ static int ctapi_connect(sc_reader_t *reader)
|
|||
|
||||
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
|
||||
if (rv || rbuf[lr-2] != 0x90) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error activating card: %d\n", rv);
|
||||
sc_log(reader->ctx, "Error activating card: %d", rv);
|
||||
return SC_ERROR_TRANSMIT_FAILED;
|
||||
}
|
||||
if (lr < 2)
|
||||
|
@ -307,7 +307,7 @@ static struct sc_reader_driver ctapi_drv = {
|
|||
};
|
||||
|
||||
static struct ctapi_module * add_module(struct ctapi_global_private_data *gpriv,
|
||||
const char *name, void *dlhandle)
|
||||
const char *name, void *dlhandle)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -322,30 +322,28 @@ static struct ctapi_module * add_module(struct ctapi_global_private_data *gpriv,
|
|||
}
|
||||
|
||||
static int ctapi_load_module(sc_context_t *ctx,
|
||||
struct ctapi_global_private_data *gpriv,
|
||||
scconf_block *conf)
|
||||
struct ctapi_global_private_data *gpriv, scconf_block *conf)
|
||||
{
|
||||
const char *val;
|
||||
struct ctapi_functions funcs;
|
||||
struct ctapi_module *mod;
|
||||
const scconf_list *list;
|
||||
scconf_block *conf_block = NULL;
|
||||
void *dlh;
|
||||
int r, i, NumUnits;
|
||||
u8 cmd[5], rbuf[256], sad, dad;
|
||||
unsigned short lr;
|
||||
|
||||
|
||||
|
||||
list = scconf_find_list(conf, "ports");
|
||||
if (list == NULL) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "No ports configured.\n");
|
||||
sc_log(ctx, "No ports configured.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
val = conf->name->data;
|
||||
dlh = sc_dlopen(val);
|
||||
if (!dlh) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to open shared library '%s': %s\n", val, sc_dlerror());
|
||||
sc_log(ctx, "Unable to open shared library '%s': %s", val, sc_dlerror());
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -368,12 +366,12 @@ static int ctapi_load_module(sc_context_t *ctx,
|
|||
struct ctapi_private_data *priv;
|
||||
|
||||
if (sscanf(list->data, "%d", &port) != 1) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Port '%s' is not a number.\n", list->data);
|
||||
sc_log(ctx, "Port '%s' is not a number.", list->data);
|
||||
continue;
|
||||
}
|
||||
rv = funcs.CT_init((unsigned short)mod->ctn_count, (unsigned short)port);
|
||||
if (rv) {
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "CT_init() failed with %d\n", rv);
|
||||
sc_log(ctx, "CT_init() failed with %d", rv);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -391,6 +389,16 @@ static int ctapi_load_module(sc_context_t *ctx,
|
|||
reader->name = strdup(namebuf);
|
||||
priv->funcs = funcs;
|
||||
priv->ctn = mod->ctn_count;
|
||||
|
||||
reader->max_send_size = SC_READER_SHORT_APDU_MAX_SEND_SIZE;
|
||||
reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
|
||||
|
||||
conf_block = sc_get_conf_block(ctx, "reader_driver", "ctapi", 1);
|
||||
if (conf_block) {
|
||||
reader->max_send_size = scconf_get_int(conf_block, "max_send_size", reader->max_send_size);
|
||||
reader->max_recv_size = scconf_get_int(conf_block, "max_recv_size", reader->max_recv_size);
|
||||
}
|
||||
|
||||
r = _sc_add_reader(ctx, reader);
|
||||
if (r) {
|
||||
funcs.CT_close((unsigned short)mod->ctn_count);
|
||||
|
@ -413,16 +421,16 @@ static int ctapi_load_module(sc_context_t *ctx,
|
|||
|
||||
rv = priv->funcs.CT_data(priv->ctn, &dad, &sad, 5, cmd, &lr, rbuf);
|
||||
if (rv || (lr < 4) || (rbuf[lr-2] != 0x90)) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Error getting status of terminal: %d, using defaults\n", rv);
|
||||
sc_log(reader->ctx, "Error getting status of terminal: %d, using defaults", rv);
|
||||
}
|
||||
if (rbuf[0] != CTBCS_P2_STATUS_TFU) {
|
||||
/* Number of slots might also detected by using CTBCS_P2_STATUS_ICC.
|
||||
If you think that's important please do it... ;) */
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x\n", rbuf[0]);
|
||||
sc_log(reader->ctx, "Invalid data object returnd on CTBCS_P2_STATUS_TFU: 0x%x", rbuf[0]);
|
||||
}
|
||||
NumUnits = rbuf[1];
|
||||
if (NumUnits + 4 > lr) {
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Invalid data returnd: %d functional units, size %d\n", NumUnits, rv);
|
||||
sc_log(reader->ctx, "Invalid data returnd: %d functional units, size %d", NumUnits, rv);
|
||||
}
|
||||
priv->ctapi_functional_units = 0;
|
||||
for(i = 0; i < NumUnits; i++) {
|
||||
|
@ -444,22 +452,22 @@ static int ctapi_load_module(sc_context_t *ctx,
|
|||
/* Maybe a weak point here if multiple interfaces are present and not returned
|
||||
in the "canonical" order. This is not forbidden by the specs, but why should
|
||||
anyone want to do that? */
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Found slot id 0x%x\n", rbuf[i+2]);
|
||||
sc_log(reader->ctx, "Found slot id 0x%x", rbuf[i+2]);
|
||||
break;
|
||||
|
||||
case CTBCS_P1_DISPLAY:
|
||||
priv->ctapi_functional_units |= CTAPI_FU_DISPLAY;
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Display detected\n");
|
||||
sc_log(reader->ctx, "Display detected");
|
||||
break;
|
||||
|
||||
case CTBCS_P1_KEYPAD:
|
||||
priv->ctapi_functional_units |= CTAPI_FU_KEYBOARD;
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Keypad detected\n");
|
||||
sc_log(reader->ctx, "Keypad detected");
|
||||
break;
|
||||
|
||||
case CTBCS_P1_PRINTER:
|
||||
priv->ctapi_functional_units |= CTAPI_FU_PRINTER;
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Printer detected\n");
|
||||
sc_log(reader->ctx, "Printer detected");
|
||||
break;
|
||||
|
||||
case CTBCS_P1_FINGERPRINT:
|
||||
|
@ -468,11 +476,11 @@ static int ctapi_load_module(sc_context_t *ctx,
|
|||
case CTBCS_P1_FACE_RECOGNITION:
|
||||
case CTBCS_P1_IRISSCAN:
|
||||
priv->ctapi_functional_units |= CTAPI_FU_BIOMETRIC;
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Biometric sensor detected\n");
|
||||
sc_log(reader->ctx, "Biometric sensor detected");
|
||||
break;
|
||||
|
||||
default:
|
||||
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Unknown functional unit 0x%x\n", rbuf[i+2]);
|
||||
sc_log(reader->ctx, "Unknown functional unit 0x%x", rbuf[i+2]);
|
||||
}
|
||||
}
|
||||
/* CT-BCS does not define Keyboard/Display for each slot, so I assume
|
||||
|
@ -490,7 +498,7 @@ static int ctapi_load_module(sc_context_t *ctx,
|
|||
}
|
||||
return 0;
|
||||
symerr:
|
||||
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to resolve CT-API symbols.\n");
|
||||
sc_log(ctx, "Unable to resolve CT-API symbols.");
|
||||
sc_dlclose(dlh);
|
||||
return -1;
|
||||
}
|
||||
|
@ -506,21 +514,13 @@ static int ctapi_init(sc_context_t *ctx)
|
|||
return SC_ERROR_OUT_OF_MEMORY;
|
||||
ctx->reader_drv_data = gpriv;
|
||||
|
||||
for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
|
||||
blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
|
||||
"reader_driver", "ctapi");
|
||||
if (blocks && blocks[0])
|
||||
conf_block = blocks[0];
|
||||
conf_block = sc_get_conf_block(ctx, "reader_driver", "ctapi", 1);
|
||||
if (conf_block) {
|
||||
blocks = scconf_find_blocks(ctx->conf, conf_block, "module", NULL);
|
||||
for (i = 0; blocks != NULL && blocks[i] != NULL; i++)
|
||||
ctapi_load_module(ctx, gpriv, blocks[i]);
|
||||
free(blocks);
|
||||
if (conf_block != NULL)
|
||||
break;
|
||||
}
|
||||
if (conf_block == NULL)
|
||||
return 0;
|
||||
blocks = scconf_find_blocks(ctx->conf, conf_block, "module", NULL);
|
||||
for (i = 0; blocks != NULL && blocks[i] != NULL; i++)
|
||||
ctapi_load_module(ctx, gpriv, blocks[i]);
|
||||
free(blocks);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ static int
|
|||
openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info)
|
||||
{
|
||||
sc_reader_t *reader;
|
||||
scconf_block *conf_block;
|
||||
struct driver_data *data;
|
||||
int rc;
|
||||
|
||||
|
@ -119,6 +120,12 @@ openct_add_reader(sc_context_t *ctx, unsigned int num, ct_info_t *info)
|
|||
reader->drv_data = data;
|
||||
reader->name = strdup(data->info.ct_name);
|
||||
|
||||
conf_block = sc_get_conf_block(ctx, "reader_driver", "openct", 1);
|
||||
if (conf_block) {
|
||||
reader->max_send_size = scconf_get_int(conf_block, "max_send_size", reader->max_send_size);
|
||||
reader->max_recv_size = scconf_get_int(conf_block, "max_recv_size", reader->max_recv_size);
|
||||
}
|
||||
|
||||
if ((rc = _sc_add_reader(ctx, reader)) < 0) {
|
||||
free(data);
|
||||
free(reader->name);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -50,10 +50,11 @@ const char *sc_get_version(void)
|
|||
int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen)
|
||||
{
|
||||
int err = SC_SUCCESS;
|
||||
size_t left, count = 0;
|
||||
size_t left, count = 0, in_len;
|
||||
|
||||
assert(in != NULL && out != NULL && outlen != NULL);
|
||||
left = *outlen;
|
||||
left = *outlen;
|
||||
in_len = strlen(in);
|
||||
|
||||
while (*in != '\0') {
|
||||
int byte = 0, nybbles = 2;
|
||||
|
@ -76,10 +77,17 @@ int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen)
|
|||
}
|
||||
byte |= c;
|
||||
}
|
||||
|
||||
/* Detect premature end of string before byte is complete */
|
||||
if (in_len > 1 && *in == '\0' && nybbles >= 0) {
|
||||
err = SC_ERROR_INVALID_ARGUMENTS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*in == ':' || *in == ' ')
|
||||
in++;
|
||||
if (left <= 0) {
|
||||
err = SC_ERROR_BUFFER_TOO_SMALL;
|
||||
err = SC_ERROR_BUFFER_TOO_SMALL;
|
||||
break;
|
||||
}
|
||||
out[count++] = (u8) byte;
|
||||
|
@ -798,12 +806,12 @@ void *sc_mem_alloc_secure(sc_context_t *ctx, size_t len)
|
|||
|
||||
pointer = calloc(len, sizeof(unsigned char));
|
||||
if (!pointer)
|
||||
return NULL;
|
||||
return NULL;
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
/* TODO mprotect */
|
||||
/* Do not swap the memory */
|
||||
if (mlock(pointer, len) >= 0)
|
||||
locked = 1;
|
||||
locked = 1;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
/* Do not swap the memory */
|
||||
|
@ -811,26 +819,27 @@ void *sc_mem_alloc_secure(sc_context_t *ctx, size_t len)
|
|||
locked = 1;
|
||||
#endif
|
||||
if (!locked) {
|
||||
if (ctx->flags & SC_CTX_FLAG_PARANOID_MEMORY) {
|
||||
sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, failing allocation because paranoid set");
|
||||
free (pointer);
|
||||
pointer = NULL;
|
||||
} else {
|
||||
sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, sensitive data may be paged to disk");
|
||||
}
|
||||
if (ctx->flags & SC_CTX_FLAG_PARANOID_MEMORY) {
|
||||
sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, failing allocation because paranoid set");
|
||||
free (pointer);
|
||||
pointer = NULL;
|
||||
} else {
|
||||
sc_do_log (ctx, 0, NULL, 0, NULL, "cannot lock memory, sensitive data may be paged to disk");
|
||||
}
|
||||
}
|
||||
return pointer;
|
||||
}
|
||||
|
||||
void sc_mem_clear(void *ptr, size_t len)
|
||||
{
|
||||
#ifdef ENABLE_OPENSSL
|
||||
/* FIXME: Bug in 1.0.0-beta series crashes with 0 length */
|
||||
if (len > 0)
|
||||
if (len > 0) {
|
||||
#ifdef ENABLE_OPENSSL
|
||||
OPENSSL_cleanse(ptr, len);
|
||||
#else
|
||||
memset(ptr, 0, len);
|
||||
memset(ptr, 0, len);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int sc_mem_reverse(unsigned char *buf, size_t len)
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include "libopensc/pkcs15.h"
|
||||
#include "libopensc/log.h"
|
||||
#include "libopensc/internal.h"
|
||||
#include "libopensc/aux-data.h"
|
||||
#include "pkcs15init/pkcs15-init.h"
|
||||
|
||||
#ifdef ENABLE_OPENSSL
|
||||
|
@ -148,11 +149,11 @@ struct md_pkcs15_container {
|
|||
int index;
|
||||
struct sc_pkcs15_id id;
|
||||
char guid[MAX_CONTAINER_NAME_LEN + 1];
|
||||
unsigned flags;
|
||||
unsigned char flags;
|
||||
size_t size_key_exchange, size_sign;
|
||||
|
||||
struct sc_pkcs15_object *cert_obj, *prkey_obj, *pubkey_obj;
|
||||
BOOL guid_overwrite;
|
||||
// BOOL guid_overwrite;
|
||||
};
|
||||
|
||||
struct md_dh_agreement {
|
||||
|
@ -195,8 +196,8 @@ typedef struct _VENDOR_SPECIFIC
|
|||
}VENDOR_SPECIFIC;
|
||||
|
||||
/*
|
||||
* Windows (ex. Vista) may access the card from more the one thread.
|
||||
* The following data type and static data is an attemt to resolve
|
||||
* Windows (ex. Vista) may access the card from more than one thread.
|
||||
* The following data type and static data is an attempt to resolve
|
||||
* some of the encountered multi-thread issues of OpenSC
|
||||
* on the minidriver side.
|
||||
*
|
||||
|
@ -246,8 +247,6 @@ static void logprintf(PCARD_DATA pCardData, int level, _Printf_format_string_ co
|
|||
{
|
||||
va_list arg;
|
||||
VENDOR_SPECIFIC *vs;
|
||||
#define CARDMOD_LOW_LEVEL_DEBUG 1
|
||||
#ifdef CARDMOD_LOW_LEVEL_DEBUG
|
||||
/* Use a simplied log to get all messages including messages
|
||||
* before opensc is loaded. The file must be modifiable by all
|
||||
* users as we maybe called under lsa or user. Note data from
|
||||
|
@ -255,20 +254,23 @@ static void logprintf(PCARD_DATA pCardData, int level, _Printf_format_string_ co
|
|||
* flush to get last message before ann crash
|
||||
* close so as the file is not left open during any wait.
|
||||
*/
|
||||
{
|
||||
FILE* lldebugfp = NULL;
|
||||
DWORD md_debug = 0;
|
||||
DWORD sz = sizeof(md_debug);
|
||||
int rv;
|
||||
|
||||
lldebugfp = fopen("C:\\tmp\\md.log","a+");
|
||||
rv = sc_ctx_win32_get_config_value("CARDMOD_LOW_LEVEL_DEBUG",
|
||||
"MiniDriverDebug", "Software\\OpenSC Project\\OpenSC",
|
||||
(char *)(&md_debug), &sz);
|
||||
if (rv == SC_SUCCESS && md_debug != 0) {
|
||||
FILE *lldebugfp = fopen("C:\\tmp\\md.log","a+");
|
||||
if (lldebugfp) {
|
||||
va_start(arg, format);
|
||||
vfprintf(lldebugfp, format, arg);
|
||||
va_end(arg);
|
||||
fflush(lldebugfp);
|
||||
fclose(lldebugfp);
|
||||
lldebugfp = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
va_start(arg, format);
|
||||
if(pCardData != NULL) {
|
||||
|
@ -557,39 +559,49 @@ static VOID md_generate_guid( __in_ecount(MAX_CONTAINER_NAME_LEN+1) PSTR szGuid)
|
|||
if (szRPCGuid) RpcStringFreeA(&szRPCGuid);
|
||||
}
|
||||
|
||||
static VOID
|
||||
static DWORD
|
||||
md_contguid_get_guid_from_card(PCARD_DATA pCardData, struct sc_pkcs15_object *prkey, __in_ecount(MAX_CONTAINER_NAME_LEN+1) PSTR szGuid)
|
||||
{
|
||||
int rv;
|
||||
VENDOR_SPECIFIC *vs;
|
||||
size_t guid_len = MAX_CONTAINER_NAME_LEN+1;
|
||||
|
||||
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
||||
rv = sc_pkcs15_get_object_guid(vs->p15card, prkey, 0, (unsigned char*) szGuid, &guid_len);
|
||||
rv = sc_pkcs15_get_object_guid(vs->p15card, prkey, 1, (unsigned char*) szGuid, &guid_len);
|
||||
if (rv) {
|
||||
logprintf(pCardData, 2, "md_contguid_get_guid_from_card(): error %d\n", rv);
|
||||
return;
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
/* add a new entry in the guid conversion table */
|
||||
static VOID
|
||||
md_contguid_add_conversion(PCARD_DATA pCardData, struct sc_pkcs15_object *prkey,
|
||||
__in_ecount(MAX_CONTAINER_NAME_LEN+1) PSTR szWindowsGuid)
|
||||
static DWORD
|
||||
md_contguid_add_conversion(PCARD_DATA pCardData, struct sc_pkcs15_object *prkey,
|
||||
__in_ecount(MAX_CONTAINER_NAME_LEN+1) PSTR szWindowsGuid)
|
||||
{
|
||||
DWORD ret;
|
||||
int i;
|
||||
CHAR szOpenSCGuid[MAX_CONTAINER_NAME_LEN+1] = "";
|
||||
md_contguid_get_guid_from_card(pCardData, prkey, szOpenSCGuid);
|
||||
if (strcmp(szOpenSCGuid, szWindowsGuid) == 0)
|
||||
return;
|
||||
|
||||
ret = md_contguid_get_guid_from_card(pCardData, prkey, szOpenSCGuid);
|
||||
if (ret != SCARD_S_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (strcmp(szOpenSCGuid, szWindowsGuid) == 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < MD_MAX_CONVERSIONS; i++) {
|
||||
if (md_static_conversions[i].szWindowsGuid[0] == 0) {
|
||||
strcpy_s(md_static_conversions[i].szWindowsGuid, MAX_CONTAINER_NAME_LEN+1, szWindowsGuid);
|
||||
strcpy_s(md_static_conversions[i].szOpenSCGuid, MAX_CONTAINER_NAME_LEN+1, szOpenSCGuid);
|
||||
logprintf(pCardData, 0, "md_contguid_add_conversion(): Registering conversion '%s' '%s'\n", szWindowsGuid, szOpenSCGuid);
|
||||
return;
|
||||
return SCARD_S_SUCCESS;;
|
||||
}
|
||||
}
|
||||
logprintf(pCardData, 0, "md_contguid_add_conversion(): Unable to add a new conversion with guid %s. Further loads may trigger errors\n", szWindowsGuid);
|
||||
logprintf(pCardData, 0, "md_contguid_add_conversion(): Unable to add a new conversion with guid %s.\n", szWindowsGuid);
|
||||
return SCARD_F_INTERNAL_ERROR;;
|
||||
}
|
||||
|
||||
/* remove an entry in the guid conversion table*/
|
||||
|
@ -622,7 +634,7 @@ md_contguid_find_conversion(PCARD_DATA pCardData, __in_ecount(MAX_CONTAINER_NAME
|
|||
/* build key args from the minidriver guid */
|
||||
static VOID
|
||||
md_contguid_build_key_args_from_cont_guid(PCARD_DATA pCardData, __in_ecount(MAX_CONTAINER_NAME_LEN+1) PSTR szGuid,
|
||||
struct sc_pkcs15init_prkeyargs *prkey_args)
|
||||
struct sc_pkcs15init_prkeyargs *prkey_args)
|
||||
{
|
||||
/* strlen(szGuid) <= MAX_CONTAINER_NAME */
|
||||
logprintf(pCardData, 3, "Using the guid '%s'\n", szGuid);
|
||||
|
@ -641,13 +653,15 @@ md_contguid_build_key_args_from_cont_guid(PCARD_DATA pCardData, __in_ecount(MAX_
|
|||
}
|
||||
|
||||
/* build minidriver guid from the key */
|
||||
static VOID
|
||||
static DWORD
|
||||
md_contguid_build_cont_guid_from_key(PCARD_DATA pCardData, struct sc_pkcs15_object *key_obj, __in_ecount(MAX_CONTAINER_NAME_LEN+1) PSTR szGuid)
|
||||
{
|
||||
VENDOR_SPECIFIC *vs;
|
||||
struct sc_pkcs15_prkey_info *prkey_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
|
||||
DWORD dwret = SCARD_S_SUCCESS;
|
||||
|
||||
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
||||
|
||||
|
||||
szGuid[0] = '\0';
|
||||
/* priorize the use of the key id over the key label as a container name */
|
||||
if (md_is_guid_as_id(pCardData) && prkey_info->id.len > 0 && prkey_info->id.len <= MAX_CONTAINER_NAME_LEN) {
|
||||
|
@ -656,10 +670,34 @@ md_contguid_build_cont_guid_from_key(PCARD_DATA pCardData, struct sc_pkcs15_obje
|
|||
} else if (md_is_guid_as_label(pCardData) && key_obj->label[0] != 0) {
|
||||
strncpy_s(szGuid, MAX_CONTAINER_NAME_LEN+1, key_obj->label, MAX_CONTAINER_NAME_LEN);
|
||||
} else {
|
||||
md_contguid_get_guid_from_card(pCardData, key_obj, szGuid);
|
||||
dwret = md_contguid_get_guid_from_card(pCardData, key_obj, szGuid);
|
||||
}
|
||||
|
||||
return dwret;
|
||||
}
|
||||
|
||||
|
||||
static DWORD
|
||||
md_cont_flags_from_key(PCARD_DATA pCardData, struct sc_pkcs15_object *key_obj, unsigned char *cont_flags)
|
||||
{
|
||||
struct sc_pkcs15_prkey_info *prkey_info = NULL;
|
||||
VENDOR_SPECIFIC *vs;
|
||||
int rv;
|
||||
|
||||
vs = (VENDOR_SPECIFIC*) pCardData->pvVendorSpecific;
|
||||
prkey_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
|
||||
|
||||
*cont_flags = CONTAINER_MAP_VALID_CONTAINER;
|
||||
if (prkey_info->aux_data) {
|
||||
rv = sc_aux_data_get_md_flags(vs->ctx, prkey_info->aux_data, cont_flags);
|
||||
if (rv != SC_ERROR_NOT_SUPPORTED && rv != SC_SUCCESS)
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* Search directory by name and optionally by name of it's parent */
|
||||
static DWORD
|
||||
md_fs_find_directory(PCARD_DATA pCardData, struct md_directory *parent, char *name, struct md_directory **out)
|
||||
|
@ -986,111 +1024,14 @@ md_pkcs15_update_containers(PCARD_DATA pCardData, unsigned char *blob, size_t si
|
|||
cont->size_sign = pp->wSigKeySizeBits;
|
||||
cont->size_key_exchange = pp->wKeyExchangeKeySizeBits;
|
||||
logprintf(pCardData, 3, "update P15 containers: touch container (idx:%i,id:%s,guid:%.*s,flags:%X)\n",
|
||||
idx, sc_pkcs15_print_id(&cont->id),(int)sizeof cont->guid,cont->guid,cont->flags);
|
||||
idx, sc_pkcs15_print_id(&cont->id),
|
||||
(int)sizeof cont->guid, cont->guid, cont->flags);
|
||||
}
|
||||
}
|
||||
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
md_pkcs15_update_container_from_do(PCARD_DATA pCardData, struct sc_pkcs15_object *dobj)
|
||||
{
|
||||
VENDOR_SPECIFIC *vs;
|
||||
DWORD dwret = SCARD_F_INTERNAL_ERROR;
|
||||
struct sc_pkcs15_data *ddata = NULL;
|
||||
struct sc_pkcs15_id id;
|
||||
int rv, offs, idx;
|
||||
unsigned flags;
|
||||
|
||||
if (!pCardData || !dobj)
|
||||
return SCARD_E_INVALID_PARAMETER;
|
||||
vs = pCardData->pvVendorSpecific;
|
||||
|
||||
rv = sc_pkcs15_read_data_object(vs->p15card, (struct sc_pkcs15_data_info *)dobj->data, &ddata);
|
||||
if (rv) {
|
||||
logprintf(pCardData, 2, "sc_pkcs15_read_data_object('%.*s') returned %i\n", (int) sizeof dobj->label, dobj->label, rv);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
offs = 0;
|
||||
if (*(ddata->data + offs++) != 0x01) {
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
return SCARD_E_INVALID_VALUE;
|
||||
}
|
||||
id.len = *(ddata->data + offs++);
|
||||
memcpy(id.value, ddata->data + offs, id.len);
|
||||
offs += (int) id.len;
|
||||
|
||||
if (*(ddata->data + offs++) != 0x02) {
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
return SCARD_E_INVALID_VALUE;
|
||||
}
|
||||
if (*(ddata->data + offs++) != 0x01) {
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
return SCARD_E_INVALID_VALUE;
|
||||
}
|
||||
|
||||
flags = *(ddata->data + offs);
|
||||
|
||||
for (idx=0; idx<MD_MAX_KEY_CONTAINERS && vs->p15_containers[idx].prkey_obj; idx++) {
|
||||
if (vs->p15_containers[idx].guid_overwrite)
|
||||
continue;
|
||||
if (sc_pkcs15_compare_id(&id, &vs->p15_containers[idx].id)) {
|
||||
_snprintf_s(vs->p15_containers[idx].guid, MAX_CONTAINER_NAME_LEN+1, MAX_CONTAINER_NAME_LEN,
|
||||
"%s", dobj->label);
|
||||
vs->p15_containers[idx].flags = flags;
|
||||
logprintf(pCardData, 2, "Set container's guid to '%s' and flags to 0x%X\n",
|
||||
vs->p15_containers[idx].guid, flags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static DWORD
|
||||
md_pkcs15_default_container_from_do(PCARD_DATA pCardData, struct sc_pkcs15_object *dobj)
|
||||
{
|
||||
VENDOR_SPECIFIC *vs;
|
||||
struct sc_pkcs15_data *ddata = NULL;
|
||||
DWORD dwret = SCARD_F_INTERNAL_ERROR;
|
||||
int rv, idx;
|
||||
char guid[MAX_CONTAINER_NAME_LEN + 1];
|
||||
|
||||
if (!pCardData || !dobj)
|
||||
return SCARD_E_INVALID_PARAMETER;
|
||||
|
||||
vs = pCardData->pvVendorSpecific;
|
||||
|
||||
rv = sc_pkcs15_read_data_object(vs->p15card, (struct sc_pkcs15_data_info *)dobj->data, &ddata);
|
||||
if (rv) {
|
||||
logprintf(pCardData, 2, "sc_pkcs15_read_data_object('%.*s') returned %i\n", (int) sizeof dobj->label, dobj->label, rv);
|
||||
return SCARD_F_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (ddata->data_len > MAX_CONTAINER_NAME_LEN || ddata->data_len < 32) {
|
||||
logprintf(pCardData, 2, "Invalid container name length %i\n", ddata->data_len);
|
||||
return SCARD_E_INVALID_VALUE;
|
||||
}
|
||||
|
||||
memset(guid, 0, sizeof(guid));
|
||||
memcpy(&guid[0] , ddata->data, ddata->data_len);
|
||||
|
||||
logprintf(pCardData, 2, "Search container '%s' to set it as default\n", guid);
|
||||
for (idx=0; idx<MD_MAX_KEY_CONTAINERS && vs->p15_containers[idx].prkey_obj; idx++) {
|
||||
if (strstr(vs->p15_containers[idx].guid, guid)) {
|
||||
vs->p15_containers[idx].flags |= CONTAINER_MAP_DEFAULT_CONTAINER;
|
||||
logprintf(pCardData, 2, "Default container is '%s'\n", vs->p15_containers[idx].guid);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sc_pkcs15_free_data_object(ddata);
|
||||
return SCARD_S_SUCCESS;
|
||||
}
|
||||
|
||||
static DWORD
|
||||
md_pkcs15_delete_object(PCARD_DATA pCardData, struct sc_pkcs15_object *obj)
|
||||
|
@ -1474,11 +1415,11 @@ md_fs_add_msroot(PCARD_DATA pCardData, struct md_file **head)
|
|||
* Set the content of the 'soft' 'cmapfile':
|
||||
* 1. Initialize internal p15_contaniers with the existing private keys PKCS#15 objects;
|
||||
* 2. Try to read the content of the PKCS#15 'DATA' object 'CSP':'cmapfile',
|
||||
* If some record from the 'DATA' object references an existing key:
|
||||
* If some record from the 'DATA' object references an existing key:
|
||||
* 2a. Update the non-pkcs#15 attributes of the corresponding internal p15_container;
|
||||
* 2b. Change the index of internal p15_container according to the index from 'DATA' file.
|
||||
* Records from 'DATA' file are ignored is they do not have
|
||||
* the corresponding PKCS#15 private key object.
|
||||
* Records from 'DATA' file are ignored is they do not have
|
||||
* the corresponding PKCS#15 private key object.
|
||||
* 3. Initalize the content of the 'soft' 'cmapfile' from the inernal p15-containers.
|
||||
*/
|
||||
static DWORD
|
||||
|
@ -1525,21 +1466,28 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
|
|||
continue;
|
||||
}
|
||||
|
||||
md_contguid_build_cont_guid_from_key(pCardData, key_obj, cont->guid);
|
||||
dwret = md_contguid_build_cont_guid_from_key(pCardData, key_obj, cont->guid);
|
||||
if (dwret != SCARD_S_SUCCESS)
|
||||
return dwret;
|
||||
|
||||
/* replace the OpenSC guid by a Windows Guid if needed
|
||||
Typically used in the certificate enrollment process.
|
||||
Windows create a new container with a Windows guid, close the context, then create a new context and look for the previous container.
|
||||
If we return our guid, it fails because the Windows guid can't be found.
|
||||
The overwrite is present to avoid this conversion been replaced by md_pkcs15_update_container_from_do*/
|
||||
cont->guid_overwrite = md_contguid_find_conversion(pCardData, cont->guid);
|
||||
// cont->guid_overwrite = md_contguid_find_conversion(pCardData, cont->guid);
|
||||
|
||||
cont->flags = CONTAINER_MAP_VALID_CONTAINER;
|
||||
// cont->flags = CONTAINER_MAP_VALID_CONTAINER;
|
||||
dwret = md_cont_flags_from_key(pCardData, key_obj, &cont->flags);
|
||||
if (dwret != SCARD_S_SUCCESS)
|
||||
return dwret;
|
||||
if (cont->flags & CONTAINER_MAP_DEFAULT_CONTAINER)
|
||||
found_default = 1;
|
||||
|
||||
/* AT_KEYEXCHANGE is more general key usage,
|
||||
* it allows 'decryption' as well as 'signature' key usage.
|
||||
* AT_SIGNATURE allows only 'signature' usage.
|
||||
*/
|
||||
* it allows 'decryption' as well as 'signature' key usage.
|
||||
* AT_SIGNATURE allows only 'signature' usage.
|
||||
*/
|
||||
cont->size_key_exchange = cont->size_sign = 0;
|
||||
if (key_obj->type == SC_PKCS15_TYPE_PRKEY_RSA) {
|
||||
if (prkey_info->usage & USAGE_ANY_DECIPHER)
|
||||
|
@ -1573,6 +1521,7 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
|
|||
|
||||
if (conts_num) {
|
||||
/* Read 'CMAPFILE' (Gemalto style) and update the attributes of P15 containers */
|
||||
#if 0
|
||||
struct sc_pkcs15_object *dobjs[MD_MAX_KEY_CONTAINERS + 1], *default_cont = NULL;
|
||||
int num_dobjs = MD_MAX_KEY_CONTAINERS + 1;
|
||||
|
||||
|
@ -1611,7 +1560,7 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
|
|||
return dwret;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Initialize 'CMAPFILE' content from the P15 containers */
|
||||
p = (PCONTAINER_MAP_RECORD)cmap_buf;
|
||||
for (ii=0; ii<MD_MAX_KEY_CONTAINERS; ii++) {
|
||||
|
@ -1652,7 +1601,7 @@ md_set_cmapfile(PCARD_DATA pCardData, struct md_file *file)
|
|||
loghex(pCardData, 7, (PBYTE) (p+ii), sizeof(CONTAINER_MAP_RECORD));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dwret = md_fs_add_msroot(pCardData, &(file->next));
|
||||
if (dwret != SCARD_S_SUCCESS)
|
||||
return dwret;
|
||||
|
@ -2027,7 +1976,7 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke
|
|||
|
||||
/* use the Windows Guid as input to determine some characteristics of the key such as the label or the id */
|
||||
md_contguid_build_key_args_from_cont_guid(pCardData, cont->guid, &(keygen_args.prkey_args));
|
||||
|
||||
|
||||
if (keygen_args.prkey_args.label == NULL) {
|
||||
md_generate_guid(szGuid);
|
||||
keygen_args.prkey_args.label = szGuid;
|
||||
|
@ -2040,7 +1989,9 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke
|
|||
goto done;
|
||||
}
|
||||
|
||||
md_contguid_add_conversion(pCardData, cont->prkey_obj, cont->guid);
|
||||
dwret = md_contguid_add_conversion(pCardData, cont->prkey_obj, cont->guid);
|
||||
if (dwret != SCARD_S_SUCCESS)
|
||||
return dwret;
|
||||
|
||||
cont->id = ((struct sc_pkcs15_prkey_info *)cont->prkey_obj->data)->id;
|
||||
cont->index = idx;
|
||||
|
@ -2049,7 +2000,6 @@ md_pkcs15_generate_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, DWORD ke
|
|||
logprintf(pCardData, 3, "MdGenerateKey(): generated key(idx:%i,id:%s,guid:%.*s)\n",
|
||||
idx, sc_pkcs15_print_id(&cont->id),(int) sizeof cont->guid, cont->guid);
|
||||
|
||||
dwret = SCARD_S_SUCCESS;
|
||||
done:
|
||||
sc_pkcs15init_unbind(profile);
|
||||
sc_unlock(card);
|
||||
|
@ -2146,11 +2096,11 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob,
|
|||
|
||||
sc_pkcs15init_set_p15card(profile, vs->p15card);
|
||||
cont = &(vs->p15_containers[idx]);
|
||||
|
||||
|
||||
prkey_args.label = szGuid;
|
||||
/* use the Windows Guid as input to determine some characteristics of the key such as the label or the id */
|
||||
md_contguid_build_key_args_from_cont_guid(pCardData, cont->guid, &prkey_args);
|
||||
|
||||
|
||||
memcpy(pubkey_args.id.value, prkey_args.id.value, prkey_args.id.len);
|
||||
pubkey_args.id.len = prkey_args.id.len;
|
||||
pubkey_args.label = prkey_args.label;
|
||||
|
@ -2172,14 +2122,15 @@ md_pkcs15_store_key(PCARD_DATA pCardData, DWORD idx, DWORD key_type, BYTE *blob,
|
|||
goto done;
|
||||
}
|
||||
|
||||
md_contguid_add_conversion(pCardData, cont->prkey_obj, cont->guid);
|
||||
dwret = md_contguid_add_conversion(pCardData, cont->prkey_obj, cont->guid);
|
||||
if (dwret != SCARD_S_SUCCESS)
|
||||
return dwret;
|
||||
|
||||
cont->id = ((struct sc_pkcs15_prkey_info *)cont->prkey_obj->data)->id;
|
||||
cont->index = idx;
|
||||
cont->flags |= CONTAINER_MAP_VALID_CONTAINER;
|
||||
|
||||
logprintf(pCardData, 3, "MdStoreKey(): stored key(idx:%i,id:%s,guid:%.*s)\n", idx, sc_pkcs15_print_id(&cont->id),(int) sizeof cont->guid,cont->guid);
|
||||
dwret = SCARD_S_SUCCESS;
|
||||
|
||||
done:
|
||||
sc_pkcs15init_unbind(profile);
|
||||
|
@ -3881,7 +3832,7 @@ DWORD WINAPI CardSignData(__in PCARD_DATA pCardData, __inout PCARD_SIGNING_INFO
|
|||
r = sc_pkcs15_compute_signature(vs->p15card, pkey, opt_crypt_flags, dataToSign, dataToSignLen, pbuf, lg);
|
||||
logprintf(pCardData, 2, "sc_pkcs15_compute_signature return %d\n", r);
|
||||
if(r < 0) {
|
||||
logprintf(pCardData, 2, "sc_pkcs15_compute_signature erreur %s\n", sc_strerror(r));
|
||||
logprintf(pCardData, 2, "sc_pkcs15_compute_signature error %s\n", sc_strerror(r));
|
||||
pCardData->pfnCspFree(pbuf);
|
||||
return md_translate_OpenSC_to_Windows_error(r, SCARD_F_INTERNAL_ERROR);
|
||||
}
|
||||
|
@ -5739,7 +5690,6 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL,
|
|||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
#ifdef CARDMOD_LOW_LEVEL_DEBUG
|
||||
CHAR name[MAX_PATH + 1] = "\0";
|
||||
char *reason = "";
|
||||
|
||||
|
@ -5762,7 +5712,6 @@ BOOL APIENTRY DllMain( HINSTANCE hinstDLL,
|
|||
|
||||
logprintf(NULL,8,"\n********** DllMain Module(handle:0x%p) '%s'; reason='%s'; Reserved=%p; P:%d; T:%d\n",
|
||||
hinstDLL, name, reason, lpReserved, GetCurrentProcessId(), GetCurrentThreadId());
|
||||
#endif
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
|
|
|
@ -66,7 +66,7 @@ filesystem {
|
|||
|
||||
# Private RSA keys
|
||||
EF OberthurAWP-private-key-info {
|
||||
ACL = WRITE=CHV1, UPDATE=CHV1, READ=CHV1;
|
||||
ACL = WRITE=CHV1, UPDATE=CHV1, READ=NONE;
|
||||
}
|
||||
EF template-private-key {
|
||||
file-id = 3000;
|
||||
|
@ -78,7 +78,7 @@ filesystem {
|
|||
|
||||
# Private DES keys
|
||||
EF OberthurAWP-private-des-info {
|
||||
ACL = WRITE=CHV1, UPDATE=CHV1, READ=CHV1;
|
||||
ACL = WRITE=CHV1, UPDATE=CHV1, READ=NONE;
|
||||
}
|
||||
EF template-private-des {
|
||||
file-id = 4000;
|
||||
|
@ -90,7 +90,7 @@ filesystem {
|
|||
|
||||
# Private data
|
||||
EF OberthurAWP-privdata-info {
|
||||
ACL = WRITE=CHV1, UPDATE=CHV1, READ=CHV1;
|
||||
ACL = WRITE=CHV1, UPDATE=CHV1, READ=NONE;
|
||||
}
|
||||
EF template-privdata {
|
||||
file-id = 6000;
|
||||
|
|
|
@ -855,15 +855,39 @@ authentic_emu_update_tokeninfo(struct sc_profile *profile, struct sc_pkcs15_card
|
|||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
static int
|
||||
authentic_pkcs15_init_card(struct sc_profile *profile, struct sc_pkcs15_card *p15card)
|
||||
{
|
||||
LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
authentic_pkcs15_create_dir(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
|
||||
struct sc_file *df)
|
||||
{
|
||||
LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
authentic_pkcs15_create_pin(struct sc_profile *profile, struct sc_pkcs15_card *p15card,
|
||||
struct sc_file *df, struct sc_pkcs15_object *pin_obj,
|
||||
const unsigned char *pin, size_t pin_len,
|
||||
const unsigned char *puk, size_t puk_len)
|
||||
{
|
||||
LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_NOT_SUPPORTED);
|
||||
}
|
||||
|
||||
|
||||
static struct sc_pkcs15init_operations
|
||||
sc_pkcs15init_authentic_operations = {
|
||||
authentic_pkcs15_erase_card,
|
||||
NULL, /* init_card */
|
||||
NULL, /* create_dir */
|
||||
authentic_pkcs15_init_card,
|
||||
authentic_pkcs15_create_dir,
|
||||
NULL, /* create_domain */
|
||||
NULL, /* select_pin_reference */
|
||||
NULL, /* create_pin */
|
||||
authentic_pkcs15_create_pin,
|
||||
authentic_pkcs15_select_key_reference,
|
||||
authentic_pkcs15_create_key,
|
||||
authentic_pkcs15_store_key,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
||||
* Copyright (C) 2010 Viktor Tarasov <vtarasov@opentrust.com>
|
||||
* OpenTrust <www.opentrust.com>
|
||||
* OpenTrust <www.opentrust.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -671,7 +671,7 @@ iasecc_pkcs15_get_auth_id_from_se(struct sc_pkcs15_card *p15card, unsigned char
|
|||
struct sc_pkcs15_id *auth_id)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_object *pin_objs[32];
|
||||
struct sc_pkcs15_object *pin_objs[32];
|
||||
int rv, ii, nn_pins, se_ref, pin_ref;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
@ -683,7 +683,7 @@ iasecc_pkcs15_get_auth_id_from_se(struct sc_pkcs15_card *p15card, unsigned char
|
|||
if (!(scb & IASECC_SCB_METHOD_USER_AUTH))
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, pin_objs, 32);
|
||||
rv = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, pin_objs, 32);
|
||||
LOG_TEST_RET(ctx, rv, "Error while getting AUTH objects");
|
||||
nn_pins = rv;
|
||||
|
||||
|
@ -1441,12 +1441,12 @@ iasecc_md_gemalto_set_default(struct sc_pkcs15_card *p15card, struct sc_profile
|
|||
struct sc_file *file = NULL;
|
||||
|
||||
sc_log(ctx, "update data object content in '%s'\n", sc_print_path(&dinfo->path));
|
||||
rv = sc_select_file(p15card->card, &dinfo->path, &file);
|
||||
LOG_TEST_RET(ctx, rv, "Cannot select data object file");
|
||||
rv = sc_select_file(p15card->card, &dinfo->path, &file);
|
||||
LOG_TEST_RET(ctx, rv, "Cannot select data object file");
|
||||
|
||||
rv = sc_pkcs15init_update_file(profile, p15card, file, guid, guid_len);
|
||||
sc_file_free(file);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to update 'CSP'/'Default Key Container' data object");
|
||||
rv = sc_pkcs15init_update_file(profile, p15card, file, guid, guid_len);
|
||||
sc_file_free(file);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to update 'CSP'/'Default Key Container' data object");
|
||||
}
|
||||
|
||||
LOG_FUNC_RETURN(ctx, rv);
|
||||
|
@ -1460,7 +1460,7 @@ iasecc_md_gemalto_unset_default(struct sc_pkcs15_card *p15card, struct sc_profil
|
|||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_object *data_obj = NULL;
|
||||
struct sc_pkcs15_data *dod = NULL;
|
||||
struct sc_pkcs15_object *key_objs[32];
|
||||
struct sc_pkcs15_object *key_objs[32];
|
||||
struct sc_pkcs15_prkey_info *key_info = (struct sc_pkcs15_prkey_info *)key_obj->data;
|
||||
unsigned char guid[40];
|
||||
size_t guid_len;
|
||||
|
@ -1545,7 +1545,7 @@ iasecc_md_gemalto_new_prvkey(struct sc_pkcs15_card *p15card, struct sc_profile *
|
|||
sc_init_oid(&data_args.app_oid);
|
||||
data_args.label = (char *)guid;
|
||||
data_args.app_label = "CSP";
|
||||
data_args.der_encoded.value = data;
|
||||
data_args.der_encoded.value = data;
|
||||
data_args.der_encoded.len = offs;
|
||||
|
||||
rv = sc_pkcs15init_store_data_object(p15card, profile, &data_args, NULL);
|
||||
|
@ -1581,7 +1581,7 @@ iasecc_md_gemalto_delete_prvkey(struct sc_pkcs15_card *p15card, struct sc_profil
|
|||
LOG_TEST_RET(ctx, rv, "Cannot get private key GUID");
|
||||
|
||||
rv = sc_pkcs15_find_data_object_by_name(p15card, "CSP", (char *)guid, &data_obj);
|
||||
if (rv == SC_ERROR_OBJECT_NOT_FOUND)
|
||||
if (rv == SC_ERROR_OBJECT_NOT_FOUND)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
LOG_TEST_RET(ctx, rv, "Find 'CSP'/<key> data object error");
|
||||
|
||||
|
@ -1643,22 +1643,22 @@ iasecc_store_pubkey(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|||
|
||||
prkey_info = (struct sc_pkcs15_prkey_info *)prkey_object->data;
|
||||
|
||||
pubkey_info->key_reference = prkey_info->key_reference;
|
||||
pubkey_info->key_reference = prkey_info->key_reference;
|
||||
|
||||
pubkey_info->access_flags = prkey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL;
|
||||
pubkey_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
|
||||
pubkey_info->access_flags = prkey_info->access_flags & SC_PKCS15_PRKEY_ACCESS_LOCAL;
|
||||
pubkey_info->access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
|
||||
|
||||
pubkey_info->native = 0;
|
||||
pubkey_info->native = 0;
|
||||
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_SIGN ? SC_PKCS15_PRKEY_USAGE_VERIFY : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_SIGNRECOVER ? SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION ? SC_PKCS15_PRKEY_USAGE_VERIFY : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT ? SC_PKCS15_PRKEY_USAGE_ENCRYPT : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP ? SC_PKCS15_PRKEY_USAGE_WRAP : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_SIGN ? SC_PKCS15_PRKEY_USAGE_VERIFY : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_SIGNRECOVER ? SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION ? SC_PKCS15_PRKEY_USAGE_VERIFY : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_DECRYPT ? SC_PKCS15_PRKEY_USAGE_ENCRYPT : 0;
|
||||
pubkey_info->usage |= prkey_info->usage & SC_PKCS15_PRKEY_USAGE_UNWRAP ? SC_PKCS15_PRKEY_USAGE_WRAP : 0;
|
||||
|
||||
iasecc_pkcs15_add_access_rule(object, SC_PKCS15_ACCESS_RULE_MODE_READ, NULL);
|
||||
iasecc_pkcs15_add_access_rule(object, SC_PKCS15_ACCESS_RULE_MODE_READ, NULL);
|
||||
|
||||
memcpy(&pubkey_info->algo_refs[0], &prkey_info->algo_refs[0], sizeof(pubkey_info->algo_refs));
|
||||
memcpy(&pubkey_info->algo_refs[0], &prkey_info->algo_refs[0], sizeof(pubkey_info->algo_refs));
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
@ -1672,6 +1672,7 @@ iasecc_store_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_card *card = p15card->card;
|
||||
struct sc_file *pfile = NULL;
|
||||
struct sc_path parent_path;
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
@ -1680,6 +1681,14 @@ iasecc_store_cert(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
|
|||
rv = iasecc_pkcs15_new_file(profile, card, SC_PKCS15_TYPE_CERT, 0, &pfile);
|
||||
LOG_TEST_RET(ctx, rv, "IasEcc new CERT file error");
|
||||
|
||||
parent_path = pfile->path;
|
||||
if (parent_path.len >= 2)
|
||||
parent_path.len -= 2;
|
||||
if (!parent_path.len && !parent_path.aid.len)
|
||||
sc_format_path("3F00", &parent_path);
|
||||
rv = sc_select_file(card, &parent_path, NULL);
|
||||
LOG_TEST_RET(ctx, rv, "cannot select parent of certificate to store");
|
||||
|
||||
rv = iasecc_pkcs15_fix_file_access(p15card, pfile, object);
|
||||
LOG_TEST_RET(ctx, rv, "encode file access rules failed");
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@
|
|||
#include "libopensc/cardctl.h"
|
||||
#include "libopensc/asn1.h"
|
||||
#include "libopensc/log.h"
|
||||
#include "libopensc/aux-data.h"
|
||||
#include "profile.h"
|
||||
#include "pkcs15-init.h"
|
||||
|
||||
|
@ -813,12 +814,14 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile,
|
|||
*/
|
||||
sc_log(ctx, "Add virtual SO_PIN('%.*s',flags:%X,reference:%i,path:'%s')", (int) sizeof pin_obj->label, pin_obj->label,
|
||||
pin_attrs->flags, pin_attrs->reference, sc_print_path(&pin_ainfo.path));
|
||||
|
||||
r = sc_pkcs15_add_object(p15card, pin_obj);
|
||||
LOG_TEST_RET(ctx, r, "Failed to add 'SOPIN' AUTH object");
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform card-specific initialization */
|
||||
|
||||
if (profile->ops->init_card) {
|
||||
r = profile->ops->init_card(profile, p15card);
|
||||
if (r < 0 && pin_obj) {
|
||||
|
@ -829,11 +832,12 @@ sc_pkcs15init_add_app(struct sc_card *card, struct sc_profile *profile,
|
|||
}
|
||||
|
||||
/* Create the application directory */
|
||||
r = profile->ops->create_dir(profile, p15card, df);
|
||||
if (profile->ops->create_dir)
|
||||
r = profile->ops->create_dir(profile, p15card, df);
|
||||
LOG_TEST_RET(ctx, r, "Create 'DIR' error");
|
||||
|
||||
/* Store SO PIN */
|
||||
if (pin_obj)
|
||||
if (pin_obj && profile->ops->create_pin)
|
||||
r = profile->ops->create_pin(profile, p15card, df, pin_obj,
|
||||
args->so_pin, args->so_pin_len,
|
||||
args->so_puk, args->so_puk_len);
|
||||
|
@ -1264,6 +1268,46 @@ err:
|
|||
}
|
||||
|
||||
|
||||
static int
|
||||
_pkcd15init_set_aux_md_data(struct sc_pkcs15_card *p15card, struct sc_auxiliary_data **aux_data,
|
||||
unsigned char *guid, size_t guid_len)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
unsigned char flags = SC_MD_CONTAINER_MAP_VALID_CONTAINER;
|
||||
char gd[SC_MD_MAX_CONTAINER_NAME_LEN + 1];
|
||||
int rv;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
||||
if(!guid || !guid_len)
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
|
||||
if (!aux_data)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
|
||||
|
||||
if (guid_len > SC_MD_MAX_CONTAINER_NAME_LEN)
|
||||
LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_DATA);
|
||||
|
||||
memset(gd, 0, sizeof(gd));
|
||||
memcpy(gd, guid, guid_len);
|
||||
|
||||
if (*aux_data == NULL) {
|
||||
rv = sc_aux_data_allocate(ctx, aux_data, NULL);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to allocate aux data");
|
||||
}
|
||||
|
||||
rv = sc_aux_data_set_md_guid(ctx, *aux_data, gd);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to set private key CMAP record GUID");
|
||||
|
||||
if (sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0) == 0)
|
||||
flags |= SC_MD_CONTAINER_MAP_DEFAULT_CONTAINER;
|
||||
|
||||
rv = sc_aux_data_set_md_flags(ctx, *aux_data, flags);
|
||||
LOG_TEST_RET(ctx, rv, "Failed to set private key CMAP record flags");
|
||||
|
||||
LOG_FUNC_RETURN(ctx, SC_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate a new private key
|
||||
*/
|
||||
|
@ -1309,6 +1353,10 @@ sc_pkcs15init_generate_key(struct sc_pkcs15_card *p15card, struct sc_profile *pr
|
|||
|
||||
key_info = (struct sc_pkcs15_prkey_info *) object->data;
|
||||
|
||||
r = _pkcd15init_set_aux_md_data(p15card, &key_info->aux_data,
|
||||
keygen_args->prkey_args.guid, keygen_args->prkey_args.guid_len);
|
||||
LOG_TEST_RET(ctx, r, "Failed to set aux MD data");
|
||||
|
||||
/* Set up the PuKDF info. The public key will be filled in
|
||||
* by the card driver's generate_key function called below.
|
||||
* Auth.ID of the public key object is left empty. */
|
||||
|
@ -1394,8 +1442,9 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil
|
|||
struct sc_pkcs15init_prkeyargs *keyargs, struct sc_pkcs15_object **res_obj)
|
||||
{
|
||||
struct sc_context *ctx = p15card->card->ctx;
|
||||
struct sc_pkcs15_object *object;
|
||||
struct sc_pkcs15_object *object = NULL;
|
||||
struct sc_pkcs15_prkey key;
|
||||
struct sc_pkcs15_prkey_info *key_info = NULL;
|
||||
int keybits, r = 0;
|
||||
|
||||
LOG_FUNC_CALLED(ctx);
|
||||
|
@ -1435,8 +1484,9 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card, struct sc_profil
|
|||
r = sc_pkcs15init_encode_prvkey_content(p15card, &key, object);
|
||||
LOG_TEST_RET(ctx, r, "Failed to encode public key");
|
||||
|
||||
/* Get the number of private keys already on this card */
|
||||
/*idx = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0);*/
|
||||
key_info = (struct sc_pkcs15_prkey_info *) object->data;
|
||||
r = _pkcd15init_set_aux_md_data(p15card, &key_info->aux_data, keyargs->guid, keyargs->guid_len);
|
||||
LOG_TEST_RET(ctx, r, "Failed to set aux MD data");
|
||||
|
||||
if (profile->ops->create_key)
|
||||
r = profile->ops->create_key(profile, p15card, object);
|
||||
|
|
|
@ -327,7 +327,7 @@ sc_profile_load(struct sc_profile *profile, const char *filename)
|
|||
scconf_context *conf;
|
||||
const char *profile_dir = NULL;
|
||||
char path[PATH_MAX];
|
||||
int res = 0, i;
|
||||
int res = 0, i;
|
||||
#ifdef _WIN32
|
||||
char temp_path[PATH_MAX];
|
||||
DWORD temp_len;
|
||||
|
@ -341,26 +341,15 @@ sc_profile_load(struct sc_profile *profile, const char *filename)
|
|||
if (profile_dir)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!profile_dir) {
|
||||
#ifdef _WIN32
|
||||
rc = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueEx(hKey, "ProfileDir", NULL, NULL, (LPBYTE) temp_path, &temp_len);
|
||||
if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
|
||||
profile_dir = temp_path;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
if (!profile_dir) {
|
||||
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\OpenSC Project\\OpenSC", 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (rc == ERROR_SUCCESS) {
|
||||
temp_len = PATH_MAX;
|
||||
rc = RegQueryValueEx(hKey, "ProfileDir", NULL, NULL, (LPBYTE) temp_path, &temp_len);
|
||||
if ((rc == ERROR_SUCCESS) && (temp_len < PATH_MAX))
|
||||
profile_dir = temp_path;
|
||||
RegCloseKey(hKey);
|
||||
}
|
||||
}
|
||||
temp_len = PATH_MAX;
|
||||
res = sc_ctx_win32_get_config_value(NULL, "ProfileDir", "Software\\OpenSC Project\\OpenSC",
|
||||
temp_path, &temp_len);
|
||||
if (res)
|
||||
LOG_FUNC_RETURN(ctx, res);
|
||||
profile_dir = temp_path;
|
||||
#else
|
||||
profile_dir = SC_PKCS15_PROFILE_DIRECTORY;
|
||||
#endif
|
||||
|
|
|
@ -66,10 +66,11 @@ static int dump_unusedspace(void)
|
|||
|
||||
if (p15card->file_unusedspace != NULL)
|
||||
path = p15card->file_unusedspace->path;
|
||||
else {
|
||||
else if (p15card->file_app != NULL) {
|
||||
path = p15card->file_app->path;
|
||||
sc_append_path_id(&path, (const u8 *) "\x50\x33", 2);
|
||||
}
|
||||
} else
|
||||
return -1;
|
||||
path.count = -1;
|
||||
|
||||
r = sc_pkcs15_read_file(p15card, &path, &buf, &buf_len);
|
||||
|
|
|
@ -84,7 +84,7 @@ int sc_test_init(int *argc, char *argv[])
|
|||
return rc;
|
||||
} else {
|
||||
for (i = rc = 0; rc != 1 && i < (int) sc_ctx_get_reader_count(ctx); i++)
|
||||
rc = sc_detect_card_presence(sc_ctx_get_reader(ctx, opt_reader));
|
||||
rc = sc_detect_card_presence(sc_ctx_get_reader(ctx, i));
|
||||
if (rc == 1)
|
||||
opt_reader = i - 1;
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@ static struct ec_curve_info {
|
|||
} ec_curve_infos[] = {
|
||||
{"secp192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
|
||||
{"prime192v1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
|
||||
{"prime192v2", "1.2.840.10045.3.1.2", "06082A8648CE3D030102", 192},
|
||||
{"prime192v3", "1.2.840.10045.3.1.3", "06082A8648CE3D030103", 192},
|
||||
{"nistp192", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
|
||||
{"ansiX9p192r1", "1.2.840.10045.3.1.1", "06082A8648CE3D030101", 192},
|
||||
|
||||
|
@ -83,6 +85,7 @@ static struct ec_curve_info {
|
|||
{"prime256v1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
|
||||
{"secp256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
|
||||
{"ansiX9p256r1", "1.2.840.10045.3.1.7", "06082A8648CE3D030107", 256},
|
||||
{"frp256v1", "1.2.250.1.223.101.256.1", "060a2a817a01815f65820001", 256},
|
||||
|
||||
{"secp384r1", "1.3.132.0.34", "06052B81040022", 384},
|
||||
{"prime384v1", "1.3.132.0.34", "06052B81040022", 384},
|
||||
|
@ -2659,7 +2662,11 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
|
|||
{CKA_ENCRYPT, &true, sizeof(true)},
|
||||
{CKA_DECRYPT, &true, sizeof(true)}
|
||||
};
|
||||
|
||||
#if defined(ENABLE_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x00908000L && !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_ECDSA)
|
||||
CK_ECDH1_DERIVE_PARAMS ecdh_parms;
|
||||
unsigned char buf[512];
|
||||
#endif /* ENABLE_OPENSSL etc */
|
||||
|
||||
if (!opt_mechanism_used)
|
||||
if (!find_mechanism(slot, CKF_DERIVE|CKF_HW, NULL, 0, &opt_mechanism))
|
||||
util_fatal("Derive mechanism not supported\n");
|
||||
|
@ -2674,8 +2681,6 @@ derive_key(CK_SLOT_ID slot, CK_SESSION_HANDLE session, CK_OBJECT_HANDLE key)
|
|||
case CKM_ECDH1_DERIVE:
|
||||
/* Use OpenSSL to read the other public key, and get the raw verion */
|
||||
{
|
||||
CK_ECDH1_DERIVE_PARAMS ecdh_parms;
|
||||
unsigned char buf[512];
|
||||
int len;
|
||||
BIO *bio_in = NULL;
|
||||
const EC_KEY *eckey = NULL;
|
||||
|
@ -5033,7 +5038,7 @@ static const char *p11_mechanism_to_name(CK_MECHANISM_TYPE mech)
|
|||
if (mi->mech == mech)
|
||||
return mi->name;
|
||||
}
|
||||
snprintf(temp, sizeof(temp), "mechtype-%lu", (unsigned long) mech);
|
||||
snprintf(temp, sizeof(temp), "mechtype-0x%lX", (unsigned long) mech);
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,9 +58,11 @@ enum {
|
|||
OPT_MD5,
|
||||
OPT_PKCS1,
|
||||
OPT_BIND_TO_AID,
|
||||
OPT_VERSION,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "version", 0, NULL, OPT_VERSION },
|
||||
{ "sign", 0, NULL, 's' },
|
||||
{ "decipher", 0, NULL, 'c' },
|
||||
{ "key", 1, NULL, 'k' },
|
||||
|
@ -84,6 +86,7 @@ static const struct option options[] = {
|
|||
};
|
||||
|
||||
static const char *option_help[] = {
|
||||
"Print OpenSC package version",
|
||||
"Performs digital signature operation",
|
||||
"Decipher operation",
|
||||
"Selects the private key ID to use",
|
||||
|
@ -354,8 +357,9 @@ int main(int argc, char * const argv[])
|
|||
int err = 0, r, c, long_optind = 0;
|
||||
int do_decipher = 0;
|
||||
int do_sign = 0;
|
||||
int do_print_version = 0;
|
||||
int action_count = 0;
|
||||
struct sc_pkcs15_object *key;
|
||||
struct sc_pkcs15_object *key;
|
||||
sc_context_param_t ctx_param;
|
||||
|
||||
while (1) {
|
||||
|
@ -365,6 +369,10 @@ int main(int argc, char * const argv[])
|
|||
if (c == '?')
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
switch (c) {
|
||||
case OPT_VERSION:
|
||||
do_print_version = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 's':
|
||||
do_sign++;
|
||||
action_count++;
|
||||
|
@ -430,6 +438,11 @@ int main(int argc, char * const argv[])
|
|||
if (action_count == 0)
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
|
||||
if (do_print_version) {
|
||||
printf("%s\n", OPENSC_SCM_REVISION);
|
||||
action_count--;
|
||||
}
|
||||
|
||||
if (!(opt_crypt_flags & SC_ALGORITHM_RSA_HASHES))
|
||||
opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_NONE;
|
||||
|
||||
|
@ -477,7 +490,7 @@ int main(int argc, char * const argv[])
|
|||
fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label);
|
||||
|
||||
if (do_decipher) {
|
||||
if ((err = get_key(SC_PKCS15_PRKEY_USAGE_DECRYPT, &key))
|
||||
if ((err = get_key(SC_PKCS15_PRKEY_USAGE_DECRYPT|SC_PKCS15_PRKEY_USAGE_UNWRAP, &key))
|
||||
|| (err = decipher(key)))
|
||||
goto end;
|
||||
action_count--;
|
||||
|
|
|
@ -139,6 +139,8 @@ enum {
|
|||
OPT_ERASE_APPLICATION,
|
||||
OPT_IGNORE_CA_CERTIFICATES,
|
||||
OPT_UPDATE_EXISTING,
|
||||
OPT_MD_CONTAINER_GUID,
|
||||
OPT_VERSION,
|
||||
|
||||
OPT_PIN1 = 0x10000, /* don't touch these values */
|
||||
OPT_PUK1 = 0x10001,
|
||||
|
@ -150,6 +152,7 @@ enum {
|
|||
};
|
||||
|
||||
const struct option options[] = {
|
||||
{ "version", 0, NULL, OPT_VERSION },
|
||||
{ "erase-card", no_argument, NULL, 'E' },
|
||||
{ "create-pkcs15", no_argument, NULL, 'C' },
|
||||
{ "store-pin", no_argument, NULL, 'P' },
|
||||
|
@ -201,6 +204,7 @@ const struct option options[] = {
|
|||
{ "profile", required_argument, NULL, 'p' },
|
||||
{ "card-profile", required_argument, NULL, 'c' },
|
||||
{ "options-file", required_argument, NULL, OPT_OPTIONS },
|
||||
{ "md-container-guid", required_argument, NULL, OPT_MD_CONTAINER_GUID},
|
||||
{ "wait", no_argument, NULL, 'w' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
|
@ -211,6 +215,7 @@ const struct option options[] = {
|
|||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
static const char * option_help[] = {
|
||||
"Print OpenSC package version",
|
||||
"Erase the smart card",
|
||||
"Creates a new PKCS #15 structure",
|
||||
"Store a new PIN/PUK on the card",
|
||||
|
@ -261,6 +266,7 @@ static const char * option_help[] = {
|
|||
"Specify the general profile to use",
|
||||
"Specify the card profile to use",
|
||||
"Read additional command line options from file",
|
||||
"For a new key specify GUID for a MD container",
|
||||
"Wait for card insertion",
|
||||
"Display this message",
|
||||
"Verbose operation. Use several times to enable debug output.",
|
||||
|
@ -287,6 +293,7 @@ enum {
|
|||
ACTION_SANITY_CHECK,
|
||||
ACTION_UPDATE_LAST_UPDATE,
|
||||
ACTION_ERASE_APPLICATION,
|
||||
ACTION_PRINT_VERSION,
|
||||
|
||||
ACTION_MAX
|
||||
};
|
||||
|
@ -360,6 +367,7 @@ static char * opt_application_id = NULL;
|
|||
static char * opt_application_name = NULL;
|
||||
static char * opt_bind_to_aid = NULL;
|
||||
static char * opt_puk_authid = NULL;
|
||||
static char * opt_md_container_guid = NULL;
|
||||
static unsigned int opt_x509_usage = 0;
|
||||
static unsigned int opt_delete_flags = 0;
|
||||
static unsigned int opt_type = 0;
|
||||
|
@ -525,6 +533,9 @@ main(int argc, char **argv)
|
|||
printf("About to %s.\n", action_names[action]);
|
||||
|
||||
switch (action) {
|
||||
case ACTION_PRINT_VERSION:
|
||||
printf("%s\n", OPENSC_SCM_REVISION);
|
||||
break;
|
||||
case ACTION_ASSERT_PRISTINE:
|
||||
/* skip printing error message */
|
||||
if ((r = do_assert_pristine(card)) < 0)
|
||||
|
@ -1500,7 +1511,7 @@ do_generate_key(struct sc_profile *profile, const char *spec)
|
|||
|
||||
if ((r = init_keyargs(&keygen_args.prkey_args)) < 0)
|
||||
return r;
|
||||
keygen_args.prkey_args.access_flags |=
|
||||
keygen_args.prkey_args.access_flags |=
|
||||
SC_PKCS15_PRKEY_ACCESS_SENSITIVE
|
||||
| SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
|
||||
| SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
|
||||
|
@ -1558,7 +1569,7 @@ static int init_keyargs(struct sc_pkcs15init_prkeyargs *args)
|
|||
sc_pkcs15_format_id(opt_authid, &args->auth_id);
|
||||
} else if (!opt_insecure) {
|
||||
util_error("no PIN given for key - either use --insecure or \n"
|
||||
"specify a PIN using --auth-id");
|
||||
"specify a PIN using --auth-id");
|
||||
return SC_ERROR_INVALID_ARGUMENTS;
|
||||
}
|
||||
if (opt_extractable) {
|
||||
|
@ -1566,6 +1577,12 @@ static int init_keyargs(struct sc_pkcs15init_prkeyargs *args)
|
|||
}
|
||||
args->label = opt_label;
|
||||
args->x509_usage = opt_x509_usage;
|
||||
|
||||
if (opt_md_container_guid) {
|
||||
args->guid = (unsigned char *)opt_md_container_guid;
|
||||
args->guid_len = strlen(opt_md_container_guid);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2552,6 +2569,12 @@ handle_option(const struct option *opt)
|
|||
case OPT_UPDATE_EXISTING:
|
||||
opt_update_existing = 1;
|
||||
break;
|
||||
case OPT_MD_CONTAINER_GUID:
|
||||
opt_md_container_guid = optarg;
|
||||
break;
|
||||
case OPT_VERSION:
|
||||
this_action = ACTION_PRINT_VERSION;
|
||||
break;
|
||||
default:
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ enum {
|
|||
OPT_LIST_SKEYS,
|
||||
OPT_NO_PROMPT,
|
||||
OPT_RAW,
|
||||
OPT_PRINT_VERSION
|
||||
};
|
||||
|
||||
#define NELEMENTS(x) (sizeof(x)/sizeof((x)[0]))
|
||||
|
@ -91,6 +92,7 @@ enum {
|
|||
static int authenticate(sc_pkcs15_object_t *obj);
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "version", 0, NULL, OPT_PRINT_VERSION },
|
||||
{ "learn-card", no_argument, NULL, 'L' },
|
||||
{ "list-applications", no_argument, NULL, OPT_LIST_APPLICATIONS },
|
||||
{ "read-certificate", required_argument, NULL, 'r' },
|
||||
|
@ -103,7 +105,7 @@ static const struct option options[] = {
|
|||
{ "dump", no_argument, NULL, 'D' },
|
||||
{ "unblock-pin", no_argument, NULL, 'u' },
|
||||
{ "change-pin", no_argument, NULL, OPT_CHANGE_PIN },
|
||||
{ "list-keys", no_argument, NULL, 'k' },
|
||||
{ "list-keys", no_argument, NULL, 'k' },
|
||||
{ "list-public-keys", no_argument, NULL, OPT_LIST_PUB },
|
||||
{ "read-public-key", required_argument, NULL, OPT_READ_PUB },
|
||||
#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
|
||||
|
@ -113,7 +115,7 @@ static const struct option options[] = {
|
|||
{ "test-update", no_argument, NULL, 'T' },
|
||||
{ "update", no_argument, NULL, 'U' },
|
||||
{ "reader", required_argument, NULL, OPT_READER },
|
||||
{ "pin", required_argument, NULL, OPT_PIN },
|
||||
{ "pin", required_argument, NULL, OPT_PIN },
|
||||
{ "new-pin", required_argument, NULL, OPT_NEWPIN },
|
||||
{ "puk", required_argument, NULL, OPT_PUK },
|
||||
{ "verify-pin", no_argument, NULL, OPT_VERIFY_PIN },
|
||||
|
@ -128,6 +130,7 @@ static const struct option options[] = {
|
|||
};
|
||||
|
||||
static const char *option_help[] = {
|
||||
"Print OpenSC package version",
|
||||
"Stores card info to cache",
|
||||
"List the on-card PKCS#15 applications",
|
||||
"Reads certificate with ID <arg>",
|
||||
|
@ -241,7 +244,7 @@ static void print_cert_info(const struct sc_pkcs15_object *obj)
|
|||
|
||||
print_access_rules(obj->access_rules, SC_PKCS15_MAX_ACCESS_RULES);
|
||||
|
||||
rv = sc_pkcs15_read_certificate(p15card, cert_info, &cert_parsed);
|
||||
rv = sc_pkcs15_read_certificate(p15card, cert_info, &cert_parsed);
|
||||
if (rv >= 0 && cert_parsed) {
|
||||
printf("\tEncoded serial : %02X %02X ", *(cert_parsed->serial), *(cert_parsed->serial + 1));
|
||||
util_hex_dump(stdout, cert_parsed->serial + 2, cert_parsed->serial_len - 2, "");
|
||||
|
@ -557,7 +560,7 @@ static void print_prkey_info(const struct sc_pkcs15_object *obj)
|
|||
printf("\tID : %s\n", sc_pkcs15_print_id(&prkey->id));
|
||||
|
||||
guid_len = sizeof(guid);
|
||||
if (!sc_pkcs15_get_object_guid(p15card, obj, 0, guid, &guid_len)) {
|
||||
if (!sc_pkcs15_get_object_guid(p15card, obj, 1, guid, &guid_len)) {
|
||||
printf("\tMD:guid : ");
|
||||
if (strlen((char *)guid) == guid_len) {
|
||||
printf("%s\n", (char *)guid);
|
||||
|
@ -606,7 +609,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj)
|
|||
"neverExtract", "local"
|
||||
};
|
||||
const unsigned int af_count = NELEMENTS(access_flags);
|
||||
int have_path = (pubkey->path.len != 0) || (pubkey->path.aid.len != 0);
|
||||
int have_path = (pubkey->path.len != 0) || (pubkey->path.aid.len != 0);
|
||||
|
||||
printf("Public %s Key [%.*s]\n", types[7 & obj->type], (int) sizeof obj->label, obj->label);
|
||||
print_common_flags(obj);
|
||||
|
@ -627,11 +630,11 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj)
|
|||
|
||||
if (pubkey->modulus_length) {
|
||||
printf("\tModLength : %lu\n", (unsigned long)pubkey->modulus_length);
|
||||
}
|
||||
}
|
||||
else if (pubkey->field_length) {
|
||||
printf("\tFieldLength : %lu\n", (unsigned long)pubkey->field_length);
|
||||
}
|
||||
else if (obj->type == SC_PKCS15_TYPE_PUBKEY_EC && have_path) {
|
||||
}
|
||||
else if (obj->type == SC_PKCS15_TYPE_PUBKEY_EC && have_path) {
|
||||
sc_pkcs15_pubkey_t *pkey = NULL;
|
||||
if (!sc_pkcs15_read_pubkey(p15card, obj, &pkey)) {
|
||||
printf("\tFieldLength : %lu\n", (unsigned long)pkey->u.ec.params.field_length);
|
||||
|
@ -646,7 +649,7 @@ static void print_pubkey_info(const struct sc_pkcs15_object *obj)
|
|||
if (obj->auth_id.len != 0)
|
||||
printf("\tAuth ID : %s\n", sc_pkcs15_print_id(&obj->auth_id));
|
||||
printf("\tID : %s\n", sc_pkcs15_print_id(&pubkey->id));
|
||||
if (!have_path || obj->content.len)
|
||||
if (!have_path || obj->content.len)
|
||||
printf("\tDirectValue : <%s>\n", obj->content.len ? "present" : "absent");
|
||||
}
|
||||
|
||||
|
@ -775,7 +778,7 @@ static void print_skey_info(const struct sc_pkcs15_object *obj)
|
|||
printf("\tPath : %s\n", sc_print_path(&skey->path));
|
||||
|
||||
guid_len = sizeof(guid);
|
||||
if (!sc_pkcs15_get_object_guid(p15card, obj, 0, guid, &guid_len)) {
|
||||
if (!sc_pkcs15_get_object_guid(p15card, obj, 1, guid, &guid_len)) {
|
||||
printf("\tGUID : %s\n", (char *)guid);
|
||||
}
|
||||
|
||||
|
@ -905,7 +908,7 @@ static int read_ssh_key(void)
|
|||
if (!pubkey->u.rsa.modulus.data || !pubkey->u.rsa.modulus.len ||
|
||||
!pubkey->u.rsa.exponent.data || !pubkey->u.rsa.exponent.len) {
|
||||
fprintf(stderr, "Failed to decode public RSA key.\n");
|
||||
goto fail2;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
buf[0]=0;
|
||||
|
@ -963,7 +966,7 @@ static int read_ssh_key(void)
|
|||
!pubkey->u.dsa.g.data || !pubkey->u.dsa.g.len ||
|
||||
!pubkey->u.dsa.pub.data || !pubkey->u.dsa.pub.len) {
|
||||
fprintf(stderr, "Failed to decode DSA key.\n");
|
||||
goto fail2;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
buf[0]=0;
|
||||
|
@ -1139,13 +1142,13 @@ static int verify_pin(void)
|
|||
int r;
|
||||
|
||||
if (!opt_auth_id) {
|
||||
struct sc_pkcs15_object *objs[32];
|
||||
struct sc_pkcs15_object *objs[32];
|
||||
int ii;
|
||||
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, objs, 32);
|
||||
if (r < 0) {
|
||||
fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
|
||||
return -1;
|
||||
fprintf(stderr, "PIN code enumeration failed: %s\n", sc_strerror(r));
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (ii=0;ii<r;ii++) {
|
||||
|
@ -1610,7 +1613,8 @@ static int read_and_cache_file(const sc_path_t *path)
|
|||
}
|
||||
r = head - buf;
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
|
||||
r = sc_read_binary(card, 0, buf, size, 0);
|
||||
if (r < 0) {
|
||||
|
@ -1692,18 +1696,18 @@ static int test_update(sc_card_t *in_card)
|
|||
sc_apdu_t apdu;
|
||||
static u8 cmd1[2] = { 0x50, 0x15};
|
||||
u8 rbuf[258];
|
||||
int rc;
|
||||
int rc;
|
||||
int r;
|
||||
static u8 fci_bad[] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static u8 fci_good[] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00 };
|
||||
|
||||
|
||||
|
||||
if (strcmp("cardos",in_card->driver->short_name) != 0) {
|
||||
printf("not using the cardos driver, card is fine.\n");
|
||||
if (strcmp("cardos",in_card->driver->short_name) != 0) {
|
||||
printf("not using the cardos driver, card is fine.\n");
|
||||
rc = 0;
|
||||
goto end;
|
||||
}
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* first select file on 5015 and get fci */
|
||||
sc_format_apdu(in_card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x08, 0x00);
|
||||
|
@ -1747,7 +1751,7 @@ static int test_update(sc_card_t *in_card)
|
|||
|
||||
{
|
||||
size_t i=0;
|
||||
while(i < rbuf[1]) {
|
||||
while(i < rbuf[1]) {
|
||||
if (rbuf[2+i] == 0x86) { /* found our buffer */
|
||||
break;
|
||||
}
|
||||
|
@ -1776,7 +1780,7 @@ static int test_update(sc_card_t *in_card)
|
|||
}
|
||||
end:
|
||||
/* 0 = card ok, 1 = card vulnerable, 2 = problem! */
|
||||
return rc;
|
||||
return rc;
|
||||
|
||||
bad_fci:
|
||||
util_hex_dump(stdout,rbuf,apdu.resplen," ");
|
||||
|
@ -1836,7 +1840,7 @@ static int update(sc_card_t *in_card)
|
|||
if (apdu.resplen < 1) {
|
||||
printf("get lifecycle failed: lifecycle byte not in response\n");
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (rbuf[0] != 0x10 && rbuf[0] != 0x20) {
|
||||
printf("lifecycle neither user nor admin, can't proceed\n");
|
||||
|
@ -1890,7 +1894,7 @@ skip_change_lifecycle:
|
|||
|
||||
printf("security update applied successfully.\n");
|
||||
end:
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char * const argv[])
|
||||
|
@ -1916,6 +1920,7 @@ int main(int argc, char * const argv[])
|
|||
int do_learn_card = 0;
|
||||
int do_test_update = 0;
|
||||
int do_update = 0;
|
||||
int do_print_version = 0;
|
||||
int action_count = 0;
|
||||
sc_context_param_t ctx_param;
|
||||
|
||||
|
@ -1930,6 +1935,10 @@ int main(int argc, char * const argv[])
|
|||
if (c == '?')
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
switch (c) {
|
||||
case OPT_PRINT_VERSION:
|
||||
do_print_version = 1;
|
||||
action_count++;
|
||||
break;
|
||||
case 'r':
|
||||
opt_cert = optarg;
|
||||
do_read_cert = 1;
|
||||
|
@ -2052,6 +2061,11 @@ int main(int argc, char * const argv[])
|
|||
if (action_count == 0)
|
||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||
|
||||
if (do_print_version) {
|
||||
printf("%s\n", OPENSC_SCM_REVISION);
|
||||
action_count--;
|
||||
}
|
||||
|
||||
memset(&ctx_param, 0, sizeof(ctx_param));
|
||||
ctx_param.ver = 0;
|
||||
ctx_param.app_name = app_name;
|
||||
|
@ -2074,7 +2088,7 @@ int main(int argc, char * const argv[])
|
|||
if (verbose)
|
||||
fprintf(stderr, "Trying to find a PKCS#15 compatible card...\n");
|
||||
|
||||
if (opt_bind_to_aid) {
|
||||
if (opt_bind_to_aid) {
|
||||
struct sc_aid aid;
|
||||
|
||||
aid.len = sizeof(aid.value);
|
||||
|
@ -2181,7 +2195,7 @@ int main(int argc, char * const argv[])
|
|||
action_count--;
|
||||
}
|
||||
if (do_test_update || do_update) {
|
||||
err = test_update(card);
|
||||
err = test_update(card);
|
||||
action_count--;
|
||||
if (err == 2) { /* problem */
|
||||
err = 1;
|
||||
|
|
|
@ -111,6 +111,7 @@
|
|||
<RegistryValue Type="string" Name="ConfigFile" Value="[INSTALLDIR]opensc.conf"/>
|
||||
<RegistryValue Type="string" Name="ProfileDir" Value="[INSTALLDIR]profiles"/>
|
||||
<RegistryValue Type="string" Name="SmDir" Value="[INSTALLDIR]tools"/>
|
||||
<RegistryValue Type="integer" Name="MiniDriverDebug" Value="0"/>
|
||||
</RegistryKey>
|
||||
</Component>
|
||||
|
||||
|
|
Loading…
Reference in New Issue