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:
Viktor Tarasov 2016-06-03 11:16:59 +02:00
commit 7eeba1fba8
74 changed files with 2869 additions and 1642 deletions

2
.gitignore vendored
View File

@ -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

View File

@ -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 \

View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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

117
doc/tools/gids-tool.1.xml Normal file
View File

@ -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>

View File

@ -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>,

View File

@ -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>

View File

@ -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>,

View File

@ -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>

View File

@ -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.

View File

@ -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);

View File

@ -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 */

View File

@ -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

View File

@ -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)

View File

@ -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 */

204
src/libopensc/aux-data.c Normal file
View File

@ -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;
}

85
src/libopensc/aux-data.h Normal file
View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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)

View File

@ -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

View 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

View File

@ -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);

View File

@ -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},

View File

@ -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)
{

View File

@ -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;

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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);
}

View File

@ -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)
{

View File

@ -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

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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);

View File

@ -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;

View File

@ -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)) {

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)
{

View File

@ -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,

View File

@ -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;
}

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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;

View File

@ -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,

View File

@ -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");

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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--;

View File

@ -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);
}

View File

@ -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;

View File

@ -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>