diff --git a/.gitignore b/.gitignore
index b2e9761..bfd3723 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
esc-1.1.0.tar.bz2
/esc-1.1.1.tar.bz2
+/esc-1.1.2.tar.bz2
diff --git a/esc b/esc
index cce19fc..293b861 100755
--- a/esc
+++ b/esc
@@ -18,155 +18,17 @@
# END COPYRIGHT BLOCK
-DO_FORCEMODE="false"
-DO_SHOW_VERSION="false"
-ESC_ARGS=
-
-
-ESC_PROFILE_BASE=~/.redhat/esc
-ESC_LOG_FILE=esc.log
-
-ESC_PATH=$LIBDIR/esc-1.1.1
-ESC_BIN_PATH=/usr/bin
-ESC_EXEC=esc
-ESCD_EXEC=escd
-
-ESC_BIN=$ESC_PATH/xulrunner/xulrunner-bin
-ESCD_BIN=./$ESCD_EXEC
-
-LAST_PROG_PID=0
-SIGUSR1=10
-
-FORCE_START_ESC=
-
-XPTI_DAT=xpti.dat
-COMPREG_DAT=compreg.dat
-LOCK_FILE=lock
-PARENT_LOCK_FILE=.parentlock
+ESC_PATH=/usr/lib64/esc-1.1.2
+ESC_BIN=esc.js
+ESC_EXEC=gjs
export OPENSC_CONF=$ESC_PATH/opensc.esc.conf
-
-function isProgRunning {
-
- userID=$(whoami)
- isProgRunning=$(pgrep -U $userID -f $1)
- if [ $isProgRunning ];
- then
- LAST_PROG_PID=$isProgRunning
- return 0
- fi
- LAST_PROG_PID=0
- return 1
-}
-
-function removeFile {
-
- rm -f $1
-}
-
-function cleanupProfile {
-
- removeFile $ESC_PROFILE_BASE/*default/$XPTI_DAT
- removeFile $ESC_PROFILE_BASE/*default/$COMPREG_DAT
- removeFile $ESC_PROFILE_BASE/*default/$LOCK_FILE
- removeFile $ESC_PROFILE_BASE/*default/$PARENT_LOCK_FILE
-
-}
-
-function processArgs {
-
- for arg in $1
- do
-
- #echo "theArg: $arg"
- if [ $arg == "forceStartESC" ]
- then
- #echo "Do force mode!"
- FORCE_START_ESC="true"
- fi
-
- if [ $arg == "keyInserted" ]
- then
- FORCE_START_ESC="true"
- fi
-
- if [ $arg == "-version" ]
- then
- #echo "Do show version!"
- DO_SHOW_VERSION="true"
- fi
- done
-}
-
-
-processArgs $*
-
-if [ ! -d $ESC_PROFILE_BASE ]
-then
- mkdir -p $ESC_PROFILE_BASE
-fi
+export GI_TYPELIB_PATH=$ESC_PATH/lib/girepository-1.0
+export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ESC_PATH/lib
cd $ESC_PATH
-#First check if we just want the version
-
-if [ $DO_SHOW_VERSION == "true" ]
- then
- #echo "try to run the version command!"
- ESC_ARGS="-version"
- ./$ESC_EXEC $ESC_ARGS
- exit 0
-fi
-
-# Start up the daemon if it is not running
-
-isProgRunning $ESCD_BIN
-
-if [ $LAST_PROG_PID -gt 0 ]
-then
- false
- #echo "escd already running."
-else
- #echo "escd not running start."
- cleanupProfile
- ./$ESCD_EXEC --key_Inserted=\"/usr/bin/esc\" --on_Signal=\"/usr/bin/esc\"
- exit 0
-fi
-
-# Now check to see if we wer signaled from the daemon
-
-if [ $FORCE_START_ESC ]
-then
- #echo "force start esc."
-
- #Check to see if esc is already running
-
- isProgRunning $ESC_BIN
- if [ $LAST_PROG_PID -gt 0 ]
- then
- #echo "attempting a force start but already running ... exit."
- exit 0
- fi
- #echo "force start esc not running start esc..."
- ./$ESC_EXEC
- exit 0
-fi
-
-isProgRunning $ESC_BIN
-
-if [ $LAST_PROG_PID -gt 0 ]
-then
- #echo "esc already running."
- ./$ESC_EXEC
- exit 0
-else
- #echo "esc not already running start up and bring up window."
- ./$ESC_EXEC &
- sleep 4
- #echo "done sleeping bring up esc window."
- ./$ESC_EXEC
- exit 0
-fi
+$ESC_EXEC ./$ESC_BIN &
exit 0
diff --git a/esc-1.1.1-fix1.patch b/esc-1.1.1-fix1.patch
deleted file mode 100644
index 02a330d..0000000
--- a/esc-1.1.1-fix1.patch
+++ /dev/null
@@ -1,8237 +0,0 @@
-diff -up ./esc/opensc.esc.conf.fix1 ./esc/opensc.esc.conf
---- ./esc/opensc.esc.conf.fix1 2018-04-26 11:44:38.429986239 -0700
-+++ ./esc/opensc.esc.conf 2018-04-26 11:44:38.429986239 -0700
-@@ -0,0 +1,48 @@
-+app default {
-+ enable_default_driver = true;
-+
-+ card_atr
-+ 3B:FF:14:00:FF:81:31:FE:45:80:25:A0:00:00:00:56:57:53:43:36:35:30:03:03:38 {
-+ pkcs11_enable_InitToken = yes;
-+ }
-+
-+ card_atr
-+ 3B:FF:14:00:FF:81:31:FE:45:80:25:A0:00:00:00:56:57:53:43:36:35:30:01:00:39 {
-+ pkcs11_enable_InitToken = yes;
-+ }
-+
-+ card_atr
-+ 3B:FF:14:00:FF:81:31:FE:45:80:25:A0:00:00:00:56:57:53:43:36:35:30:03:00:3B {
-+ pkcs11_enable_InitToken = yes;
-+ }
-+ reader_driver ctapi {
-+ }
-+ reader_driver pcsc {
-+ }
-+ reader_driver openct {
-+ };
-+ card_drivers = coolkey, cac, piv, default;
-+ secure_messaging local_authentic {
-+ module_path = /usr/lib64;
-+ }
-+ framework pkcs15 {
-+ builtin_emulators = coolkey, cac, piv;
-+ }
-+}
-+app opensc-pkcs11 {
-+ pkcs11 {
-+ }
-+}
-+app onepin-opensc-pkcs11 {
-+ pkcs11 {
-+ slots_per_card = 1;
-+ }
-+}
-+app tokend {
-+ framework tokend {
-+ }
-+}
-+app cardmod {
-+ reader_driver cardmod {
-+ }
-+}
-diff -up ./esc/src/app/daemon/manifest.mn.fix1 ./esc/src/app/daemon/manifest.mn
---- ./esc/src/app/daemon/manifest.mn.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/daemon/manifest.mn 2018-04-26 14:55:48.926180480 -0700
-@@ -30,13 +30,13 @@ endif
-
-
-
--DEFINES += -I$(SYS_INC)/nspr4 -I$(SYS_INC)/nss3 -I$(SYS_INC)/$(MOZ_OFFSET)/nspr -I$(SYS_INC)/$(MOZ_OFFSET)/nss
-+DEFINES += -I$(SYS_INC)/nspr4 -I$(SYS_INC)/nss3 -I$(SYS_INC)/$(MOZ_OFFSET)/nspr -I$(SYS_INC)/$(MOZ_OFFSET)/nss -I$(SYS_INC)/PCSC -I$(CORE_DEPTH)/src/lib/coolkey
-
- DEFINES += $(shell pkg-config --cflags xft)
-
- CPPFLAGS += $(DEFINES) -g
-
--LDFLAGS += -lstdc++ -L$(CORE_DIST)/$(OBJDIR)/lib -L$(XULRUNNER_LIBS_LDFLAGS) -lnss3 -lnspr4 -lssl3 -lckyapplet $(shell pkg-config --libs xft)
-+LDFLAGS += -lstdc++ -L$(CORE_DIST)/$(OBJDIR)/lib -L$(XULRUNNER_LIBS_LDFLAGS) -lnss3 -lnspr4 -lssl3 $(shell pkg-config --libs xft)
- LDFLAGS += -lckymanager -lhttpchunked -lm -lnss3 -lplc4 -lplds4 -lX11
- # MODULE public and private header directories are implicitly REQUIRED.
-
-diff -up ./esc/src/app/xpcom/Makefile.sdk.fix1 ./esc/src/app/xpcom/Makefile.sdk
---- ./esc/src/app/xpcom/Makefile.sdk.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xpcom/Makefile.sdk 2018-04-26 11:44:38.430986233 -0700
-@@ -144,8 +144,8 @@ NSPR_INCLUDE = /usr/include/nspr4
- GECKO_INCLUDES = -I $(GECKO_SDK_PATH)/include -I $(GECKO_INCLUDE_PATH) -I $(NSPR_INCLUDE) -I $(NSS_INCLUDE) -I $(GECKO_INCLUDE_PATH)/xpcom
-
-
--COOL_INCLUDES = -I $(CORE_INC)/ckymanager -I $(CORE_INC)/httpchuncked
--COOL_LDFLAGS = -L$(CORE_DIST)/lib -lckymanager -lhttpchunked $(CKY_LIB_LDD) -lckyapplet
-+COOL_INCLUDES = -I $(CORE_INC)/ckymanager -I $(CORE_INC)/httpchuncked -I /usr/include/PCSC -I $(CORE_DEPTH)/src/lib/coolkey
-+COOL_LDFLAGS = -L$(CORE_DIST)/lib -lckymanager -lhttpchunked
-
- OBJECT = rhCoolKey.o
-
-@@ -258,6 +258,7 @@ $(DEPLOY_OBJDIR):
-
- cd $(CORE_DEPTH)/$(DEPLOY_OFFSET)/app/xul/esc; zip -r test.zip * -x *\CVS\* \*.fix*; unzip -d esc test.zip ; rm -f test.zip
- $(PYTHON_BIN) $(GECKO_SDK_PATH)/bin/install_app.py $(CORE_DEPTH)$(DEPLOY_OFFSET)/app/xul/esc/esc $(DEPLOY_OBJDIR)/esc --appName esc
-+ $(NSINSTALL) $(CORE_DEPTH)/opensc.esc.conf $(DEPLOY_OBJDIR)/esc
-
- ifeq ($(OS_ARCH), Darwin)
- mkdir $(DEPLOY_OBJDIR)/$(XULRUNNER_FRAME_BASE)
-diff -up ./esc/src/app/xul/esc/application.ini.fix1 ./esc/src/app/xul/esc/application.ini
---- ./esc/src/app/xul/esc/application.ini.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/application.ini 2018-04-26 11:44:38.431986227 -0700
-@@ -25,7 +25,7 @@ Vendor=RedHat
- Name=ESC
- ;
- ; This field specifies your application's version. This field is optional.
--Version=1.1.0-24
-+Version=1.1.1-1
- ;
- ; This field specifies your application's build ID (timestamp). This field is
- ; required.
-@@ -47,6 +47,6 @@ MinVersion=6.0.0
- ; application requires. It should be specified if your application uses
- ; unfrozen interfaces. Specifying 1.8 matches all releases with a version
- ; prefixed by 1.8 (e.g., 1.8a4, 1.8b, 1.8.2).
--MaxVersion=50.0.0
-+MaxVersion=60.0.0
-
- [Shell]
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/advancedinfo.xul.fix1 ./esc/src/app/xul/esc/chrome/content/esc/advancedinfo.xul
---- ./esc/src/app/xul/esc/chrome/content/esc/advancedinfo.xul.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/advancedinfo.xul 2018-04-26 11:44:38.431986227 -0700
-@@ -33,7 +33,6 @@
-
-
-
--
-
-
-
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/config.xul.fix1 ./esc/src/app/xul/esc/chrome/content/esc/config.xul
---- ./esc/src/app/xul/esc/chrome/content/esc/config.xul.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/config.xul 2018-04-26 11:44:38.432986221 -0700
-@@ -30,7 +30,6 @@
- onunload="cleanup();"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
--
-
-
-
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/ESC.js.fix1 ./esc/src/app/xul/esc/chrome/content/esc/ESC.js
---- ./esc/src/app/xul/esc/chrome/content/esc/ESC.js.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/ESC.js 2018-04-26 11:44:38.433986216 -0700
-@@ -151,7 +151,6 @@ jsNotify.prototype = {
- //
- function cleanup()
- {
-- TrayRemoveWindow(null);
- try {
- netkey.rhCoolKeyUnSetNotifyCallback(gNotify);
- } catch(e) {
-@@ -1881,11 +1880,6 @@ function hiddenWindowStartup()
-
- // We do want notify events though
- var doPreserveNotify = true;
--
--
-- SetMenuItemsText();
-- HideWindow();
-- TrayRemoveWindow(doPreserveNotify);
- }
-
- function IdentifyWindow()
-@@ -2950,7 +2944,6 @@ function DoFormatCoolKey(type)
- var screennamepwd = null;
- var tokencode = null;
-
--
- if (!FormatCoolKey(keyType, keyID, lType, screenname, pin,screennamepwd,tokencode))
- {
- failed = 1;
-@@ -2997,10 +2990,6 @@ function OnCoolKeyInserted(keyType, keyI
- var allowNotify = DoCoolKeyGetConfigValue(ESC_ALLOW_NOTIFICATIONS);
-
- recordMessage("Key inserted!" + "Window " + IdentifyWindow());
-- if(gHiddenPage)
-- {
-- TrayShowNotificationIcon();
-- }
-
- if (!GetCoolKeyIsEnrolled(keyType, keyID) )
- {
-@@ -3024,7 +3013,6 @@ function OnCoolKeyInserted(keyType, keyI
- SelectRowByKeyID(keyType, keyID);
-
- }
--
- if(gHiddenPage)
- {
- var phoneHomeSuccess = 1;
-@@ -3269,12 +3257,11 @@ function Validate()
-
- function OnCoolKeyStateChange(keyType, keyID, keyState, data,strData)
- {
-- // alert("KeyID: " + keyID + "\n" +
-- // "KeyState: " + keyState + "\n" +
-- // "Data: " + data);
-+ //alert("KeyID: " + keyID + "\n" +
-+ // "KeyState: " + keyState + "\n" +
-+ // "Data: " + data);
- //alert("State Change ="+keyState);
-
--
- switch(keyState)
- {
- case 1000: // KeyInserted
-@@ -4804,3 +4791,8 @@ function GetESCLogPathName(aName)
-
-
- }
-+
-+function TraySendNotificationMessage(aTitle,aMessage,aSeverity,aTimeout,aIcon)
-+{
-+ //alert(aMessage);
-+}
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/esc.xul.fix1 ./esc/src/app/xul/esc/chrome/content/esc/esc.xul
---- ./esc/src/app/xul/esc/chrome/content/esc/esc.xul.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/esc.xul 2018-04-26 11:44:38.433986216 -0700
-@@ -30,7 +30,6 @@
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-
--
-
-
-
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/hiddenWindow.xul.fix1 ./esc/src/app/xul/esc/chrome/content/esc/hiddenWindow.xul
---- ./esc/src/app/xul/esc/chrome/content/esc/hiddenWindow.xul.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/hiddenWindow.xul 2018-04-26 11:44:38.434986210 -0700
-@@ -21,6 +21,5 @@
- onload="hiddenWindowStartup();"
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
--
-
-
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/security.xul.fix1 ./esc/src/app/xul/esc/chrome/content/esc/security.xul
---- ./esc/src/app/xul/esc/chrome/content/esc/security.xul.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/security.xul 2018-04-26 11:44:38.434986210 -0700
-@@ -31,7 +31,6 @@
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-
--
-
-
-
-diff -up ./esc/src/app/xul/esc/chrome/content/esc/settings.xul.fix1 ./esc/src/app/xul/esc/chrome/content/esc/settings.xul
---- ./esc/src/app/xul/esc/chrome/content/esc/settings.xul.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/app/xul/esc/chrome/content/esc/settings.xul 2018-04-26 11:44:38.435986204 -0700
-@@ -32,7 +32,6 @@
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
-
-
--
-
-
-
-diff -up ./esc/src/lib/coolkey/cky_applet.c.fix1 ./esc/src/lib/coolkey/cky_applet.c
---- ./esc/src/lib/coolkey/cky_applet.c.fix1 2018-04-26 11:44:38.436986198 -0700
-+++ ./esc/src/lib/coolkey/cky_applet.c 2018-04-26 11:44:38.436986198 -0700
-@@ -0,0 +1,2119 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#include
-+#include "cky_applet.h"
-+#include
-+
-+#define MIN(x, y) ((x) < (y) ? (x) : (y))
-+
-+/*****************************************************************
-+ *
-+ * Generic factorys are used by the generic APDU processing
-+ * to customize the formatting of APDU. Typically APDUs are formatted
-+ * using parameterized calls of the form CKYAPDUFactory_ADPUNAME.
-+ * The generic processing code, however needs calls with a common
-+ * Signature. To accomplish the conversion, we build generic versions
-+ * which take a void * parameter. Trivial APDU's can pass NULL or a pointer
-+ * to the single parameter that they need. More complicated APDU's use
-+ * CKYAppletArg* data structures defined above to pass more arguments.
-+ *
-+ * Generic factorys then call the standard CKYAPDUFactor_ADPUNAME() functions
-+ * to build the APDUs. These functions are intended only as arguments
-+ * to the generic ADPU calls, and not to be called directly.
-+ *
-+ *****************************************************************/
-+CKYStatus
-+CKYAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 4, 0, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 2, 12, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
-+P15AppletFactory_SelectFile(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectFile(apdu, 0, 0, (const CKYBuffer *)param);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_SelectCardManager(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_SelectCardManager(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetCPLCData(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetCPLCData(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ListKeys(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_ListKeys(apdu, *( CKYByte *)param);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeCryptInit(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeCrypt *ccs=(const CKYAppletArgComputeCrypt *)param;
-+ return CKYAPDUFactory_ComputeCryptInit(apdu, ccs->keyNumber, ccs->mode,
-+ ccs->direction, ccs->location);
-+
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeCryptProcess(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeCrypt *ccs=(const CKYAppletArgComputeCrypt *)param;
-+ return CKYAPDUFactory_ComputeCryptProcess(apdu, ccs->keyNumber,
-+ ccs->location, ccs->data);
-+
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeCryptFinal(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeCrypt *ccs=(const CKYAppletArgComputeCrypt *)param;
-+ return CKYAPDUFactory_ComputeCryptFinal(apdu, ccs->keyNumber,
-+ ccs->location, ccs->data, ccs->sig);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeCryptOneStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeCrypt *ccs=(const CKYAppletArgComputeCrypt *)param;
-+ return CKYAPDUFactory_ComputeCryptOneStep(apdu, ccs->keyNumber,ccs->mode,
-+ ccs->direction, ccs->location, ccs->data, ccs->sig);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgComputeECCSignature *ccs=(const CKYAppletArgComputeECCSignature *)param;
-+ return CKYAPDUFactory_ComputeECCSignatureOneStep(apdu, ccs->keyNumber,
-+ ccs->location, ccs->data, ccs->sig);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, const void *param)
-+{
-+
-+ const CKYAppletArgComputeECCKeyAgreement *ccs=(const CKYAppletArgComputeECCKeyAgreement *)param;
-+ return CKYAPDUFactory_ComputeECCKeyAgreementOneStep(apdu, ccs->keyNumber, ccs->location, ccs->publicValue, ccs->secretKey);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_CreatePIN(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgCreatePIN *cps = (const CKYAppletArgCreatePIN *)param;
-+ return CKYAPDUFactory_CreatePIN(apdu, cps->pinNumber, cps->maxAttempts,
-+ cps->pinValue);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgVerifyPIN *vps = (const CKYAppletArgVerifyPIN *)param;
-+ return CKYAPDUFactory_VerifyPIN(apdu, vps->pinNumber, vps->pinValue);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ChangePIN(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgChangePIN *cps = (const CKYAppletArgChangePIN *)param;
-+ return CKYAPDUFactory_ChangePIN(apdu, cps->pinNumber, cps->oldPin,
-+ cps->newPin);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ListPINs(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_ListPINs(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_Logout(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_Logout(apdu, *(const CKYByte *)param);
-+}
-+
-+/* Future add WriteObject */
-+
-+CKYStatus
-+CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgWriteObject *wos = (const CKYAppletArgWriteObject *)param;
-+ return CKYAPDUFactory_WriteObject(apdu,wos->objectID,wos->offset,wos->size,wos->data);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgCreateObject *cos=(const CKYAppletArgCreateObject *)param;
-+ return CKYAPDUFactory_CreateObject(apdu, cos->objectID, cos->size,
-+ cos->readACL, cos->writeACL, cos->deleteACL);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_DeleteObject(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgDeleteObject *dos=(const CKYAppletArgDeleteObject *)param;
-+ return CKYAPDUFactory_DeleteObject(apdu, dos->objectID, dos->zero);
-+
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ReadObject(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYAppletArgReadObject *ros = (const CKYAppletArgReadObject *)param;
-+ return CKYAPDUFactory_ReadObject(apdu, ros->objectID,
-+ ros->offset, ros->size);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_ListObjects(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_ListObjects(apdu, *(const CKYByte *)param);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetStatus(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetStatus(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_Noop(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_Noop(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetBuildID(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetBuildID(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetLifeCycle(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetLifeCycle(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetLifeCycleV2(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetLifeCycleV2(apdu);
-+}
-+CKYStatus
-+CKYAppletFactory_GetRandom(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetRandom(apdu, *(CKYByte *)param);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_SeedRandom(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYBuffer *buf=(CKYBuffer *)param;
-+ return CKYAPDUFactory_SeedRandom(apdu, buf);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetIssuerInfo(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetIssuerInfo(apdu);
-+}
-+
-+CKYStatus
-+CKYAppletFactory_GetBuiltinACL(CKYAPDU *apdu, const void *param)
-+{
-+ return CKYAPDUFactory_GetBuiltinACL(apdu);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SignDecryptStep(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYBuffer *buf=(CKYBuffer *)param;
-+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_STEP, buf);
-+}
-+
-+CKYStatus
-+CACAppletFactory_SignDecryptFinal(CKYAPDU *apdu, const void *param)
-+{
-+ const CKYBuffer *buf=(CKYBuffer *)param;
-+ return CACAPDUFactory_SignDecrypt(apdu, CAC_P1_FINAL, buf);
-+}
-+
-+CKYStatus
-+PIVAppletFactory_SignDecrypt(CKYAPDU *apdu, const void *param)
-+{
-+ const PIVAppletArgSignDecrypt *psd = (const PIVAppletArgSignDecrypt *)param;
-+ return PIVAPDUFactory_SignDecrypt(apdu, psd->chain, psd->alg, psd->key,
-+ psd->len, psd->buf);
-+}
-+
-+CKYStatus
-+P15AppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgVerifyPIN *vps = (const P15AppletArgVerifyPIN *)param;
-+ return P15APDUFactory_VerifyPIN(apdu, vps->pinRef, vps->pinVal);
-+}
-+
-+CKYStatus
-+CACAppletFactory_GetCertificate(CKYAPDU *apdu, const void *param)
-+{
-+ CKYSize *size=(CKYSize*)param;
-+ return CACAPDUFactory_GetCertificate(apdu, *size);
-+}
-+
-+CKYStatus
-+PIVAppletFactory_GetCertificate(CKYAPDU *apdu, const void *param)
-+{
-+ CKYBuffer *tag =(CKYBuffer*)param;
-+ return PIVAPDUFactory_GetData(apdu, tag, 0);
-+}
-+
-+CKYStatus
-+CACAppletFactory_ReadFile(CKYAPDU *apdu, const void *param)
-+{
-+ const CACAppletArgReadFile *rfs = (const CACAppletArgReadFile *)param;
-+ return CACAPDUFactory_ReadFile(apdu, rfs->offset, rfs->type, rfs->count);
-+}
-+
-+CKYStatus
-+CACAppletFactory_GetProperties(CKYAPDU *apdu, const void *param)
-+{
-+ return CACAPDUFactory_GetProperties(apdu);
-+}
-+
-+/*
-+ * deprecates 0.x functions
-+ */
-+CKYStatus
-+CKYAppletFactory_LogoutAllV0(CKYAPDU *apdu, const void *param)
-+{
-+ CKYByte data[2] = { 0, 0};
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_LOGOUT_ALL);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetSendData(apdu, data, sizeof(data));
-+}
-+
-+CKYStatus
-+P15AppletFactory_ReadRecord(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgReadRecord *rrs = (const P15AppletArgReadRecord *)param;
-+ return P15APDUFactory_ReadRecord(apdu, rrs->record,
-+ rrs->short_ef, rrs->flags, rrs->size);
-+}
-+
-+CKYStatus
-+P15AppletFactory_ReadBinary(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgReadBinary *res = (const P15AppletArgReadBinary *)param;
-+ return P15APDUFactory_ReadBinary(apdu, res->offset,
-+ res->short_ef, res->flags, res->size);
-+}
-+
-+CKYStatus
-+P15AppletFactory_ManageSecurityEnvironment(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgManageSecurityEnvironment *mse =
-+ (const P15AppletArgManageSecurityEnvironment *)param;
-+ return P15APDUFactory_ManageSecurityEnvironment(apdu, mse->p1,
-+ mse->p2, mse->keyRef);
-+}
-+
-+CKYStatus
-+P15AppletFactory_PerformSecurityOperation(CKYAPDU *apdu, const void *param)
-+{
-+ const P15AppletArgPerformSecurityOperation *pso =
-+ (const P15AppletArgPerformSecurityOperation *)param;
-+ return P15APDUFactory_PerformSecurityOperation(apdu, pso->dir, pso->chain,
-+ pso->retLen, pso->data);
-+}
-+/*****************************************************************
-+ *
-+ * Generic Fill routines used by several calls in common
-+ * and globally accessible
-+ *
-+ *****************************************************************/
-+
-+/* a null fill function for those APDU's which do not return data */
-+CKYStatus
-+CKYAppletFill_Null(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ return CKYSUCCESS;
-+}
-+
-+/* a Buffer Replace fill function for those APDU's which return unformated
-+ * chunks of data */
-+CKYStatus
-+CKYAppletFill_ReplaceBuffer(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYBuffer *buf = (CKYBuffer *)param;
-+
-+ if (buf == NULL) {
-+ return CKYSUCCESS;
-+ }
-+ return CKYBuffer_Replace(buf, 0, CKYBuffer_Data(response),
-+ CKYBuffer_Size(response) -2);
-+}
-+
-+/* a Buffer Append fill function. Can be used with any APDU that uses Buffer
-+ * Replace. Repeated calls continuously fill the buffer. Most useful for read.
-+ */
-+CKYStatus
-+CKYAppletFill_AppendBuffer(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYBuffer *buf = (CKYBuffer *)param;
-+
-+ return CKYBuffer_AppendData(buf, CKYBuffer_Data(response),
-+ CKYBuffer_Size(response) -2);
-+}
-+
-+
-+CKYStatus
-+CKYAppletFill_Byte(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYByte *v = (CKYByte *)param;
-+
-+ *v = CKYBuffer_GetChar(response, 0);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYAppletFill_Short(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ unsigned short *v = (unsigned short *)param;
-+
-+ *v = CKYBuffer_GetShort(response, 0);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYAppletFill_Long(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ unsigned long *v = (unsigned long *)param;
-+
-+ *v = CKYBuffer_GetLong(response, 0);
-+ return CKYSUCCESS;
-+}
-+
-+/*****************************************************************
-+ *
-+ * Utilities shared by all the fetch Cards.
-+ *
-+ *****************************************************************/
-+/*
-+ * verify the we got a successful response. Responses should include
-+ * the expected data returned plus a 2 byte return code. This return
-+ * code should be 0x9000 on success.
-+ */
-+CKYBool
-+CKYApplet_VerifyResponse(const CKYBuffer *buf, CKYSize dataSize,
-+ CKYISOStatus *apduRC) {
-+ CKYSize size = CKYBuffer_Size(buf);
-+ CKYISOStatus rc = CKYISO_INVRESPONSE;
-+ CKYBool valid = 0;
-+
-+ /* is there enough size for the return code ? */
-+ if (size < 2) {
-+ goto done;
-+ }
-+ /* fetch the data */
-+ rc = CKYBuffer_GetShort(buf, size-2);
-+
-+ /* is there enough size for the expected data ? */
-+ if ((dataSize != CKY_SIZE_UNKNOWN) && (size != dataSize+2)) {
-+ goto done;
-+ }
-+
-+ /* did we return successfully? */
-+ valid = (rc == CKYISO_SUCCESS) || ((rc & CKYISO_MORE_MASK) == CKYISO_MORE);
-+
-+done:
-+ if (apduRC) {
-+ *apduRC = rc;
-+ }
-+ return valid;
-+}
-+
-+
-+/*
-+ * most commands have identical operations. Isolate the differences in
-+ * call back functions, and create a generic APDU handler which Creates
-+ * APDU's, Does the exchange, and fills in the results.
-+ */
-+CKYStatus
-+CKYApplet_HandleAPDU(CKYCardConnection *conn,
-+ CKYAppletFactory afFunc, const void *afArg,
-+ const CKYBuffer *nonce, CKYSize size,
-+ CKYFillFunction fillFunc, void *fillArg, CKYISOStatus *apduRC)
-+{
-+ CKYAPDU apdu;
-+ CKYBuffer response;
-+ CKYStatus ret;
-+
-+ if (apduRC) {
-+ *apduRC = CKYISO_NORESPONSE;
-+ }
-+
-+ /* initialize the response and APDU buffers */
-+ CKYBuffer_InitEmpty(&response);
-+ ret = CKYAPDU_Init(&apdu);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ /* fill in the APDU buffer with the correct values */
-+ ret = (*afFunc)(&apdu, afArg);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ /* if NONCE supplied, add it to the end of the apdu */
-+ if (nonce) {
-+ /*
-+ * Local Secured commands need the nonce returned from Login to
-+ * verify that they are valid. Nonce's are just added to the end
-+ * of the APDU much like
-+ */
-+ ret = CKYAPDU_AppendSendDataBuffer(&apdu, nonce);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+
-+ /* send it to the card */
-+ ret = CKYCardConnection_ExchangeAPDU(conn, &apdu, &response);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ /* verify we got the expected response */
-+ if (!CKYApplet_VerifyResponse(&response, size, apduRC)) {
-+ ret = CKYAPDUFAIL;
-+ goto done;
-+ }
-+
-+ /* Fill in our output data structure */
-+ ret = (*fillFunc)(&response, size, fillArg);
-+done:
-+ CKYBuffer_FreeData(&response);
-+ CKYAPDU_FreeData(&apdu);
-+ return ret;
-+}
-+
-+
-+/*****************************************************************
-+ *
-+ * The following convience functions convert APDU calls
-+ * into function calls, with input and output parameters.
-+ * The application is still responsible for 1) creating a connection
-+ * to the card, 2) Getting a tranaction long, then 3) selecting
-+ * the appropriate applet (or Card manager). Except for those
-+ * calls that have been noted, the appropriate applet is the CoolKey
-+ * applet.
-+ *
-+ *****************************************************************/
-+/*
-+ * Select an applet. Must happen after we start a transaction and before
-+ * we issue any applet specific command.
-+ */
-+CKYStatus
-+CKYApplet_SelectFile(CKYCardConnection *conn, const CKYBuffer *AID,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, AID, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+static CKYByte coolkeyid[] = {0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00 };
-+/*
-+ * Select the CoolKey applet. Must happen after we start a transaction and
-+ * before we issue any applet specific command.
-+ */
-+CKYStatus
-+CKYApplet_SelectCoolKeyManager(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer COOLKEYAID;
-+ CKYBuffer_InitFromData(&COOLKEYAID, coolkeyid, sizeof(coolkeyid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &COOLKEYAID,
-+ NULL, 0, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&COOLKEYAID);
-+ return ret;
-+}
-+
-+static CKYByte CACPKIid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01 };
-+/*
-+ * Select the CoolKey applet. Must happen after we start a transaction and
-+ * before we issue any applet specific command.
-+ */
-+CKYStatus
-+CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cacAID,
-+ CKYByte instance, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer_AppendData(cacAID, CACPKIid, sizeof(CACPKIid));
-+ CKYBuffer_AppendChar(cacAID, instance);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, cacAID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ CKYBuffer_Resize(cacAID, 0);
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * Select the card manager. Must happen after we start a transaction and before
-+ * we issue any card manager commands.
-+ */
-+CKYStatus
-+CKYApplet_SelectCardManager(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectCardManager, NULL,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+static CKYByte cacmgrid[] = {0xa0, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00 };
-+CKYStatus
-+CACApplet_SelectCardManager(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer CAC_CM_AID;
-+ CKYBuffer_InitFromData(&CAC_CM_AID, cacmgrid, sizeof(cacmgrid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&CAC_CM_AID);
-+ return ret;
-+}
-+
-+static CKYByte cacCCCid[] = {0xa0, 0x00, 0x00, 0x01, 0x16, 0xdb, 0x00 };
-+CKYStatus
-+CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer CAC_CM_AID;
-+ CKYBuffer_InitFromData(&CAC_CM_AID, cacCCCid, sizeof(cacCCCid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &CAC_CM_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&CAC_CM_AID);
-+ return ret;
-+}
-+
-+CKYStatus
-+CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShortLE(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+/*
-+ * GetCPLC cluster -- must be called with CM selected
-+ */
-+static CKYStatus
-+ckyAppletFill_GetCPLCData(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYAppletRespGetCPLCData *gcdp = (CKYAppletRespGetCPLCData *)param;
-+
-+ gcdp->CPLCtag = CKYBuffer_GetShort(response, 0);
-+ gcdp->length = CKYBuffer_GetChar(response, 2);
-+ gcdp->fabricator = CKYBuffer_GetShort(response, 3);
-+ gcdp->romType = CKYBuffer_GetShort(response, 5);
-+ gcdp->romOSID = CKYBuffer_GetShort(response, 7);
-+ gcdp->romOSDate = CKYBuffer_GetShort(response, 9);
-+ gcdp->romOSLevel = CKYBuffer_GetShort(response, 11);
-+ gcdp->eepromFabricationDate = CKYBuffer_GetShort(response, 13);
-+ gcdp->eepromSerialNumber = CKYBuffer_GetLong(response, 15);
-+ gcdp->eepromBatchID = CKYBuffer_GetShort(response, 19);
-+ gcdp->eepromModuleFabricator = CKYBuffer_GetShort(response, 21);
-+ gcdp->eepromModuleDate = CKYBuffer_GetShort(response, 23);
-+ gcdp->eepromICManufacturer = CKYBuffer_GetShort(response, 25);
-+ gcdp->eepromEmbeddingDate = CKYBuffer_GetShort(response, 27);
-+ gcdp->eepromPrePersonalizer = CKYBuffer_GetShort(response, 29);
-+ gcdp->eepromPrePersonalizeDate = CKYBuffer_GetShort(response, 31);
-+ gcdp->eepromPrePersonalizeID = CKYBuffer_GetLong(response, 33);
-+ gcdp->eepromPersonalizer = CKYBuffer_GetShort(response, 37);
-+ gcdp->eepromPersonalizeDate = CKYBuffer_GetShort(response, 39);
-+ gcdp->eepromPersonalizeID = CKYBuffer_GetLong(response, 41);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetCPLCData(CKYCardConnection *conn, CKYAppletRespGetCPLCData *cplc,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetCPLCData, NULL, NULL,
-+ CKY_SIZE_GET_CPLCDATA, ckyAppletFill_GetCPLCData, cplc, apduRC);
-+}
-+
-+/*
-+ * Get CUID. The CUID exists in the CPLC data. We use the same basic
-+ * APDU, but use a differ fill function to collect it.
-+ */
-+static CKYStatus
-+ckyAppletFill_GetCUID(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYBuffer *cuid = (CKYBuffer *)param;
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Resize(cuid,10);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ /* fabricator 2 bytes */
-+ CKYBuffer_SetChar(cuid, 0, CKYBuffer_GetChar(response, 3));
-+ CKYBuffer_SetChar(cuid, 1, CKYBuffer_GetChar(response, 4));
-+ /* IC Type 2 bytes */
-+ CKYBuffer_SetChar(cuid, 2, CKYBuffer_GetChar(response, 5));
-+ CKYBuffer_SetChar(cuid, 3, CKYBuffer_GetChar(response, 6));
-+ /* Batch ID 2 bytes */
-+ CKYBuffer_SetChar(cuid, 4, CKYBuffer_GetChar(response, 19));
-+ CKYBuffer_SetChar(cuid, 5, CKYBuffer_GetChar(response, 20));
-+ /* IC Serial Number 4 bytes */
-+ CKYBuffer_SetChar(cuid, 6, CKYBuffer_GetChar(response, 15));
-+ CKYBuffer_SetChar(cuid, 7, CKYBuffer_GetChar(response, 16));
-+ CKYBuffer_SetChar(cuid, 8, CKYBuffer_GetChar(response, 17));
-+ CKYBuffer_SetChar(cuid, 9, CKYBuffer_GetChar(response, 18));
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetCUID(CKYCardConnection *conn, CKYBuffer *cuid, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetCPLCData, NULL, NULL,
-+ CKY_SIZE_GET_CPLCDATA, ckyAppletFill_GetCUID, cuid, apduRC);
-+}
-+
-+/*
-+ * Get MSN. The MSN exists in the CPLC data. We use the same basic
-+ * APDU, but use a differ fill function to collect it.
-+ */
-+static CKYStatus
-+ckyAppletFill_GetMSN(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ unsigned long *msn = (unsigned long *)param;
-+ *msn = CKYBuffer_GetLong(response, 41);
-+
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetMSN(CKYCardConnection *conn, unsigned long *msn,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetCPLCData, NULL, NULL,
-+ CKY_SIZE_GET_CPLCDATA, ckyAppletFill_GetMSN, msn, apduRC);
-+}
-+
-+/*
-+ * ListKeys cluster
-+ */
-+static CKYStatus
-+ckyAppletFill_ListKeys(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYAppletRespListKeys *lkp = (CKYAppletRespListKeys *)param;
-+
-+ lkp->keyNum = CKYBuffer_GetChar(response, 0);
-+ lkp->keyType = CKYBuffer_GetChar(response, 1);
-+ lkp->keyPartner = CKYBuffer_GetChar(response, 2);
-+ lkp->keySize = CKYBuffer_GetShort(response, 3);
-+ lkp->readACL = CKYBuffer_GetShort(response, 5);
-+ lkp->writeACL = CKYBuffer_GetShort(response, 7);
-+ lkp->useACL = CKYBuffer_GetShort(response, 9);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_ListKeys(CKYCardConnection *conn, CKYByte seq,
-+ CKYAppletRespListKeys *lkp, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ListKeys, &seq, NULL,
-+ CKY_SIZE_LIST_KEYS, ckyAppletFill_ListKeys, lkp, apduRC);
-+}
-+
-+/*
-+ * Compute Crypt Cluster.
-+ *
-+ * Compute Crypt takes 3 types: Init, Process, Final.
-+ *
-+ */
-+CKYStatus
-+CKYApplet_ComputeCryptInit(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte mode, CKYByte direction, CKYByte location,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgComputeCrypt ccd;
-+ ccd.keyNumber = keyNumber;
-+ ccd.mode = mode;
-+ ccd.direction = direction;
-+ ccd.location = location;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptInit, &ccd,
-+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_ComputeCryptProcess(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgComputeCrypt ccd;
-+ ccd.keyNumber = keyNumber;
-+ ccd.location = location;
-+ ccd.data = data;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptProcess,
-+ &ccd, nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+/* computeECCValue returns data in the form :
-+ * len: short
-+ * data: byte[len]
-+ * This fill routine returns A buffer with a copy of data and a length of len */
-+static CKYStatus
-+ckyAppletFill_ComputeECCValueFinal(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ CKYBuffer *cbuf = (CKYBuffer *)param;
-+ CKYSize respSize = CKYBuffer_Size(response);
-+ CKYSize dataLen;
-+
-+ if (cbuf == 0) {
-+ return CKYSUCCESS; /* app didn't want the result */
-+ }
-+ /* data response code + length code */
-+ if (respSize < 4) {
-+ return CKYAPDUFAIL;
-+ }
-+ dataLen = CKYBuffer_GetShort(response, 0);
-+ if (dataLen > (respSize-4)) {
-+ return CKYAPDUFAIL;
-+ }
-+ return CKYBuffer_Replace(cbuf, 0, CKYBuffer_Data(response)+2, dataLen);
-+}
-+
-+/* computeCrypt returns data in the form :
-+ * len: short
-+ * data: byte[len]
-+ * This fill routine returns A buffer with a copy of data and a length of len */
-+static CKYStatus
-+ckyAppletFill_ComputeCryptFinal(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ CKYBuffer *cbuf = (CKYBuffer *)param;
-+ CKYSize respSize = CKYBuffer_Size(response);
-+ CKYSize dataLen;
-+
-+ if (cbuf == 0) {
-+ return CKYSUCCESS; /* app didn't want the result */
-+ }
-+ /* data response code + length code */
-+ if (respSize < 4) {
-+ return CKYAPDUFAIL;
-+ }
-+ dataLen = CKYBuffer_GetShort(response, 0);
-+ if (dataLen > (respSize-4)) {
-+ return CKYAPDUFAIL;
-+ }
-+ return CKYBuffer_Replace(cbuf, 0, CKYBuffer_Data(response)+2, dataLen);
-+}
-+
-+CKYStatus
-+CKYApplet_ComputeCryptFinal(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data, CKYBuffer *sig, CKYBuffer *result,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgComputeCrypt ccd;
-+ ccd.keyNumber = keyNumber;
-+ ccd.location = location;
-+ ccd.data = data;
-+ ccd.data = sig;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ComputeCryptFinal, &ccd,
-+ nonce, CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal, result, apduRC);
-+}
-+
-+/*
-+ * do a complete ComputeCrypt operation
-+ * ...look to data size to see if we should read/write the data to
-+ * the on card buffer. (future)
-+ */
-+CKYStatus
-+CKYApplet_ComputeCrypt(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte mode, CKYByte direction, const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYAppletArgComputeCrypt ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+ short dataSize = 0;
-+ int use2APDUs = 0;
-+ int use_dl_object = CKYBuffer_Size(data) > 200 ;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+ ccd.mode = mode;
-+ ccd.direction = direction;
-+ ccd.location = use_dl_object ? CKY_DL_OBJECT : CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (use_dl_object) {
-+ CKYBuffer sizeBuf;
-+
-+ CKYBuffer_InitEmpty(&sizeBuf);
-+ CKYBuffer_AppendShort(&sizeBuf, CKYBuffer_Size(data));
-+
-+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
-+ 0, CKYBuffer_Size(&sizeBuf), nonce,
-+ &sizeBuf, apduRC);
-+
-+ CKYBuffer_FreeData(&sizeBuf);
-+ if( ret != CKYSUCCESS)
-+ goto fail;
-+
-+ ret = CKYApplet_WriteObjectFull(conn, 0xffffffff,
-+ 2, CKYBuffer_Size(data), nonce,
-+ data, apduRC);
-+
-+ if(ret != CKYSUCCESS)
-+ goto fail;
-+ }
-+
-+ if (mode == CKY_RSA_NO_PAD) {
-+ ccd.data = use_dl_object ? &empty : data;
-+ ccd.sig = sig;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeCryptOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
-+ use_dl_object ? NULL : result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ use2APDUs = 1; /* maybe it's an old applet */
-+ }
-+ } else {
-+ use2APDUs = 1;
-+ }
-+ if (use2APDUs) {
-+ /* future, if data is to big write it to the internal object
-+ * and set location to DL_OBJECT */
-+ ccd.data = ∅
-+ ccd.sig = sig;
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeCryptInit, &ccd, nonce,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+ if (ret == CKYSUCCESS) {
-+ ccd.data = use_dl_object ? &empty : data;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeCryptFinal, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeCryptFinal,
-+ use_dl_object ? NULL : result, apduRC);
-+ }
-+ }
-+
-+ if (use_dl_object && ret == CKYSUCCESS) {
-+ CKYBuffer sizeOutBuf;
-+ CKYBuffer_InitEmpty(&sizeOutBuf);
-+
-+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
-+ 0, 2,
-+ nonce,&sizeOutBuf,apduRC);
-+
-+ if(ret != CKYSUCCESS) {
-+ CKYBuffer_FreeData(&sizeOutBuf);
-+ goto fail;
-+ }
-+
-+ dataSize = CKYBuffer_GetShort(&sizeOutBuf, 0);
-+
-+ CKYBuffer_FreeData(&sizeOutBuf);
-+
-+ ret = CKYApplet_ReadObjectFull(conn,0xffffffff,
-+ 2, dataSize,
-+ nonce,result,apduRC);
-+ }
-+
-+fail:
-+
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYApplet_ComputeECCKeyAgreement(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *publicValue, CKYBuffer *sharedSecret,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret = CKYAPDUFAIL;
-+ CKYAppletArgComputeECCKeyAgreement ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+ /* Routine creates a sym key, should easily fit in one apdu */
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+ ccd.location = CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (ccd.location == CKY_DL_APDU) {
-+ ccd.publicValue = publicValue;
-+ ccd.secretKey = sharedSecret;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeECCKeyAgreementOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeECCValueFinal,
-+ result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ return ret;
-+ }
-+ }
-+
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYApplet_ComputeECCSignature(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret = CKYAPDUFAIL;
-+ CKYAppletArgComputeECCSignature ccd;
-+ CKYBuffer empty;
-+ CKYISOStatus status;
-+
-+ CKYBuffer_InitEmpty(&empty);
-+ ccd.keyNumber = keyNumber;
-+
-+ /* Assume APDU, the signature can only get so big with our key sizes, ~ 130 for 521 bit key. */
-+ ccd.location = CKY_DL_APDU;
-+
-+ if (!apduRC)
-+ apduRC = &status;
-+
-+ if (ccd.location == CKY_DL_APDU) {
-+ ccd.data = data;
-+ ccd.sig = sig;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CKYAppletFactory_ComputeECCSignatureOneStep, &ccd, nonce,
-+ CKY_SIZE_UNKNOWN, ckyAppletFill_ComputeECCValueFinal,
-+ result, apduRC);
-+ if (ret == CKYAPDUFAIL && *apduRC == CKYISO_INCORRECT_P2) {
-+ return ret;
-+ }
-+
-+ }
-+
-+ return ret;
-+}
-+
-+/*
-+ * do a CAC Sign/Decrypt
-+ */
-+CKYStatus
-+CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
-+ CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+
-+ CKYBuffer_Resize(result, 0);
-+ for(offset = 0; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE;
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE) {
-+ CKYBuffer_Resize(&tmp,0);
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, CKY_MAX_WRITE_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptStep,
-+ &tmp, NULL, CKY_SIZE_UNKNOWN,
-+ CKYAppletFill_AppendBuffer,
-+ result, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+ CKYBuffer_Resize(&tmp,0);
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, dataSize - offset);
-+ ret = CKYApplet_HandleAPDU(conn, CACAppletFactory_SignDecryptFinal,
-+ &tmp, NULL, CKY_SIZE_UNKNOWN,
-+ CKYAppletFill_AppendBuffer,
-+ result, apduRC);
-+
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != dataSize)) {
-+ /* RSA returns the same data size as input, didn't happen, so
-+ * something is wrong. */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-+
-+const P15PinInfo CACPinInfo =
-+ { P15PinInitialized|P15PinNeedsPadding, P15PinUTF8, 0, 8, 8, 0, 0xff };
-+const P15PinInfo PIVPinInfo =
-+ { P15PinLocal|P15PinInitialized|P15PinNeedsPadding,
-+ P15PinUTF8, 0, 8, 8, 0, 0xff };
-+/*
-+ * do a CAC VerifyPIN
-+ */
-+CKYStatus
-+CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin, int local,
-+ CKYISOStatus *apduRC)
-+{
-+ return P15Applet_VerifyPIN(conn, pin,
-+ local ? &PIVPinInfo: &CACPinInfo, apduRC);
-+}
-+
-+
-+/*
-+ * Get a CAC Certificate
-+ */
-+CKYStatus
-+CACApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYSize size = 100;
-+
-+ CKYBuffer_Resize(cert,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_GetCertificate, &size, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+ while ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-+ size = *apduRC & ~CKYISO_MORE_MASK;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_GetCertificate, &size, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * Read a CAC Tag/Value file
-+ */
-+CKYStatus
-+CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type, CKYBuffer *buffer,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYByte maxtransfer;
-+ unsigned short offset = 0;
-+ unsigned short size;
-+ CACAppletArgReadFile rfs;
-+
-+ CKYBuffer_Resize(buffer,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ rfs.offset = 0;
-+ rfs.count = 2;
-+ rfs.type = type;
-+
-+ /* APDU's are expensive, Grab a big chunk of the file first if possible */
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_ReadFile, &rfs, NULL,
-+ rfs.count, CKYAppletFill_AppendBuffer,
-+ buffer, apduRC);
-+ /* file is probably smaller than 100 bytes, get the actual size first */
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ size = CKYBuffer_GetShortLE(buffer, 0) + 2 /* include the length itself */;
-+ maxtransfer = CKY_MAX_READ_CHUNK_SIZE;
-+ /* get the rest of the buffer if necessary */
-+ for (offset = CKYBuffer_Size(buffer); size > offset;
-+ offset = CKYBuffer_Size(buffer)) {
-+ rfs.offset = offset;
-+ rfs.count = MIN(size - offset, maxtransfer);
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_ReadFile, &rfs, NULL,
-+ rfs.count, CKYAppletFill_AppendBuffer,
-+ buffer, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ if (*apduRC == CAC_INVALID_PARAMS) {
-+ maxtransfer = maxtransfer/2;
-+ if (maxtransfer == 0) {
-+ return ret;
-+ }
-+ } else {
-+ return ret;
-+ }
-+ }
-+ }
-+ return ret;
-+}
-+
-+/*
-+ * Select a EF
-+ */
-+CKYStatus
-+P15Applet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShort(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, P15AppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15Applet_SelectRootFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer efBuf;
-+ CKYBuffer_InitEmpty(&efBuf);
-+ CKYBuffer_AppendShort(&efBuf, ef);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile, &efBuf,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ CKYBuffer_FreeData(&efBuf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15Applet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ const P15PinInfo *pinInfo, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYSize size;
-+ CKYBuffer encodedPin;
-+ P15AppletArgVerifyPIN vps;
-+
-+ CKYBuffer_InitEmpty(&encodedPin);
-+
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+
-+ size = strlen(pin);
-+ if (pinInfo->pinFlags & P15PinNeedsPadding) {
-+ if (size > pinInfo->storedLength) {
-+ size = pinInfo->storedLength;
-+ }
-+ ret=CKYBuffer_Reserve(&encodedPin, pinInfo->storedLength);
-+ if (ret != CKYSUCCESS) { goto fail; }
-+ }
-+ /* This is where we would do upcase processing for the case insensitive
-+ * flag. It's also where we would do mapping for bcd pins */
-+ ret = CKYBuffer_Replace(&encodedPin, 0, (const CKYByte *)pin, size);
-+ if (ret != CKYSUCCESS) { goto fail; }
-+ if (pinInfo->pinFlags & P15PinNeedsPadding) {
-+ int i;
-+ int padSize = pinInfo->storedLength - size;
-+ for (i=0; i < padSize; i++) {
-+ CKYBuffer_AppendChar(&encodedPin, pinInfo->padChar);
-+ }
-+ }
-+
-+ vps.pinRef = pinInfo->pinRef |
-+ ((pinInfo->pinFlags & P15PinLocal) ? ISO_LOGIN_LOCAL : ISO_LOGIN_GLOBAL);
-+ vps.pinVal = &encodedPin;
-+ ret = CKYApplet_HandleAPDU(conn, P15AppletFactory_VerifyPIN, &vps, NULL,
-+ 0, CKYAppletFill_Null,
-+ NULL, apduRC);
-+ /* it's unfortunate that the same code that means 'more data to follow' for
-+ * GetCertificate also means, auth failure, you only have N more attempts
-+ * left in the verify PIN call */
-+ if ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-+ ret = CKYAPDUFAIL;
-+ }
-+fail:
-+ CKYBuffer_FreeData(&encodedPin);
-+ return ret;
-+}
-+
-+
-+/*
-+ * Read Record
-+ */
-+CKYStatus
-+P15Applet_ReadRecord(CKYCardConnection *conn, CKYByte record, CKYByte short_ef,
-+ CKYByte flags, CKYByte size, CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ P15AppletArgReadRecord rrd;
-+
-+ rrd.record = record;
-+ rrd.short_ef = short_ef;
-+ rrd.flags = flags;
-+ rrd.size = size;
-+ return CKYApplet_HandleAPDU(conn, P15AppletFactory_ReadRecord, &rrd, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_ReplaceBuffer, data, apduRC);
-+}
-+
-+static CKYStatus
-+P15Applet_ManageSecurityEnvironment(CKYCardConnection *conn, CKYByte key,
-+ CKYByte direction, CKYByte p1,
-+ CKYISOStatus *apduRC)
-+{
-+ P15AppletArgManageSecurityEnvironment mse;
-+
-+ mse.p1 = p1; /* this appears to be where most cards disagree */
-+ mse.p2 = (direction == CKY_DIR_DECRYPT) ? ISO_MSE_KEA : ISO_MSE_SIGN;
-+ mse.keyRef = key; /* should be CKYBuffer in the future? */
-+ return CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_ManageSecurityEnvironment, &mse, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+P15Applet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, CKYByte direction,
-+ const CKYBuffer *data, CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ P15AppletArgPerformSecurityOperation pso;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+ int length = dataSize;
-+ int appendLength = length;
-+ int hasPad = 0;
-+
-+ /* Hack, lie and say we are always doing encipherment */
-+ direction = CKY_DIR_DECRYPT;
-+ CKYBuffer_Resize(result,0);
-+ /*
-+ * first set the security environment
-+ */
-+ ret = P15Applet_ManageSecurityEnvironment(conn, key, direction,
-+ ISO_MSE_SET|ISO_MSE_QUAL_COMPUTE, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+
-+ pso.data = &tmp;
-+ pso.dir = direction;
-+ if (direction == CKY_DIR_DECRYPT) {
-+ length++;
-+ CKYBuffer_AppendChar(&tmp, 0x00); /* pad byte */
-+ hasPad = 1;
-+ }
-+ if (CKYCardConnection_GetProtocol(conn) == SCARD_PROTOCOL_T0) {
-+ ret = CKYBuffer_Reserve(&tmp, CKY_MAX_WRITE_CHUNK_SIZE);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ for(offset = 0; length > CKY_MAX_WRITE_CHUNK_SIZE;
-+ hasPad = 0,
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE,
-+ length -= CKY_MAX_WRITE_CHUNK_SIZE) {
-+ pso.chain = 1;
-+ pso.retLen = 0;
-+ CKYBuffer_AppendBuffer(&tmp, data, offset,
-+ hasPad ? (CKY_MAX_WRITE_CHUNK_SIZE-1) : CKY_MAX_WRITE_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_PerformSecurityOperation, &pso, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_Null, NULL, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_Resize(&tmp, 0);
-+ }
-+ appendLength = length;
-+ } else {
-+ ret = CKYBuffer_Reserve(&tmp, length);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ }
-+ CKYBuffer_AppendBuffer(&tmp, data, offset, appendLength);
-+ pso.chain = 0;
-+ pso.retLen = dataSize;
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ P15AppletFactory_PerformSecurityOperation, &pso, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_ReplaceBuffer, result, apduRC);
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-+
-+/*
-+ * Read Binary
-+ */
-+CKYStatus
-+P15Applet_ReadBinary(CKYCardConnection *conn, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte size,
-+ CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ P15AppletArgReadBinary red;
-+
-+ red.offset = offset;
-+ red.short_ef = short_ef;
-+ red.flags = flags;
-+ red.size = size;
-+ return CKYApplet_HandleAPDU(conn, P15AppletFactory_ReadBinary, &red, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, data, apduRC);
-+}
-+
-+CKYStatus
-+CACApplet_GetCertificateFirst(CKYCardConnection *conn, CKYBuffer *cert,
-+ CKYSize *nextSize, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYSize size = 100;
-+
-+ CKYBuffer_Resize(cert,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ *nextSize = 0;
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_GetCertificate, &size, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+ if ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-+ *nextSize = *apduRC & ~CKYISO_MORE_MASK;
-+ }
-+ return ret;
-+}
-+
-+CKYStatus
-+CACApplet_GetCertificateAppend(CKYCardConnection *conn, CKYBuffer *cert,
-+ CKYSize nextSize, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYSize size = nextSize;
-+
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_GetCertificate, &size, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+ while ((*apduRC & CKYISO_MORE_MASK) == CKYISO_MORE) {
-+ size = *apduRC & ~CKYISO_MORE_MASK;
-+ ret = CKYApplet_HandleAPDU(conn,
-+ CACAppletFactory_GetCertificate, &size, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+ }
-+ return ret;
-+}
-+
-+/* Select the PIV applet */
-+static CKYByte pivAid[] = {0xa0, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00,
-+ 0x10, 0x00};
-+CKYStatus
-+PIVApplet_Select(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYBuffer PIV_Applet_AID,return_AID;
-+
-+ CKYBuffer_InitEmpty(&return_AID);
-+ CKYBuffer_InitFromData(&PIV_Applet_AID, pivAid, sizeof(pivAid));
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_SelectFile,
-+ &PIV_Applet_AID,
-+ NULL, CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer,
-+ &return_AID, apduRC);
-+ /* Some cards return OK, but don't switch to our applet */
-+ /* PIV has a well defined return for it's select, check to see if we have
-+ * a PIV card here */
-+ if (CKYBuffer_GetChar(&return_AID,0) != 0x61) {
-+ /* not an application property template, so not a PIV. We could
-+ * check that the aid tag (0x4f) and theallocation authority tag (0x79)
-+ * are present, but what we are really avoiding is broken cards that
-+ * lie about being able to switch to a particular applet, so the first
-+ * tag should be sufficient */
-+ ret = CKYAPDUFAIL; /* what we should have gotten */
-+ }
-+ CKYBuffer_FreeData(&PIV_Applet_AID);
-+ CKYBuffer_FreeData(&return_AID);
-+ return ret;
-+}
-+
-+/*
-+ * Get a PIV Certificate
-+ */
-+CKYStatus
-+PIVApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert, int tag,
-+ CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYISOStatus status;
-+ CKYBuffer tagBuf;
-+
-+ CKYBuffer_InitEmpty(&tagBuf);
-+ CKYBuffer_Reserve(&tagBuf,4); /* can be up to 4 bytes */
-+
-+ CKYBuffer_Resize(cert,0);
-+ if (apduRC == NULL) {
-+ apduRC = &status;
-+ }
-+ if (tag >= 0x01000000) {
-+ ret = CKYBuffer_AppendChar(&tagBuf, (tag >> 24) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ if (tag >= 0x010000) {
-+ ret = CKYBuffer_AppendChar(&tagBuf, (tag >> 16) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ if (tag >= 0x0100) {
-+ ret =CKYBuffer_AppendChar(&tagBuf, (tag >> 8) & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+ }
-+ ret = CKYBuffer_AppendChar(&tagBuf, tag & 0xff);
-+ if (ret != CKYSUCCESS) { goto loser; }
-+
-+
-+ ret = CKYApplet_HandleAPDU(conn,
-+ PIVAppletFactory_GetCertificate, &tagBuf, NULL,
-+ CKY_SIZE_UNKNOWN, CKYAppletFill_AppendBuffer, cert,
-+ apduRC);
-+loser:
-+ CKYBuffer_FreeData(&tagBuf);
-+
-+ return ret;
-+}
-+
-+
-+/*
-+ * record the next ber tag and length. NOTE: this is a state machine.
-+ * we can handle the case where we are passed the data just one byte
-+ * at a time.
-+ */
-+static CKYStatus
-+pivUnwrap(const CKYBuffer *buf, CKYOffset *offset,
-+ CKYSize *dataSize, PIVUnwrapState *unwrap)
-+{
-+ if (unwrap->tag == 0) {
-+ unwrap->tag = CKYBuffer_GetChar(buf, *offset);
-+ if (unwrap->tag == 0) unwrap->tag = 0xff;
-+ (*offset)++;
-+ (*dataSize)--;
-+ }
-+ if (*dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ if (unwrap->length_bytes != 0) {
-+ int len;
-+ if (unwrap->length_bytes == -1) {
-+ len = CKYBuffer_GetChar(buf, *offset);
-+ unwrap->length_bytes = 0;
-+ unwrap->length = len;
-+ (*offset)++;
-+ (*dataSize)--;
-+ if (len & 0x80) {
-+ unwrap->length = 0;
-+ unwrap->length_bytes = len & 0x7f;
-+ }
-+ }
-+ while ((*dataSize != 0) && (unwrap->length_bytes != 0)) {
-+ len = CKYBuffer_GetChar(buf, *offset);
-+ (*offset) ++;
-+ (*dataSize) --;
-+ unwrap->length = ((unwrap->length) << 8 | len);
-+ unwrap->length_bytes--;
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+/*
-+ * Remove the BER wrapping first...
-+ */
-+static CKYStatus
-+pivAppletFill_AppendUnwrapBuffer(const CKYBuffer *response,
-+ CKYSize size, void *param)
-+{
-+ PIVAppletRespSignDecrypt *prsd = (PIVAppletRespSignDecrypt *)param;
-+ CKYBuffer *buf = prsd->buf;
-+ CKYSize dataSize = CKYBuffer_Size(response);
-+ CKYOffset offset = 0;
-+
-+ if (dataSize <= 2) {
-+ return CKYSUCCESS;
-+ }
-+ dataSize -= 2;
-+ /* remove the first tag */
-+ (void) pivUnwrap(response, &offset, &dataSize, &prsd->tag_1);
-+ if (dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ /* remove the second tag */
-+ (void) pivUnwrap(response, &offset, &dataSize, &prsd->tag_2);
-+ if (dataSize == 0) {
-+ return CKYSUCCESS;
-+ }
-+ /* the rest is real data */
-+ return CKYBuffer_AppendData(buf, CKYBuffer_Data(response) + offset,
-+ dataSize);
-+}
-+
-+static CKYStatus
-+piv_wrapEncodeLength(CKYBuffer *buf, int length, int ber_len)
-+{
-+ if (ber_len== 1) {
-+ CKYBuffer_AppendChar(buf,length);
-+ } else {
-+ ber_len--;
-+ CKYBuffer_AppendChar(buf,0x80+ber_len);
-+ while(ber_len--) {
-+ CKYBuffer_AppendChar(buf,(length >> (8*ber_len)) & 0xff);
-+ }
-+ }
-+ return CKYSUCCESS;
-+}
-+/*
-+ * do a PIV Sign/Decrypt
-+ */
-+CKYStatus
-+PIVApplet_SignDecrypt(CKYCardConnection *conn, CKYByte key, unsigned int keySize, int derive,
-+ const CKYBuffer *data, CKYBuffer *result, CKYISOStatus *apduRC)
-+{
-+ CKYStatus ret;
-+ CKYSize dataSize = CKYBuffer_Size(data);
-+ CKYSize outputSize = keySize;
-+ CKYOffset offset = 0;
-+ CKYBuffer tmp;
-+ CKYByte alg;
-+ int ber_len_1;
-+ int ber_len_2;
-+ int length;
-+ PIVAppletArgSignDecrypt pasd;
-+ PIVAppletRespSignDecrypt prsd;
-+
-+ /* PIV only defines RSA 1024 and 2048, ECC 256 and ECC 384!!! */
-+ if (keySize == 128) { /* 1024 bit == 128 bytes */
-+ ber_len_2 = 2;
-+ ber_len_1 = 2;
-+ alg = 0x6;
-+ } else if (keySize == 256) { /* 2048 bits == 256 bytes */
-+ ber_len_2 = 3;
-+ ber_len_1 = 3;
-+ alg = 0x7;
-+ } else if (keySize == 32) { /* 256 bits = 32 bytes */
-+ ber_len_2 = 1;
-+ ber_len_1 = 1;
-+ alg = 0x11;
-+ if (!derive) outputSize = keySize*2;
-+ } else if (keySize == 48) { /* 384 bits = 48 bytes */
-+ ber_len_2 = 1;
-+ ber_len_1 = 1;
-+ alg = 0x14;
-+ if (!derive) outputSize = keySize*2;
-+ } else {
-+ return CKYINVALIDARGS;
-+ }
-+
-+ CKYBuffer_InitEmpty(&tmp);
-+ ret = CKYBuffer_Reserve(&tmp, CKY_MAX_WRITE_CHUNK_SIZE);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_AppendChar(&tmp,0x7c);
-+ piv_wrapEncodeLength(&tmp,dataSize + ber_len_2 + 3,ber_len_1);
-+ CKYBuffer_AppendChar(&tmp,0x82);
-+ CKYBuffer_AppendChar(&tmp,0x0);
-+ CKYBuffer_AppendChar(&tmp, derive ? 0x85 : 0x81);
-+ piv_wrapEncodeLength(&tmp,dataSize,ber_len_2);
-+
-+ /* now length == header length from here to the end*/
-+ length = CKYBuffer_Size(&tmp);
-+
-+ if (length + dataSize > CKY_MAX_WRITE_CHUNK_SIZE) {
-+ CKYBuffer_AppendBuffer(&tmp, data, 0, CKY_MAX_WRITE_CHUNK_SIZE-length);
-+ } else {
-+ CKYBuffer_AppendBuffer(&tmp, data, 0, dataSize);
-+ }
-+
-+ prsd.tag_1.tag = 0;
-+ prsd.tag_1.length_bytes = -1;
-+ prsd.tag_1.length = 0;
-+ prsd.tag_2.tag = 0;
-+ prsd.tag_2.length_bytes = -1;
-+ prsd.tag_2.length = 0;
-+ prsd.buf = result;
-+ pasd.alg = alg;
-+ pasd.key = key;
-+ pasd.buf = &tmp;
-+
-+ CKYBuffer_Resize(result,0);
-+ for(offset = -length; (dataSize-offset) > CKY_MAX_WRITE_CHUNK_SIZE; ) {
-+ pasd.chain = 1;
-+ pasd.len = 0;
-+ ret = CKYApplet_HandleAPDU(conn, PIVAppletFactory_SignDecrypt,
-+ &pasd, NULL, CKY_SIZE_UNKNOWN,
-+ pivAppletFill_AppendUnwrapBuffer,
-+ &prsd, apduRC);
-+ if (ret != CKYSUCCESS) {
-+ goto done;
-+ }
-+ CKYBuffer_Resize(&tmp,0);
-+ /* increment before we append the next tmp buffer */
-+ offset += CKY_MAX_WRITE_CHUNK_SIZE;
-+ CKYBuffer_AppendBuffer(&tmp, data, offset,
-+ MIN(dataSize-offset, CKY_MAX_WRITE_CHUNK_SIZE));
-+ }
-+
-+ pasd.chain = 0;
-+ pasd.len = outputSize;
-+
-+ ret = CKYApplet_HandleAPDU(conn, PIVAppletFactory_SignDecrypt,
-+ &pasd, NULL, CKY_SIZE_UNKNOWN,
-+ pivAppletFill_AppendUnwrapBuffer,
-+ &prsd, apduRC);
-+
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(result) != outputSize)) {
-+ /* RSA returns the same data size as input, didn't happen, so
-+ * something is wrong. */
-+ }
-+
-+done:
-+ CKYBuffer_FreeData(&tmp);
-+ return ret;
-+}
-+
-+/*
-+ * PIN cluster
-+ */
-+CKYStatus
-+CKYApplet_CreatePIN(CKYCardConnection *conn, CKYByte pinNumber,
-+ CKYByte maxAttempts, const char *pinValue,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgCreatePIN cpd;
-+ cpd.pinValue = pinValue;
-+ cpd.maxAttempts = maxAttempts;
-+ cpd.pinValue = pinValue;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_CreatePIN, &cpd, nonce,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+
-+}
-+
-+CKYStatus
-+CKYApplet_VerifyPIN(CKYCardConnection *conn, CKYByte pinNumber,
-+ const char *pinValue, CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgVerifyPIN vpd;
-+ vpd.pinValue = pinValue;
-+ vpd.pinNumber = pinNumber;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_VerifyPIN, &vpd, NULL,
-+ 8, CKYAppletFill_ReplaceBuffer, nonce, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_ChangePIN(CKYCardConnection *conn, const char *oldPin,
-+ const char *newPin, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgChangePIN cpd;
-+ cpd.oldPin = oldPin;
-+ cpd.newPin = newPin;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ChangePIN, &cpd, nonce,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_ListPINs(CKYCardConnection *conn, unsigned short *pins,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ListPINs, NULL, NULL,
-+ CKY_SIZE_LIST_PINS, CKYAppletFill_Short, pins, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_Logout(CKYCardConnection *conn, CKYByte pinNumber,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_Logout, &pinNumber, nonce,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_CreateObject(CKYCardConnection *conn, unsigned long objectID,
-+ CKYSize size, unsigned short readACL, unsigned short writeACL,
-+ unsigned short deleteACL, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgCreateObject cod;
-+ cod.objectID = objectID;
-+ cod.size = size;
-+ cod.readACL = readACL;
-+ cod.writeACL = writeACL;
-+ cod.deleteACL = deleteACL;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_CreateObject, &cod,
-+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_DeleteObject(CKYCardConnection *conn, unsigned long objectID,
-+ CKYByte zero, const CKYBuffer *nonce, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgDeleteObject dod;
-+ dod.objectID = objectID;
-+ dod.zero = zero;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_DeleteObject, &dod,
-+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+/*
-+ * Read Object cluster...
-+ * This is the raw version that goes issues a single APDU.
-+ */
-+CKYStatus
-+CKYApplet_ReadObject(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYByte size, const CKYBuffer *nonce,
-+ CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgReadObject rod;
-+
-+ rod.objectID = objectID;
-+ rod.offset = offset;
-+ rod.size = size;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ReadObject, &rod, nonce,
-+ size, CKYAppletFill_ReplaceBuffer, data, apduRC);
-+}
-+
-+/*
-+ * Read Object Append cluster...
-+ * This is also issues a single APDU, but appends the resulting data
-+ * to an existing buffer.
-+ */
-+
-+CKYStatus
-+CKYApplet_ReadObjectAppend(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYByte size, const CKYBuffer *nonce,
-+ CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgReadObject rod;
-+
-+ rod.objectID = objectID;
-+ rod.offset = offset;
-+ rod.size = size;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ReadObject, &rod, nonce,
-+ size, CKYAppletFill_AppendBuffer, data, apduRC);
-+}
-+
-+/*
-+ * Read Object
-+ * This is makes multiple APDU calls to read the entire object.
-+ */
-+CKYStatus
-+CKYApplet_ReadObjectFull(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYSize size, const CKYBuffer *nonce,
-+ CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgReadObject rod;
-+ CKYStatus ret = CKYSUCCESS;
-+
-+ rod.objectID = objectID;
-+ rod.offset = offset;
-+ do {
-+ rod.size = (CKYByte) MIN(size, CKY_MAX_READ_CHUNK_SIZE);
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_ReadObject, &rod,
-+ nonce, rod.size, CKYAppletFill_AppendBuffer, data, apduRC);
-+ size -= rod.size;
-+ rod.offset += rod.size;
-+ } while ((size > 0) && (ret == CKYSUCCESS));
-+
-+ return ret;
-+}
-+
-+
-+/*
-+ * Write Object
-+ * This makes multiple APDU calls to write the entire object.
-+ *
-+ */
-+
-+CKYStatus
-+CKYApplet_WriteObjectFull(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYSize size, const CKYBuffer *nonce,
-+ const CKYBuffer *data, CKYISOStatus *apduRC)
-+{
-+
-+ CKYBuffer chunk;
-+ CKYOffset srcOffset = 0;
-+ CKYAppletArgWriteObject wod;
-+ CKYStatus ret = CKYSUCCESS;
-+
-+ wod.objectID = objectID;
-+ wod.offset = offset;
-+ do {
-+ wod.size = (CKYByte) MIN(size, 220);
-+ ret = CKYBuffer_InitFromBuffer(&chunk, data,
-+ srcOffset, wod.size);
-+ if(ret == CKYSUCCESS) {
-+ wod.data = &chunk;
-+ ret = CKYApplet_HandleAPDU(conn, CKYAppletFactory_WriteObject, &wod,
-+ nonce, 0, CKYAppletFill_Null, NULL, apduRC);
-+ size -= wod.size;
-+ wod.offset += wod.size;
-+ srcOffset += wod.size;
-+ CKYBuffer_FreeData(&chunk);
-+ }
-+
-+ } while ((size > 0) && (ret == CKYSUCCESS));
-+
-+ return ret;
-+}
-+
-+/*
-+ * List Object cluster
-+ */
-+static CKYStatus
-+ckyAppletFill_ListObjects(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYAppletRespListObjects *lop = (CKYAppletRespListObjects *)param;
-+
-+ lop->objectID = CKYBuffer_GetLong(response, 0);
-+ lop->objectSize = CKYBuffer_GetLong(response, 4);
-+ lop->readACL = CKYBuffer_GetShort(response, 8);
-+ lop->writeACL = CKYBuffer_GetShort(response, 10);
-+ lop->deleteACL = CKYBuffer_GetShort(response, 12);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_ListObjects(CKYCardConnection *conn, CKYByte seq,
-+ CKYAppletRespListObjects *lop, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_ListObjects, &seq, NULL,
-+ CKY_SIZE_LIST_OBJECTS, ckyAppletFill_ListObjects, lop, apduRC);
-+}
-+
-+/*
-+ * GetStatus cluster
-+ */
-+static CKYStatus
-+ckyAppletFill_GetStatus(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYAppletRespGetStatus *gsp = (CKYAppletRespGetStatus *)param;
-+
-+ gsp->protocolMajorVersion = CKYBuffer_GetChar(response, 0);
-+ gsp->protocolMinorVersion = CKYBuffer_GetChar(response, 1);
-+ gsp->appletMajorVersion = CKYBuffer_GetChar(response, 2);
-+ gsp->appletMinorVersion = CKYBuffer_GetChar(response, 3);
-+ gsp->totalObjectMemory = CKYBuffer_GetLong(response, 4);
-+ gsp->freeObjectMemory = CKYBuffer_GetLong(response, 8);
-+ gsp->numberPins = CKYBuffer_GetChar(response, 12);
-+ gsp->numberKeys = CKYBuffer_GetChar(response, 13);
-+ gsp->loggedInMask = CKYBuffer_GetShort(response, 14);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetStatus(CKYCardConnection *conn, CKYAppletRespGetStatus *status,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetStatus, NULL, NULL,
-+ CKY_SIZE_GET_STATUS, ckyAppletFill_GetStatus, status, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_Noop(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_Noop, NULL, NULL,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_GetBuildID(CKYCardConnection *conn, unsigned long *buildID,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetBuildID, NULL, NULL,
-+ CKY_SIZE_GET_BUILDID, CKYAppletFill_Long, buildID, apduRC);
-+}
-+
-+/*
-+ * GetLifeCycle cluster
-+ */
-+static CKYStatus
-+ckyAppletFill_GetLifeCycle(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ *(CKYByte *)param= CKYBuffer_GetChar(response,0);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetLifeCycle(CKYCardConnection *conn, CKYByte *personalized,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetLifeCycle, NULL, NULL,
-+ CKY_SIZE_GET_LIFE_CYCLE, ckyAppletFill_GetLifeCycle, personalized, apduRC);
-+}
-+
-+static CKYStatus
-+ckyAppletFill_GetLifeCycleV2(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYAppletRespGetLifeCycleV2 *ext = (CKYAppletRespGetLifeCycleV2 *) param;
-+ ext->lifeCycle = CKYBuffer_GetChar(response,0);
-+ ext->pinCount = CKYBuffer_GetChar(response,1);
-+ ext->protocolMajorVersion = CKYBuffer_GetChar(response,2);
-+ ext->protocolMinorVersion = CKYBuffer_GetChar(response,3);
-+ return CKYSUCCESS;
-+}
-+
-+/*
-+ * GetStatus cluster
-+ */
-+static CKYStatus
-+ckyAppletFill_LifeCycleStatus(const CKYBuffer *response, CKYSize size, void *param)
-+{
-+ CKYAppletRespGetLifeCycleV2 *ext = (CKYAppletRespGetLifeCycleV2 *) param;
-+ ext->pinCount = CKYBuffer_GetChar(response,12);
-+ ext->protocolMajorVersion = CKYBuffer_GetChar(response,0);
-+ ext->protocolMinorVersion = CKYBuffer_GetChar(response,1);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetLifeCycleV2(CKYCardConnection *conn,
-+ CKYAppletRespGetLifeCycleV2 *ext, CKYISOStatus *apduRC)
-+{
-+ CKYStatus status;
-+ status = CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetLifeCycleV2,
-+ NULL,NULL, CKY_SIZE_GET_LIFE_CYCLE_V2, ckyAppletFill_GetLifeCycleV2,
-+ ext, apduRC);
-+
-+ /* Get Life Cycle Version 2 is a new APDU with combines data from
-+ * two other APDUs. Older tokens don't have this APDU, so use
-+ * the old method to get the data */
-+ if (status == CKYAPDUFAIL) {
-+ status = CKYApplet_GetLifeCycle(conn,&ext->lifeCycle, apduRC);
-+ if (status != CKYSUCCESS) {
-+ return status;
-+ }
-+ status = CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetStatus, NULL,
-+ NULL, CKY_SIZE_GET_STATUS, ckyAppletFill_LifeCycleStatus, ext, apduRC);
-+ }
-+ return status;
-+}
-+
-+/*
-+ * GetBuiltin cluster
-+ */
-+static CKYStatus
-+ckyAppletFill_GetBuiltinACL(const CKYBuffer *response,CKYSize size,void *param)
-+{
-+ CKYAppletRespGetBuiltinACL *gba = (CKYAppletRespGetBuiltinACL *) param;
-+ gba->create_object_ACL = CKYBuffer_GetShort(response,0);
-+ gba->create_object_ACL = CKYBuffer_GetShort(response,2);
-+ gba->create_object_ACL = CKYBuffer_GetShort(response,4);
-+ gba->enable_ACL_change = CKYBuffer_GetChar(response,6);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYApplet_GetBuiltinACL(CKYCardConnection *conn,
-+ CKYAppletRespGetBuiltinACL *gba, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetBuiltinACL, NULL,
-+ NULL, CKY_SIZE_GET_BUILTIN_ACL, ckyAppletFill_GetBuiltinACL, gba,
-+ apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_GetIssuerInfo(CKYCardConnection *conn, CKYBuffer *info,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetIssuerInfo, NULL,
-+ NULL, CKY_SIZE_GET_ISSUER_INFO, CKYAppletFill_ReplaceBuffer,
-+ info, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_GetRandom(CKYCardConnection *conn, CKYBuffer *data, CKYByte len,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetRandom, &len,
-+ NULL, len, CKYAppletFill_ReplaceBuffer, data, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_GetRandomAppend(CKYCardConnection *conn, CKYBuffer *data, CKYByte len,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_GetRandom, &len,
-+ NULL, len, CKYAppletFill_AppendBuffer, data, apduRC);
-+}
-+
-+CKYStatus
-+CKYApplet_SeedRandom(CKYCardConnection *conn, const CKYBuffer *data,
-+ CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_SeedRandom, data,
-+ NULL, 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+
-+
-+/*
-+ * deprecates 0.x functions
-+ */
-+/* old applet verify pin call (no nonce returned) */
-+CKYStatus
-+CKYApplet_VerifyPinV0(CKYCardConnection *conn, CKYByte pinNumber,
-+ const char *pinValue, CKYISOStatus *apduRC)
-+{
-+ CKYAppletArgVerifyPIN vpd;
-+ vpd.pinValue = pinValue;
-+ vpd.pinNumber = pinNumber;
-+
-+ vpd.pinValue = pinValue;
-+ vpd.pinNumber = pinNumber;
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_VerifyPIN, &vpd, NULL,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-+
-+/* logout all */
-+CKYStatus
-+CKYApplet_LogoutAllV0(CKYCardConnection *conn, CKYISOStatus *apduRC)
-+{
-+ return CKYApplet_HandleAPDU(conn, CKYAppletFactory_LogoutAllV0, NULL, NULL,
-+ 0, CKYAppletFill_Null, NULL, apduRC);
-+}
-diff -up ./esc/src/lib/coolkey/cky_applet.h.fix1 ./esc/src/lib/coolkey/cky_applet.h
---- ./esc/src/lib/coolkey/cky_applet.h.fix1 2018-04-26 11:44:38.436986198 -0700
-+++ ./esc/src/lib/coolkey/cky_applet.h 2018-04-26 11:44:38.436986198 -0700
-@@ -0,0 +1,680 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_APPLET_H
-+#define CKY_APPLET_H 1
-+
-+#include "cky_base.h"
-+#include "cky_card.h"
-+#include "cky_factory.h"
-+
-+/*
-+ * base typdefs
-+ */
-+/*
-+ * ISO and applet response codes.
-+ */
-+typedef unsigned short CKYISOStatus; /* applet return status */
-+/* Psuedo return codes created by the library software */
-+#define CKYISO_INVRESPONSE 0xffff /* code returned by library to
-+ * indicate no valid response
-+ * received */
-+#define CKYISO_NORESPONSE 0x0000 /* code returned by the library if
-+ * operation failed before
-+ * attempting to read a response */
-+/* ISO defined Return codes */
-+#define CKYISO_SUCCESS 0x9000 /* SUCCESS! */
-+#define CKYISO_MORE_MASK 0xff00 /* More data mask */
-+#define CKYISO_MORE 0x6300 /* More data available */
-+#define CKYISO_DATA_INVALID 0x6984
-+#define CKYISO_CONDITION_NOT_SATISFIED 0x6985 /* AKA not logged in (CAC)*/
-+#define CKYISO_SECURITY_NOT_SATISFIED 0x6982 /* AKA not logged in (PIV)*/
-+/* Applet Defined Return codes */
-+#define CKYISO_NO_MEMORY_LEFT 0x9c01 /* There have been memory
-+ * problems on the card */
-+#define CKYISO_AUTH_FAILED 0x9c02 /* Entered PIN is not correct */
-+#define CKYISO_OPERATION_NOT_ALLOWED 0x9c03 /* Required operation is not
-+ * allowed in actual
-+ * circumstances */
-+#define CKYISO_UNSUPPORTED_FEATURE 0x9c05 /* Required feature is not (yet)
-+ * supported */
-+#define CKYISO_UNAUTHORIZED 0x9c06 /* Required operation was not
-+ * authorized because of a lack of
-+ * privileges */
-+#define CKYISO_OBJECT_NOT_FOUND 0x9c07 /* Required object is missing */
-+#define CKYISO_OBJECT_EXISTS 0x9c08 /* New object ID already in use */
-+#define CKYISO_INCORRECT_ALG 0x9c09 /* Algorithm specified is not
-+ * correct */
-+#define CKYISO_SIGNATURE_INVALID 0x9c0b /* Verify operation detected an
-+ * invalid signature */
-+#define CKYISO_IDENTITY_BLOCKED 0x9c0c /* Operation has been blocked for
-+ * security reason */
-+#define CKYISO_INVALID_PARAMETER 0x9c0f /* Invalid input parameter to
-+ * command */
-+#define CKYISO_INCORRECT_P1 0x9c10 /* Incorrect P1 parameter */
-+#define CKYISO_INCORRECT_P2 0x9c11 /* Incorrect P2 parameter */
-+#define CKYISO_SEQUENCE_END 0x9c12 /* No more data available */
-+#define CKYISO_INTERNAL_ERROR 0x9cff /* Reserved for debugging,
-+ * shouldn't happen */
-+
-+#define CAC_INVALID_PARAMS 0x6a83
-+#define CAC_TAG_FILE 1
-+#define CAC_VALUE_FILE 2
-+
-+
-+#define CAC_TAG_CARDURL 0xf3
-+#define CAC_TAG_CERTIFICATE 0x70
-+#define CAC_TAG_CERTINFO 0x71
-+#define CAC_TLV_APP_PKI 0x04
-+
-+/*
-+ * Pin Constants as used by our applet
-+ */
-+#define CKY_OLD_USER_PIN_NUM 1 /* version 0 and earlier */
-+#define CKY_USER_PIN_NUM 0
-+
-+/*
-+ * special size that tells the Verify Function not to verify the size because
-+ * the ADPU can return variable size.
-+ */
-+#define CKY_SIZE_UNKNOWN 0xffffffff
-+
-+/*
-+ * structures for returning Applet responses
-+ */
-+typedef struct _CKYAppletRespGetStatus {
-+ CKYByte protocolMajorVersion;
-+ CKYByte protocolMinorVersion;
-+ CKYByte appletMajorVersion;
-+ CKYByte appletMinorVersion;
-+ unsigned long totalObjectMemory;
-+ unsigned long freeObjectMemory;
-+ CKYByte numberPins;
-+ CKYByte numberKeys;
-+ unsigned short loggedInMask;
-+} CKYAppletRespGetStatus;
-+
-+typedef struct _CKYAppletRespGetLifeCycleV2 {
-+ CKYByte lifeCycle;
-+ CKYByte pinCount;
-+ CKYByte protocolMajorVersion;
-+ CKYByte protocolMinorVersion;
-+} CKYAppletRespGetLifeCycleV2;
-+
-+typedef struct _CKYAppletRespGetBuiltinACL {
-+ unsigned short create_object_ACL;
-+ unsigned short create_key_ACL;
-+ unsigned short create_pin_ACL;
-+ CKYByte enable_ACL_change;
-+} CKYAppletRespGetBuiltinACL;
-+
-+typedef struct _CKYAppletRespGetCPLCData {
-+ unsigned short CPLCtag;
-+ CKYByte length;
-+ unsigned short fabricator;
-+ unsigned short romType;
-+ unsigned short romOSID;
-+ unsigned short romOSDate;
-+ unsigned short romOSLevel;
-+ unsigned short eepromFabricationDate;
-+ unsigned long eepromSerialNumber;
-+ unsigned short eepromBatchID;
-+ unsigned short eepromModuleFabricator;
-+ unsigned short eepromModuleDate;
-+ unsigned short eepromICManufacturer;
-+ unsigned short eepromEmbeddingDate;
-+ unsigned short eepromPrePersonalizer;
-+ unsigned short eepromPrePersonalizeDate;
-+ unsigned long eepromPrePersonalizeID;
-+ unsigned short eepromPersonalizer;
-+ unsigned short eepromPersonalizeDate;
-+ unsigned long eepromPersonalizeID;
-+} CKYAppletRespGetCPLCData;
-+
-+typedef struct _CKYAppletRespListObjects {
-+ unsigned long objectID;
-+ CKYSize objectSize;
-+ unsigned short readACL;
-+ unsigned short writeACL;
-+ unsigned short deleteACL;
-+} CKYAppletRespListObjects;
-+
-+typedef struct _CKYAppletRespListKeys {
-+ CKYByte keyNum;
-+ CKYByte keyType;
-+ CKYByte keyPartner;
-+ unsigned short keySize;
-+ unsigned short readACL;
-+ unsigned short writeACL;
-+ unsigned short useACL;
-+} CKYAppletRespListKeys;
-+
-+/*
-+ * structures for the generic factories
-+ */
-+typedef struct _CKYAppletArgCreatePIN {
-+ const char *pinValue;
-+ CKYByte pinNumber;
-+ CKYByte maxAttempts;
-+} CKYAppletArgCreatePIN;
-+
-+typedef struct _CKYAppletArgVerifyPIN {
-+ const char *pinValue;
-+ CKYByte pinNumber;
-+} CKYAppletArgVerifyPIN;
-+
-+typedef struct _CKYAppletArgChangePIN {
-+ const char *oldPin;
-+ const char *newPin;
-+ CKYByte pinNumber;
-+} CKYAppletArgChangePIN;
-+
-+typedef struct _CKYAppletArgCreateObject {
-+ unsigned long objectID;
-+ CKYSize size;
-+ unsigned short readACL;
-+ unsigned short writeACL;
-+ unsigned short deleteACL;
-+} CKYAppletArgCreateObject;
-+
-+typedef struct _CKYAppletArgDeleteObject {
-+ unsigned long objectID;
-+ CKYByte zero;
-+} CKYAppletArgDeleteObject;
-+
-+typedef struct _CKYAppletArgReadObject {
-+ unsigned long objectID;
-+ CKYOffset offset;
-+ CKYByte size;
-+} CKYAppletArgReadObject;
-+
-+
-+typedef struct _CKYAppletArgWriteObject {
-+ unsigned long objectID;
-+ CKYOffset offset;
-+ CKYByte size;
-+ CKYBuffer *data;
-+
-+} CKYAppletArgWriteObject;
-+
-+typedef struct _CKYAppletArgComputeCrypt {
-+ CKYByte keyNumber;
-+ CKYByte mode;
-+ CKYByte direction;
-+ CKYByte location;
-+ const CKYBuffer *data;
-+ const CKYBuffer *sig;
-+} CKYAppletArgComputeCrypt;
-+
-+typedef struct _CKYAppletArgComputeECCSignature {
-+ CKYByte keyNumber;
-+ CKYByte location;
-+ const CKYBuffer *data;
-+ const CKYBuffer *sig;
-+} CKYAppletArgComputeECCSignature;
-+
-+typedef struct _CKYAppletArgComputeECCKeyAgreement {
-+ CKYByte keyNumber;
-+ CKYByte location;
-+ const CKYBuffer *publicValue;
-+ const CKYBuffer *secretKey;
-+} CKYAppletArgComputeECCKeyAgreement;
-+
-+
-+typedef struct _CACAppletArgReadFile {
-+ CKYByte type;
-+ CKYByte count;
-+ unsigned short offset;
-+} CACAppletArgReadFile;
-+
-+typedef struct _PIVAppletArgSignDecrypt {
-+ CKYByte alg;
-+ CKYByte key;
-+ CKYByte chain;
-+ CKYSize len;
-+ CKYBuffer *buf;
-+} PIVAppletArgSignDecrypt;
-+
-+typedef struct _pivUnwrapState {
-+ CKYByte tag;
-+ CKYByte length;
-+ int length_bytes;
-+} PIVUnwrapState;
-+
-+typedef struct _PIVAppletRespSignDecrypt {
-+ PIVUnwrapState tag_1;
-+ PIVUnwrapState tag_2;
-+ CKYBuffer *buf;
-+} PIVAppletRespSignDecrypt;
-+
-+typedef struct _P15AppletArgReadRecord {
-+ CKYByte record;
-+ CKYByte short_ef;
-+ CKYByte flags;
-+ CKYByte size;
-+} P15AppletArgReadRecord;
-+
-+typedef struct _P15AppletArgReadBinary {
-+ unsigned short offset;
-+ CKYByte short_ef;
-+ CKYByte flags;
-+ CKYByte size;
-+} P15AppletArgReadBinary;
-+
-+typedef struct _P15AppletArgVerifyPIN {
-+ const CKYBuffer *pinVal;
-+ CKYByte pinRef;
-+} P15AppletArgVerifyPIN;
-+
-+typedef struct _P15AppletArgManageSecurityEnvironment {
-+ CKYByte p1;
-+ CKYByte p2;
-+ CKYByte keyRef;
-+}
-+ P15AppletArgManageSecurityEnvironment;
-+
-+typedef struct _P15AppletArgPerformSecurityOperation {
-+ CKYByte dir;
-+ int chain;
-+ CKYSize retLen;
-+ const CKYBuffer *data;
-+} P15AppletArgPerformSecurityOperation;
-+
-+/* fills in an APDU from a structure -- form of all the generic factories*/
-+typedef CKYStatus (*CKYAppletFactory)(CKYAPDU *apdu, const void *param);
-+/* fills in an a structure from a response -- form of all the fill structures*/
-+typedef CKYStatus (*CKYFillFunction)(const CKYBuffer *response,
-+ CKYSize size, void *param);
-+
-+CKY_BEGIN_PROTOS
-+/*****************************************************************
-+ *
-+ * Generic factorys are used by the generic APDU processing
-+ * to customize the formatting of APDU. The all have the same signature
-+ * as CKYAppletFactory. Typically APDUs are formatted
-+ * using parameterized calls of the form CKYAPDUFactory_ADPUNAME.
-+ * The generic processing code, however needs calls with a common
-+ * Signature. To accomplish the conversion, we build generic versions
-+ * which take a void * parameter. Trivial APDU's can pass NULL or a pointer
-+ * to the single parameter that they need. More complicated APDU's use
-+ * CKYAppletArg* data structures defined above to pass more arguments.
-+ *
-+ * Generic factorys then call the standard CKYAPDUFactor_ADPUNAME() functions
-+ * to build the APDUs. These functions are intended only as arguments
-+ * to the generic ADPU calls, and not to be called directly.
-+ *
-+ *****************************************************************/
-+/* param == CKYBuffer * (AID) */
-+CKYStatus CKYAppletFactory_SelectFile(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_SelectCardManager(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetCPLCData(CKYAPDU *apdu, const void *param);
-+/* param == CKYByte * (pointer to seq) */
-+CKYStatus CKYAppletFactory_ListKeys(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgComputeCrypt */
-+CKYStatus CKYAppletFactory_ComputeCryptInit(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgComputeCrypt */
-+CKYStatus CKYAppletFactory_ComputeCryptProcess(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgComputeCrypt */
-+CKYStatus CKYAppletFactory_ComputeCryptFinal(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgCreatePIN */
-+CKYStatus CKYAppletFactory_CreatePIN(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgVeriryPIN */
-+CKYStatus CKYAppletFactory_VerifyPIN(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgChangePIN */
-+CKYStatus CKYAppletFactory_ChangePIN(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_ListPINs(CKYAPDU *apdu, const void *param);
-+/* param == CKYByte * (pointer to pinNumber) */
-+CKYStatus CKYAppletFactory_Logout(CKYAPDU *apdu, const void *param);
-+/* Future add WriteObject */
-+/* parm == CKYAppletArgWriteObject */
-+CKYStatus CKYAppletFactory_WriteObject(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgCreateObject */
-+CKYStatus CKYAppletFactory_CreateObject(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgDeleteObject */
-+CKYStatus CKYAppletFactory_DeleteObject(CKYAPDU *apdu, const void *param);
-+/* param == CKYAppletArgReadObject */
-+CKYStatus CKYAppletFactory_ReadObject(CKYAPDU *apdu, const void *param);
-+/* param == CKYByte * (pointer to seq) */
-+CKYStatus CKYAppletFactory_ListObjects(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetStatus(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_Noop(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetBuildID(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetLifeCycle(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetLifeCycleV2(CKYAPDU *apdu, const void *param);
-+/* param == CKYByte * */
-+CKYStatus CKYAppletFactory_GetRandom(CKYAPDU *apdu, const void *param);
-+/* param == CKY_Buffer */
-+CKYStatus CKYAppletFactory_SeedRandom(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetIssuerInfo(CKYAPDU *apdu, const void *param);
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_GetBuiltinACL(CKYAPDU *apdu, const void *param);
-+/* deprecates 0.x functions */
-+/* param == NULL */
-+CKYStatus CKYAppletFactory_LogoutAllV0(CKYAPDU *apdu, const void *param);
-+
-+/*****************************************************************
-+ *
-+ * Generic Fill routines used by the generic APDU processing
-+ * to customize how the response data is returned to the application.
-+ * generally the param points to some structure which is filled in
-+ * by the Fill function from the response data. Each APDU command
-+ * can potentially have it's own fill function. Different appearent
-+ * functions can be accomplished by calling the same APDU with a different
-+ * fill function. The fill functions below are considered globally interesting
-+ * to applications that wish to make custom APDU calls using the
-+ * applet generic processing. Fill functions are never called directly,
-+ * but through callback, and all have the same signature (CKYFillFunction)
-+ *
-+ *****************************************************************/
-+/* a null fill function for those APDU's which do not return data */
-+CKYStatus CKYAppletFill_Null(const CKYBuffer *response, CKYSize size, void *param);
-+/* Buffer Fills: */
-+/* Replace fill function for those APDU's which return raw data */
-+/* param == CKYBuffer * */
-+CKYStatus CKYAppletFill_ReplaceBuffer(const CKYBuffer *response, CKYSize size,
-+ void *param);
-+/* Append fill function can be used with any APDU that uses Buffer
-+ * Replace. Repeated calls continuously adds more data to the buffer.
-+ * Useful for repeated operations like read. */
-+/* param == CKYBuffer * */
-+CKYStatus CKYAppletFill_AppendBuffer(const CKYBuffer *response,
-+ CKYSize size, void *param);
-+/* Single value fills: Byte, Short, & Long */
-+/* param == CKYByte * */
-+CKYStatus CKYAppletFill_Byte(const CKYBuffer *response, CKYSize size, void *param);
-+CKYStatus CKYAppletFill_Short(const CKYBuffer *response, CKYSize size, void *param);
-+CKYStatus CKYAppletFill_Long(const CKYBuffer *response, CKYSize size, void *param);
-+
-+/*****************************************************************
-+ *
-+ * Utilities shared by all the fetch Cards.
-+ *
-+ *****************************************************************/
-+/*
-+ * verify the we got a successful response. Responses should include
-+ * the expected data returned plus a 2 byte return code. This return
-+ * code should be 0x9000 on success. The function copies the return code
-+ * to apduRC if apduRC is not NULL.
-+ */
-+CKYBool CKYApplet_VerifyResponse(const CKYBuffer *response, CKYSize dataSize,
-+ CKYISOStatus *apduRC);
-+/*
-+ * most commands have identical operations. This function
-+ * handles these operations, isolating the differences in
-+ * call back functions.
-+ * It creates the ADPU using afFunc with afArg.
-+ * Adds nonce if it exists.
-+ * Sends the ADPU to the card through the connection conn.
-+ * Checks that the response was valid (returning the responce code in apduRC.
-+ * Formats the response data into fillArg with fillFunc
-+ * nonce and apduRC can be NULL (no nonce is added, no status returned
-+ * legal values for afArg are depened on afFunc.
-+ * legal values for fillArg are depened on fillFunc.
-+ */
-+CKYStatus CKYApplet_HandleAPDU(CKYCardConnection *conn,
-+ CKYAppletFactory afFunc, const void *afArg,
-+ const CKYBuffer *nonce, CKYSize size,
-+ CKYFillFunction fillFunc, void *fillArg, CKYISOStatus *apduRC);
-+
-+
-+/*****************************************************************
-+ *
-+ * The following convience functions convert APDU calls
-+ * into function calls, with input and output parameters.
-+ * The application is still responsible for
-+ * 1) creating a connection to the card,
-+ * 2) Getting a transaction lock, then
-+ * 3) selecting the appropriate applet (or Card manager).
-+ * Except for those calls that have been noted, the appropriate applet
-+ * is the CoolKey applet.
-+ *
-+ *****************************************************************/
-+/* Select an applet. Can happen with either applet selected */
-+CKYStatus CKYApplet_SelectFile(CKYCardConnection *conn, const CKYBuffer *AID,
-+ CKYISOStatus *apduRC);
-+
-+/* Select the CoolKey applet. Special case of the above command */
-+/* Can happen with either applet selected */
-+CKYStatus CKYApplet_SelectCoolKeyManager(CKYCardConnection *conn,
-+ CKYISOStatus *apduRC);
-+
-+/* Select the card manager. Can happen with either applet selected */
-+CKYStatus CKYApplet_SelectCardManager(CKYCardConnection *conn,
-+ CKYISOStatus *apduRC);
-+/* GetCPLC data -- must be called with CM selected */
-+/* fills in cplc */
-+CKYStatus CKYApplet_GetCPLCData(CKYCardConnection *conn,
-+ CKYAppletRespGetCPLCData *cplc, CKYISOStatus *apduRC);
-+/* Get CUID. -- must be called with CM selected */
-+/* special case of GetCPLCData */
-+/* fills in cuid */
-+CKYStatus CKYApplet_GetCUID(CKYCardConnection *conn,
-+ CKYBuffer *cuid, CKYISOStatus *apduRC);
-+/* Get MSN. -- must be called with CM selected */
-+/* special case of GetCPLCData */
-+/* returns msn */
-+CKYStatus CKYApplet_GetMSN(CKYCardConnection *conn, unsigned long *msn,
-+ CKYISOStatus *apduRC);
-+
-+/* List Keys -- see applet documentation */
-+CKYStatus CKYApplet_ListKeys(CKYCardConnection *conn, CKYByte seq,
-+ CKYAppletRespListKeys *lkp, CKYISOStatus *apduRC);
-+/*
-+ * Compute Crypt Cluster.
-+ *
-+ * Compute Crypt takes 3 phases: Init, Process, Final.
-+ * Applications can call each phase separately using:
-+ * CKYApplet_ComputeCryptInit
-+ * CKYApplet_ComputeCryptProcess
-+ * CKYApplet_ComputeCryptFinal
-+ * or call all three in one set with:
-+ * CKYApplet_ComputeCrypt
-+ * Buffer values passed to Compute crypt should be raw data.
-+ * The helper functions format the 2 byte length data required by the
-+ * applet automatically.
-+ */
-+CKYStatus CKYApplet_ComputeCryptInit(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte mode, CKYByte direction, CKYByte location,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_ComputeCryptProcess(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data, const CKYBuffer *nonce,
-+ CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_ComputeCryptFinal(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data, CKYBuffer *sig, CKYBuffer *result,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+/** ...look to data size to see if we should read/write the data to
-+ * the on card buffer. (future) */
-+CKYStatus CKYApplet_ComputeCrypt(CKYCardConnection *conn, CKYByte keyNumber,
-+ CKYByte mode, CKYByte direction, const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+/* Pin Command -- see applet documentation for use */
-+CKYStatus CKYApplet_CreatePIN(CKYCardConnection *conn, CKYByte pinNumber,
-+ CKYByte maxAttempts, const char *pinValue,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_VerifyPIN(CKYCardConnection *conn, CKYByte pinNumber,
-+ const char *pinValue, CKYBuffer *nonce, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_ChangePIN(CKYCardConnection *conn, const char *oldPin,
-+ const char *newPin, const CKYBuffer *nonce,
-+ CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_ListPINs(CKYCardConnection *conn, unsigned short *pins,
-+ CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_Logout(CKYCardConnection *conn, CKYByte pinNumber,
-+ const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+/* Object Commands -- see applet documentation for use */
-+CKYStatus CKYApplet_CreateObject(CKYCardConnection *conn, unsigned long objectID,
-+ CKYSize size, unsigned short readACL, unsigned short writeACL,
-+ unsigned short deleteACL, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_DeleteObject(CKYCardConnection *conn, unsigned long objectID,
-+ CKYByte zero, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-+/* CAC commands */
-+/* Select one of the CAC PKI applets. Special case of CKYApplet_SelectFile */
-+/* Select the CAC card manager. Can happen with either applet selected */
-+CKYStatus CACApplet_SelectCardManager(CKYCardConnection *conn,
-+ CKYISOStatus *apduRC);
-+/* Select the CAC CC container. Can happen with either applet selected */
-+CKYStatus CACApplet_SelectCCC(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+/* Select an old CAC applet and fill in the cardAID */
-+CKYStatus CACApplet_SelectPKI(CKYCardConnection *conn, CKYBuffer *cardAid,
-+ CKYByte instance, CKYISOStatus *apduRC);
-+/* read a TLV file */
-+CKYStatus CACApplet_ReadFile(CKYCardConnection *conn, CKYByte type,
-+ CKYBuffer *buffer, CKYISOStatus *apduRC);
-+CKYStatus CACApplet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+
-+
-+/* must happen with PKI applet selected */
-+CKYStatus CACApplet_SignDecrypt(CKYCardConnection *conn, const CKYBuffer *data,
-+ CKYBuffer *result, CKYISOStatus *apduRC);
-+CKYStatus CACApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert,
-+ CKYISOStatus *apduRC);
-+CKYStatus CACApplet_GetCertificateFirst(CKYCardConnection *conn,
-+ CKYBuffer *cert, CKYSize *nextSize,
-+ CKYISOStatus *apduRC);
-+CKYStatus CACApplet_GetCertificateAppend(CKYCardConnection *conn,
-+ CKYBuffer *cert, CKYSize nextSize,
-+ CKYISOStatus *apduRC);
-+
-+/*CKYStatus CACApplet_GetProperties(); */
-+CKYStatus CACApplet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ int local, CKYISOStatus *apduRC);
-+
-+/* Select a PIV applet */
-+CKYStatus PIVApplet_Select(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+
-+CKYStatus PIVApplet_GetCertificate(CKYCardConnection *conn, CKYBuffer *cert,
-+ int tag, CKYISOStatus *apduRC);
-+CKYStatus PIVApplet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, int derive,
-+ const CKYBuffer *data, CKYBuffer *result,
-+ CKYISOStatus *apduRC);
-+
-+/* PKCS Commands 15 */
-+CKYStatus P15Applet_SelectFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_SelectRootFile(CKYCardConnection *conn, unsigned short ef,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_ReadRecord(CKYCardConnection *conn, CKYByte record,
-+ CKYByte short_ef, CKYByte flags, CKYByte size, CKYBuffer *data,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_ReadBinary(CKYCardConnection *conn, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte size, CKYBuffer *data,
-+ CKYISOStatus *apduRC);
-+CKYStatus P15Applet_VerifyPIN(CKYCardConnection *conn, const char *pin,
-+ const P15PinInfo *pinInfo, CKYISOStatus *apduRC);
-+
-+CKYStatus P15Applet_SignDecrypt(CKYCardConnection *conn, CKYByte key,
-+ unsigned int keySize, CKYByte direction,
-+ const CKYBuffer *data, CKYBuffer *result,
-+ CKYISOStatus *apduRC);
-+
-+/*
-+ * There are 3 read commands:
-+ *
-+ * CKYApplet_ReadObject issues a single Read APDU call. Supplied data buffer
-+ * is overwritten. This function is limited to reading 240 bytes.
-+ * CKYApplet_ReadObjectAppend also issues a single Read APDU call. However,
-+ * the result is appended to the data buffer. Again, this function is limited
-+ * to reading 240 bytes.
-+ * CKYApplet_ReadObjectFull can read an entire data object. It makes multiple
-+ * apdu calls in order to read the full amount into the buffer. The buffer
-+ * is overwriten.
-+ */
-+CKYStatus CKYApplet_ReadObject(CKYCardConnection *conn, unsigned long objectID,
-+ CKYOffset offset, CKYByte size, const CKYBuffer *nonce,
-+ CKYBuffer *data, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_ReadObjectAppend(CKYCardConnection *conn,
-+ unsigned long objectID, CKYOffset offset, CKYByte size,
-+ const CKYBuffer *nonce, CKYBuffer *data, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_ReadObjectFull(CKYCardConnection *conn,
-+ unsigned long objectID, CKYOffset offset, CKYSize size,
-+ const CKYBuffer *nonce, CKYBuffer *data, CKYISOStatus *apduRC);
-+/*
-+ * There is 1 write command:
-+ * CKYApplet_WriteObjectFull can write an entire data object. It makes multiple
-+ * apdu calls in order to write the full amount into the buffer. The buffer is
-+ * overwritten.
-+*/
-+
-+CKYStatus CKYApplet_WriteObjectFull(CKYCardConnection *conn,
-+ unsigned long objectID, CKYOffset offset, CKYSize size,
-+ const CKYBuffer *nonce, const CKYBuffer *data, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_ListObjects(CKYCardConnection *conn, CKYByte seq,
-+ CKYAppletRespListObjects *lop, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_GetStatus(CKYCardConnection *conn,
-+ CKYAppletRespGetStatus *status, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_Noop(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_GetBuildID(CKYCardConnection *conn, unsigned long *buildID,
-+ CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_GetLifeCycle(CKYCardConnection *conn, CKYByte *personalized,
-+ CKYISOStatus *apduRC);
-+CKYStatus CKYApplet_GetLifeCycleV2(CKYCardConnection *conn,
-+ CKYAppletRespGetLifeCycleV2 *ext, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_GetRandom(CKYCardConnection *conn,
-+ CKYBuffer *buf, CKYByte len, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_GetRandomAppend(CKYCardConnection *conn,
-+ CKYBuffer *buf, CKYByte len, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_SeedRandom(CKYCardConnection *conn,
-+ const CKYBuffer *buf, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_GetIssuerInfo(CKYCardConnection *conn,
-+ CKYBuffer *buf, CKYISOStatus *apduRC);
-+
-+CKYStatus CKYApplet_GetBuiltinACL(CKYCardConnection *conn,
-+ CKYAppletRespGetBuiltinACL *gba, CKYISOStatus *apduRC);
-+
-+/** ECC commands
-+ * * */
-+
-+CKYStatus CKYApplet_ComputeECCSignature(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *data, CKYBuffer *sig,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-+CKYStatus
-+CKYApplet_ComputeECCKeyAgreement(CKYCardConnection *conn, CKYByte keyNumber,
-+ const CKYBuffer *publicValue, CKYBuffer *sharedSecret,
-+ CKYBuffer *result, const CKYBuffer *nonce, CKYISOStatus *apduRC);
-+
-+
-+/*
-+ * deprecates 0.x functions
-+ */
-+/* old applet verify pin call (no nonce returned) */
-+CKYStatus CKYApplet_VerifyPinV0(CKYCardConnection *conn, CKYByte pinNumber,
-+ const char *pinValue, CKYISOStatus *apduRC);
-+/* logout all */
-+CKYStatus CKYApplet_LogoutAllV0(CKYCardConnection *conn, CKYISOStatus *apduRC);
-+
-+CKY_END_PROTOS
-+#endif /* CKY_APPLET_H */
-diff -up ./esc/src/lib/coolkey/cky_base.c.fix1 ./esc/src/lib/coolkey/cky_base.c
---- ./esc/src/lib/coolkey/cky_base.c.fix1 2018-04-26 11:44:38.436986198 -0700
-+++ ./esc/src/lib/coolkey/cky_base.c 2018-04-26 11:44:38.436986198 -0700
-@@ -0,0 +1,835 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#include
-+#include
-+#include
-+#include "cky_basei.h"
-+#include "cky_base.h"
-+
-+/*
-+ * generic buffer management functions
-+ *
-+ * These functions allow simple buffer management used in the CoolKey
-+ * library and it's clients.
-+ */
-+
-+/* initialize a new buffer to a known state */
-+static void
-+ckyBuffer_initBuffer(CKYBuffer *buf)
-+{
-+#ifdef DEBUG
-+ assert(sizeof(CKYBuffer) == sizeof(CKYBufferPublic));
-+#endif
-+ buf->data = NULL;
-+ buf->size = 0;
-+ buf->len = 0;
-+ buf->reserved = NULL; /* make coverity happy */
-+}
-+
-+/*
-+ * Init functions clobbers the current contents and allocates the required
-+ * space. Active buffers should call CKYBuffer_FreerData before
-+ * calling an init function. All init functions copies the supplied data
-+ * into newly allocated space.
-+ */
-+/* init an empty buffer that will later be filled in. */
-+CKYStatus
-+CKYBuffer_InitEmpty(CKYBuffer *buf)
-+{
-+ ckyBuffer_initBuffer(buf);
-+ return CKYSUCCESS;
-+}
-+
-+/* Create a buffer of length len all initialized to '0' */
-+CKYStatus
-+CKYBuffer_InitFromLen(CKYBuffer *buf, CKYSize len)
-+{
-+ CKYStatus ret;
-+
-+ ckyBuffer_initBuffer(buf);
-+ ret = CKYBuffer_Reserve(buf, len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->len = len;
-+ memset(buf->data, 0, buf->len);
-+ return CKYSUCCESS;
-+}
-+
-+static CKYByte
-+fromHex(const char *cp)
-+{
-+ if (*cp >= '0' && *cp <= '9') {
-+ return (CKYByte) *cp - '0';
-+ }
-+ if (*cp >= 'a' && *cp <= 'f') {
-+ return (CKYByte) *cp - 'a' + 0xa;
-+ }
-+ if (*cp >= 'A' && *cp <= 'F') {
-+ return (CKYByte) *cp - 'A' + 0xA;
-+ }
-+ return 0;
-+}
-+
-+/* Create a buffer by decoding a hex string. hexString is NULL terminated. */
-+CKYStatus
-+CKYBuffer_InitFromHex(CKYBuffer *buf, const char *hexString)
-+{
-+ int len = strlen(hexString);
-+ int dataHalf = 0;
-+ CKYByte lastDigit = 0;
-+ CKYByte digit;
-+ const char *cp;
-+ CKYByte *bp;
-+ CKYStatus ret;
-+
-+ if (len & 1) {
-+ len++;
-+ dataHalf++;
-+ }
-+ ckyBuffer_initBuffer(buf);
-+ ret = CKYBuffer_Reserve(buf, len/2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->len = len/2;
-+ bp = buf->data;
-+ for (cp = hexString; *cp; cp++) {
-+ digit = fromHex(cp);
-+ /* check for error? */
-+ if (dataHalf) {
-+ *bp++= lastDigit << 4 | digit;
-+ }
-+ dataHalf ^= 1;
-+ lastDigit = digit;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+/* Create a buffer from data */
-+CKYStatus
-+CKYBuffer_InitFromData(CKYBuffer *buf, const CKYByte *data, CKYSize len)
-+{
-+ CKYStatus ret;
-+
-+ ckyBuffer_initBuffer(buf);
-+ ret = CKYBuffer_Reserve(buf, len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->len = len;
-+ memcpy(buf->data, data, buf->len);
-+ return CKYSUCCESS;
-+}
-+
-+
-+/* Create a buffer from part of another buffer. Start indicates the
-+ * offset in the old buffer to start in, and len specifies how many bytes
-+ * to copy */
-+CKYStatus
-+CKYBuffer_InitFromBuffer(CKYBuffer *buf,
-+ const CKYBuffer *src, CKYOffset start, CKYSize len)
-+{
-+ CKYStatus ret;
-+
-+ ckyBuffer_initBuffer(buf);
-+ if (src->len < start) {
-+ len = 0;
-+ } else if (src->len < start+len) {
-+ len = src->len -start;
-+ }
-+ ret = CKYBuffer_Reserve(buf, len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->len = len;
-+ if (len == 0) {
-+ return CKYSUCCESS;
-+ }
-+ memcpy(buf->data, src->data+start, buf->len);
-+ return CKYSUCCESS;
-+}
-+
-+/* Create a buffer from and exact copy of another buffer. */
-+CKYStatus
-+CKYBuffer_InitFromCopy(CKYBuffer *buf, const CKYBuffer *src)
-+{
-+ CKYStatus ret;
-+
-+ ckyBuffer_initBuffer(buf);
-+ /* src buffer has no length, make sure the dest is empty */
-+ if (src->len == 0) {
-+ return CKYSUCCESS;
-+ }
-+ ret = CKYBuffer_Reserve(buf, src->len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->len = src->len;
-+ memcpy(buf->data, src->data, buf->len);
-+ return CKYSUCCESS;
-+}
-+
-+/*
-+ * append functions increase the buffer size if necessary
-+ */
-+CKYStatus
-+CKYBuffer_AppendChar(CKYBuffer *buf, CKYByte val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 1);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len] = val;
-+ buf->len += 1;
-+ return CKYSUCCESS;
-+}
-+
-+/* append a short in network order */
-+CKYStatus
-+CKYBuffer_AppendShort(CKYBuffer *buf, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 2;
-+ return CKYSUCCESS;
-+}
-+
-+/* append a short in network order */
-+CKYStatus
-+CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 2;
-+ return CKYSUCCESS;
-+}
-+
-+/* append a long in applet order */
-+CKYStatus
-+CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[buf->len+2] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+3] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 4;
-+ return CKYSUCCESS;
-+}
-+
-+/* append a long in applet order */
-+CKYStatus
-+CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + 4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ buf->data[buf->len+3] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[buf->len+2] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[buf->len+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[buf->len+0] = (CKYByte) ((val >> 0) & 0xff);
-+ buf->len += 4;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_Replace(CKYBuffer *buf, CKYOffset offset, const CKYByte *data, CKYSize len)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, offset+len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ if (buf->len < offset + len) {
-+ buf->len = offset + len;
-+ }
-+ memcpy(buf->data+offset, data, len);
-+ return CKYSUCCESS;
-+}
-+
-+/* append data with length of len bytes */
-+CKYStatus
-+CKYBuffer_AppendData(CKYBuffer *buf, const CKYByte *data, CKYSize len)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Reserve(buf, buf->len + len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ memcpy(buf->data+buf->len, data, len);
-+ buf->len += len;
-+ return CKYSUCCESS;
-+}
-+
-+/* append data with length of len bytes */
-+CKYStatus
-+CKYBuffer_AppendBuffer(CKYBuffer *buf, const CKYBuffer *src,
-+ CKYOffset offset, CKYSize len)
-+{
-+ unsigned long maxlen = src->len - offset;
-+ if ((maxlen < len) || (src->len < offset)) {
-+ return CKYDATATOOLONG;
-+ }
-+ return CKYBuffer_AppendData(buf, src->data+offset, len);
-+}
-+
-+/* append data with length of len bytes */
-+CKYStatus
-+CKYBuffer_AppendCopy(CKYBuffer *buf, const CKYBuffer *src)
-+{
-+ return CKYBuffer_AppendData(buf, src->data, src->len);
-+}
-+
-+CKYStatus
-+CKYBuffer_Reserve(CKYBuffer *buf, CKYSize newSize)
-+{
-+ if (buf->size >= newSize) {
-+ return CKYSUCCESS;
-+ }
-+ buf->data = (CKYByte *)realloc(buf->data, newSize);
-+ if (buf->data == NULL) {
-+ buf->size = 0;
-+ buf->len = 0;
-+ return CKYNOMEM;
-+ }
-+ buf->size = newSize;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_SetChar(CKYBuffer *buf, CKYOffset offset, CKYByte val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+1) {
-+ ret = CKYBuffer_Resize(buf,offset+1);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset] = val;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_SetChars(CKYBuffer *buf, CKYOffset offset, CKYByte val, CKYSize len)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+len) {
-+ ret = CKYBuffer_Resize(buf,offset+len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ memset(buf->data+offset,val, len);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_SetShort(CKYBuffer *buf, CKYOffset offset, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+2) {
-+ ret = CKYBuffer_Resize(buf,offset+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+0] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+1] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+2) {
-+ ret = CKYBuffer_Resize(buf,offset+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+4) {
-+ ret = CKYBuffer_Resize(buf,offset+4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+0] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[offset+1] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[offset+2] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+3] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < offset+4) {
-+ ret = CKYBuffer_Resize(buf,offset+4);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ buf->data[offset+3] = (CKYByte) ((val >> 24) & 0xff);
-+ buf->data[offset+2] = (CKYByte) ((val >> 16) & 0xff);
-+ buf->data[offset+1] = (CKYByte) ((val >> 8) & 0xff);
-+ buf->data[offset+0] = (CKYByte) ((val >> 0) & 0xff);
-+ return CKYSUCCESS;
-+}
-+
-+CKYByte
-+CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ if (buf->len < offset+1) {
-+ return 0;
-+ }
-+ return buf->data[offset];
-+}
-+
-+unsigned short
-+CKYBuffer_GetShort(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned short val;
-+ if (buf->len < offset+2) {
-+ return 0;
-+ }
-+ val = ((unsigned short)buf->data[offset+0]) << 8;
-+ val |= ((unsigned short)buf->data[offset+1]) << 0;
-+ return val;
-+}
-+
-+unsigned short
-+CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned short val;
-+ if (buf->len < offset+2) {
-+ return 0;
-+ }
-+ val = ((unsigned short)buf->data[offset+1]) << 8;
-+ val |= ((unsigned short)buf->data[offset+0]) << 0;
-+ return val;
-+}
-+
-+unsigned long
-+CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned long val;
-+ if (buf->len < offset+4) {
-+ return 0;
-+ }
-+ val = ((unsigned long)buf->data[offset+0]) << 24;
-+ val |= ((unsigned long)buf->data[offset+1]) << 16;
-+ val |= ((unsigned long)buf->data[offset+2]) << 8;
-+ val |= ((unsigned long)buf->data[offset+3]) << 0;
-+ return val;
-+}
-+
-+unsigned long
-+CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset)
-+{
-+ unsigned long val;
-+ if (buf->len < offset+4) {
-+ return 0;
-+ }
-+ val = ((unsigned long)buf->data[offset+3]) << 24;
-+ val |= ((unsigned long)buf->data[offset+2]) << 16;
-+ val |= ((unsigned long)buf->data[offset+1]) << 8;
-+ val |= ((unsigned long)buf->data[offset+0]) << 0;
-+ return val;
-+}
-+
-+CKYStatus
-+CKYBuffer_Resize(CKYBuffer *buf, CKYSize newLen)
-+{
-+ CKYStatus ret;
-+
-+ if (buf->len < newLen) {
-+ ret = CKYBuffer_Reserve(buf, newLen);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ memset(buf->data+buf->len, 0, newLen - buf->len);
-+ }
-+ buf->len = newLen;
-+ return CKYSUCCESS;
-+}
-+
-+/* clear out a memory buffer... including unallocated space, then
-+ * set the buffer length to '0' */
-+void
-+CKYBuffer_Zero(CKYBuffer *buf)
-+{
-+ if (buf->size != 0) {
-+ memset(buf->data, 0, buf->size);
-+ }
-+ buf->len = 0;;
-+}
-+
-+CKYSize
-+CKYBuffer_Size(const CKYBuffer *buf)
-+{
-+ return buf->len;
-+}
-+
-+const CKYByte *
-+CKYBuffer_Data(const CKYBuffer *buf)
-+{
-+ return buf->data;
-+}
-+
-+CKYBool
-+CKYBuffer_DataIsEqual(const CKYBuffer *buf1, const CKYByte *buf2, CKYSize buf2Len)
-+{
-+ if (buf1->len != buf2Len) {
-+ return 0;
-+ }
-+
-+ /* all zero length buffers are equal, whether or not they have pointers
-+ * allocated */
-+ if (buf1->len == 0) {
-+ return 1;
-+ }
-+
-+ return memcmp(buf1->data, buf2, buf1->len) == 0;
-+}
-+
-+CKYBool
-+CKYBuffer_IsEqual(const CKYBuffer *buf1, const CKYBuffer *buf2)
-+{
-+ return CKYBuffer_DataIsEqual(buf1, buf2->data, buf2->len);
-+}
-+
-+CKYStatus
-+CKYBuffer_FreeData(CKYBuffer *buf)
-+{
-+ free(buf->data);
-+ ckyBuffer_initBuffer(buf);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYAPDU_Init(CKYAPDU *apdu)
-+{
-+#ifdef DEBUG
-+ assert(sizeof(CKYAPDU) == sizeof(CKYAPDUPublic));
-+#endif
-+ ckyBuffer_initBuffer(&apdu->apduBuf);
-+ apdu->reserved = NULL;
-+ return CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_MIN_LEN);
-+}
-+
-+CKYStatus
-+CKYAPDU_InitFromData(CKYAPDU *apdu, const CKYByte *data, CKYSize len)
-+{
-+#ifdef DEBUG
-+ assert(sizeof(CKYAPDU) == sizeof(CKYAPDUPublic));
-+#endif
-+ ckyBuffer_initBuffer(&apdu->apduBuf);
-+ apdu->reserved = NULL;
-+ if (len > CKYAPDU_MAX_DATA_LEN) {
-+ return CKYDATATOOLONG;
-+ }
-+ return CKYBuffer_InitFromData(&apdu->apduBuf, data, len);
-+}
-+
-+CKYStatus
-+CKYAPDU_FreeData(CKYAPDU *apdu)
-+{
-+ return CKYBuffer_FreeData(&apdu->apduBuf);
-+}
-+
-+
-+CKYByte
-+CKYAPDU_GetCLA(const CKYAPDU *apdu)
-+{
-+ return CKYBuffer_GetChar(&apdu->apduBuf, CKY_CLA_OFFSET);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetCLA(CKYAPDU *apdu, CKYByte b)
-+{
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_CLA_OFFSET, b);
-+}
-+
-+CKYByte
-+CKYAPDU_GetINS(const CKYAPDU *apdu)
-+{
-+ return CKYBuffer_GetChar(&apdu->apduBuf, CKY_INS_OFFSET);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetINS(CKYAPDU *apdu, CKYByte b)
-+{
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_INS_OFFSET, b);
-+}
-+
-+CKYByte
-+CKYAPDU_GetP1(const CKYAPDU *apdu)
-+{
-+ return CKYBuffer_GetChar(&apdu->apduBuf, CKY_P1_OFFSET);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetP1(CKYAPDU *apdu, CKYByte b)
-+{
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_P1_OFFSET, b);
-+}
-+
-+CKYByte
-+CKYAPDU_GetP2(const CKYAPDU *apdu)
-+{
-+ return CKYBuffer_GetChar(&apdu->apduBuf, CKY_P2_OFFSET);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetP2(CKYAPDU *apdu, CKYByte b)
-+{
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_P2_OFFSET, b);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetSendData(CKYAPDU *apdu, const CKYByte *data, CKYSize len)
-+{
-+ CKYStatus ret;
-+ CKYOffset offset = 0;
-+
-+ /* Encode with T1 if necessary */
-+
-+ if (len < CKYAPDU_MAX_DATA_LEN) {
-+ offset = 0;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, len+offset+CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS ) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) len);
-+ } else if (len < CKYAPDU_MAX_T1_DATA_LEN) {
-+ offset = 2;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, len+offset+CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS ) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) 0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetShort(&apdu->apduBuf,CKY_LC_OFFSET+1,
-+ (unsigned short)len);
-+ } else {
-+ return CKYDATATOOLONG;
-+ }
-+
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_Replace(&apdu->apduBuf,
-+ CKYAPDU_HEADER_LEN + offset , data, len);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetSendDataBuffer(CKYAPDU *apdu, const CKYBuffer *buf)
-+{
-+ return CKYAPDU_SetSendData(apdu, buf->data, buf->len);
-+}
-+
-+CKYStatus
-+CKYAPDU_AppendSendData(CKYAPDU *apdu, const CKYByte *data, CKYSize len)
-+{
-+ CKYStatus ret;
-+ CKYSize dataLen;
-+
-+ if (CKYBuffer_Size(&apdu->apduBuf) <= CKYAPDU_MIN_LEN) {
-+ return CKYAPDU_SetSendData(apdu,data, len);
-+ }
-+
-+ dataLen = CKYBuffer_Size(&apdu->apduBuf) + len - CKYAPDU_HEADER_LEN;
-+ /* only handles T0 encoding, not T1 encoding */
-+ if (dataLen >= CKYAPDU_MAX_DATA_LEN) {
-+ return CKYDATATOOLONG;
-+ }
-+ ret = CKYBuffer_AppendData(&apdu->apduBuf, data, len);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LC_OFFSET, (CKYByte) dataLen);
-+}
-+
-+CKYStatus
-+CKYAPDU_AppendSendDataBuffer(CKYAPDU *apdu, const CKYBuffer *buf)
-+{
-+ return CKYAPDU_AppendSendData(apdu, buf->data, buf->len);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetReceiveLen(CKYAPDU *apdu, CKYByte recvlen)
-+{
-+ CKYStatus ret;
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_HEADER_LEN);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_SetChar(&apdu->apduBuf, CKY_LE_OFFSET, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen)
-+{
-+ CKYStatus ret;
-+
-+ if (recvlen <= CKYAPDU_MAX_DATA_LEN) {
-+ return CKYAPDU_SetReceiveLen(apdu, (CKYByte)(recvlen & 0xff));
-+ }
-+ ret = CKYBuffer_Resize(&apdu->apduBuf, CKYAPDU_HEADER_LEN+2);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ ret = CKYBuffer_SetChar(&apdu->apduBuf, CKY_LE_OFFSET, 0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_SetShort(&apdu->apduBuf, CKY_LE_OFFSET+1, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_SetReceiveLength(CKYAPDU *apdu, CKYSize recvlen)
-+{
-+ if (recvlen <= CKYAPDU_MAX_T1_DATA_LEN) {
-+ return CKYAPDU_SetShortReceiveLen(apdu, (unsigned short)
-+ (recvlen & 0xffff));
-+ }
-+ return CKYDATATOOLONG;
-+}
-+
-+/*
-+ * Append Le, If Le=0, treat it as 256 (CKYAPD_MAX_DATA_LEN)
-+ */
-+CKYStatus
-+CKYAPDU_AppendReceiveLen(CKYAPDU *apdu, CKYByte recvlen)
-+{
-+ /* If we already have a data buffer, make sure that we aren't already
-+ * using T1 encoding */
-+ if (CKYBuffer_Size(&apdu->apduBuf) > CKYAPDU_MIN_LEN) {
-+ if (CKYBuffer_GetChar(&apdu->apduBuf, CKY_LC_OFFSET) == 0) {
-+ /* we are using T1 encoding, use AppendShort*/
-+ return CKYBuffer_AppendShort(&apdu->apduBuf,
-+ recvlen ? (unsigned short) recvlen: CKYAPDU_MAX_DATA_LEN);
-+ }
-+ }
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, recvlen);
-+}
-+
-+/*
-+ * Append a short Le. If Le be encoded with just T0, do so. If Le=0 treat
-+ * it as 65536 (CKYAPDU_MAX_T1_DATA_LEN)
-+ */
-+CKYStatus
-+CKYAPDU_AppendShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen)
-+{
-+ CKYStatus ret;
-+ /* If we already have a data buffer, it's encoding affects ours */
-+ if (CKYBuffer_Size(&apdu->apduBuf) > CKYAPDU_MIN_LEN) {
-+ /* CKY_LC_OFFSET == 0 means T1, otherwise it's T0 */
-+ if (CKYBuffer_GetChar(&apdu->apduBuf, CKY_LC_OFFSET) != 0) {
-+ /* remember 0 is 65536 here */
-+ if ((recvlen == 0) || (recvlen > CKYAPDU_MAX_DATA_LEN)) {
-+ /* we can't a encode T1 receive length if we already have a
-+ * T0 encoded buffer data */
-+ return CKYDATATOOLONG;
-+ }
-+ /* T0 encoding */
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)recvlen&0xff);
-+ }
-+ /* T1 encoding */
-+ return CKYBuffer_AppendShort(&apdu->apduBuf, recvlen);
-+ }
-+ /* if length fits in a bit and we aren't forced into T1 encoding, use
-+ * T0 */
-+ if ((recvlen != 0) && (recvlen <= CKYAPDU_MAX_DATA_LEN)) {
-+ return CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)recvlen&0xff);
-+ }
-+ /* write the T1 encoding marker */
-+ ret = CKYBuffer_AppendChar(&apdu->apduBuf, (CKYByte)0);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ /* T1 encoded length */
-+ return CKYBuffer_AppendShort(&apdu->apduBuf, recvlen);
-+}
-+
-+CKYStatus
-+CKYAPDU_AppendReceiveLength(CKYAPDU *apdu, CKYSize recvlen)
-+{
-+ if (recvlen > CKYAPDU_MAX_T1_DATA_LEN) {
-+ return CKYDATATOOLONG;
-+ }
-+ return CKYAPDU_AppendShortReceiveLen(apdu,
-+ (unsigned short)(recvlen & 0xffff));
-+}
-+
-+
-+void
-+CKY_SetName(const char *p)
-+{
-+}
-+
-+
-+
-+
-diff -up ./esc/src/lib/coolkey/cky_base.h.fix1 ./esc/src/lib/coolkey/cky_base.h
---- ./esc/src/lib/coolkey/cky_base.h.fix1 2018-04-26 11:44:38.437986192 -0700
-+++ ./esc/src/lib/coolkey/cky_base.h 2018-04-26 11:44:38.437986192 -0700
-@@ -0,0 +1,340 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_BASE_H
-+#define CKY_BASE_H 1
-+
-+/*
-+ * Common types and structs
-+ */
-+/* buffer sizes */
-+typedef unsigned long CKYSize;
-+/* offsets into buffers are data */
-+typedef unsigned long CKYOffset;
-+/* bytes, buffers */
-+typedef unsigned char CKYByte;
-+/* Bool type */
-+typedef unsigned char CKYBool;
-+
-+typedef unsigned long CKYBitFlags;
-+
-+#define CKYBUFFER_PUBLIC \
-+ unsigned long reserved1;\
-+ unsigned long reserved2;\
-+ void *reserved3;\
-+ void *reserved4;
-+
-+#define CKYAPDU_PUBLIC \
-+ unsigned long reserved1;\
-+ unsigned long reserved2;\
-+ void *reserved3;\
-+ void *reserved4; \
-+ void *reserved5;
-+
-+
-+typedef struct _CKYBuffer {
-+#ifdef CKYBUFFER_PRIVATE
-+ CKYBUFFER_PRIVATE
-+#else
-+ CKYBUFFER_PUBLIC
-+#endif
-+} CKYBuffer;
-+
-+typedef struct _CKYAPDU {
-+#ifdef CKYAPDU_PRIVATE
-+ CKYAPDU_PRIVATE
-+#else
-+ CKYAPDU_PUBLIC
-+#endif
-+} CKYAPDU;
-+
-+/*
-+ * the following is just to make sure the sizes match
-+ */
-+#ifdef DEBUG
-+#ifdef CKYBUFFER_PRIVATE
-+typedef struct _CKYBufferPublic {
-+ CKYBUFFER_PUBLIC
-+} CKYBufferPublic;
-+
-+typedef struct _CKYAPDUPublic {
-+ CKYAPDU_PUBLIC
-+} CKYAPDUPublic;
-+#endif
-+#endif
-+
-+typedef enum {
-+ CKYSUCCESS, /* operation completed successfully */
-+ CKYNOMEM, /* failed to allocate memory */
-+ CKYDATATOOLONG, /* index or length exceeded a buffer or device size */
-+ CKYNOSCARD, /* Scard library does not exist */
-+ CKYSCARDERR, /* I/O Error in the SCard interface level. */
-+ /* more specific error values can be queried from
-+ * the context or connection with the
-+ * GetLastError() call */
-+ CKYLIBFAIL, /* error is shared library. no additional
-+ * error is available. Only returned from internal
-+ * SHlib calls (not surfaced in public APIs */
-+ CKYAPDUFAIL, /* processing worked, but applet rejected the APDU
-+ * (command) sent. ADPUIOStatus has more info on
-+ * why the APDU failed */
-+ CKYINVALIDARGS, /* Caller passed in bad args */
-+ CKYINVALIDDATA, /* Data supplied was invalid */
-+ CKYUNSUPPORTED, /* Requested Operation or feature is not supported */
-+} CKYStatus;
-+
-+/*
-+ * defines related to APDU's
-+ */
-+#define CKY_CLA_OFFSET 0
-+#define CKY_INS_OFFSET 1
-+#define CKY_P1_OFFSET 2
-+#define CKY_P2_OFFSET 3
-+#define CKY_P3_OFFSET 4 /* P3 is P3, LC, and LE depending on usage */
-+#define CKY_LC_OFFSET 4
-+#define CKY_LE_OFFSET 4
-+
-+#define CKYAPDU_MAX_DATA_LEN 256
-+#define CKYAPDU_MAX_T1_DATA_LEN 65536
-+#define CKYAPDU_MIN_LEN 4
-+#define CKYAPDU_HEADER_LEN 5
-+#define CKYAPDU_MAX_LEN (CKYAPDU_HEADER_LEN+CKYAPDU_MAX_DATA_LEN)
-+#define CKY_MAX_ATR_LEN 32
-+#define CKY_OUTRAGEOUS_MALLOC_SIZE (1024*1024)
-+
-+#define P15FlagsPrivate 0x00000001
-+#define P15FlagsModifiable 0x00000002
-+
-+#define P15UsageEncrypt 0x00000001
-+#define P15UsageDecrypt 0x00000002
-+#define P15UsageSign 0x00000004
-+#define P15UsageSignRecover 0x00000008
-+#define P15UsageWrap 0x00000010
-+#define P15UsageUnwrap 0x00000020
-+#define P15UsageVerify 0x00000040
-+#define P15UsageVerifyRecover 0x00000080
-+#define P15UsageDerive 0x00000100
-+#define P15UsageNonRepudiation 0x00000200
-+
-+#define P15AccessSensitive 0x00000001
-+#define P15AccessExtractable 0x00000002
-+#define P15AccessAlwaysSenstive 0x00000004
-+#define P15AccessNeverExtractable 0x00000008
-+#define P15AccessLocal 0x00000010
-+
-+#define P15PinCaseSensitive 0x00000001
-+#define P15PinLocal 0x00000002
-+#define P15PinChangeDisabled 0x00000004
-+#define P15PinUnblockDisabled 0x00000008
-+#define P15PinInitialized 0x00000010
-+#define P15PinNeedsPadding 0x00000020
-+#define P15PinUnblockingPin 0x00000040
-+#define P15PinSOPin 0x00000080
-+#define P15PinDisableAllowed 0x00000100
-+
-+typedef enum {P15PinBCD=0, P15PinASCIINum=1, P15PinUTF8=2} P15PinType;
-+
-+typedef struct _P15PinInfo {
-+ CKYBitFlags pinFlags;
-+ P15PinType pinType;
-+ CKYByte minLength;
-+ CKYByte storedLength;
-+ unsigned long maxLength;
-+ CKYByte pinRef;
-+ CKYByte padChar;
-+} P15PinInfo;
-+
-+
-+/*
-+ * allow direct inclusion in C++ files
-+ */
-+#ifdef __cplusplus
-+#define CKY_BEGIN_PROTOS extern "C" {
-+#define CKY_END_PROTOS }
-+#else
-+#define CKY_BEGIN_PROTOS
-+#define CKY_END_PROTOS
-+#endif
-+
-+CKY_BEGIN_PROTOS
-+/*
-+ * generic buffer management functions
-+ *
-+ * These functions allow simple buffer management used in the CoolKey
-+ * library and it's clients.
-+ */
-+
-+/*
-+ * Init functions clobbers the current contents and allocates the required
-+ * space.
-+ * - Active buffers should call CKYBuffer_FreeData before calling an init
-+ * function.
-+ * - New buffers should call some CKYBuffer_Init function before any use.
-+ * - All init functions copies the supplied data into newly allocated space.
-+ */
-+/* Create an empty buffer with no memory allocated to it. This is sufficient
-+ * to begin using a buffer. Note that new calls will probably allocate memory.
-+ * It is safe to free an empty buffer. */
-+CKYStatus CKYBuffer_InitEmpty(CKYBuffer *buf);
-+
-+/* Create a buffer of length len all initialized to '0' */
-+CKYStatus CKYBuffer_InitFromLen(CKYBuffer *buf, CKYSize len);
-+
-+/* Create a buffer by decoding a hex string. hexString is NULL terminated. */
-+CKYStatus CKYBuffer_InitFromHex(CKYBuffer *buf, const char *hexString);
-+
-+/* Create a buffer from data */
-+CKYStatus CKYBuffer_InitFromData(CKYBuffer *buf, const CKYByte *data, CKYSize len);
-+
-+/* Create a buffer from part of another buffer. Start indicates the
-+ * offset in the old buffer to start in, and len specifies how many bytes
-+ * to copy */
-+CKYStatus CKYBuffer_InitFromBuffer(CKYBuffer *buf, const CKYBuffer *src,
-+ CKYOffset start, CKYSize len);
-+/* Create a buffer from an exact copy of another buffer */
-+CKYStatus CKYBuffer_InitFromCopy(CKYBuffer *buf, const CKYBuffer *src);
-+/*
-+ * append functions increase the buffer size if necessary
-+ */
-+/* append a short in applet order */
-+CKYStatus CKYBuffer_AppendChar(CKYBuffer *buf, CKYByte b);
-+
-+/* append a short in applet order */
-+CKYStatus CKYBuffer_AppendShort(CKYBuffer *buf, unsigned short val);
-+
-+/* append a short in little endian order */
-+CKYStatus CKYBuffer_AppendShortLE(CKYBuffer *buf, unsigned short val);
-+
-+/* append a long in applet order */
-+CKYStatus CKYBuffer_AppendLong(CKYBuffer *buf, unsigned long val);
-+
-+/* append a long in little endian order */
-+CKYStatus CKYBuffer_AppendLongLE(CKYBuffer *buf, unsigned long val);
-+
-+/* append data. the data starts at data and extends len bytes */
-+CKYStatus CKYBuffer_AppendData(CKYBuffer *buf, const CKYByte *data, CKYSize len);
-+
-+/* append buffer fragment. the data starts at buffer[offset]
-+ * and extends len bytes */
-+CKYStatus CKYBuffer_AppendBuffer(CKYBuffer *buf, const CKYBuffer *src,
-+ CKYOffset offset, CKYSize len);
-+
-+/* append a full buffer */
-+CKYStatus CKYBuffer_AppendCopy(CKYBuffer *buf, const CKYBuffer *src );
-+
-+/* reserve increases the space allocated for the buffer, but does not
-+ * increase the actual buffer size. If the buffer already newSize or more
-+ * space allocated, Reserve is a no op.
-+ */
-+CKYStatus CKYBuffer_Reserve(CKYBuffer *buf, CKYSize newSize) ;
-+
-+/* resize affects the buffer's size. If the buffer len increases,
-+ * the new date will be zero'ed out. If the buffer shrinks, the buffer
-+ * is truncated, but the space is not removed.
-+ */
-+CKYStatus CKYBuffer_Resize(CKYBuffer *buf, CKYSize newLen);
-+
-+/* replace bytes starting at 'offset'. If the buffer needs to be extended,
-+ * it will be automatically */
-+CKYStatus CKYBuffer_Replace(CKYBuffer *buf, CKYOffset offset, const CKYByte *data,
-+ CKYSize len);
-+
-+/* set byte at ofset. The buffer is extended to offset if necessary */
-+CKYStatus CKYBuffer_SetChar(CKYBuffer *buf, CKYOffset offset, CKYByte c);
-+/* set several copies of 'c' at from offset to offset+ len */
-+CKYStatus CKYBuffer_SetChars(CKYBuffer *buf, CKYOffset offset,
-+ CKYByte c, CKYSize len);
-+/* These functions work in applet order */
-+CKYStatus CKYBuffer_SetShort(CKYBuffer *buf, CKYOffset offset, unsigned short val);
-+CKYStatus CKYBuffer_SetLong(CKYBuffer *buf, CKYOffset offset, unsigned long val);
-+
-+/* These functions work in little endian order */
-+CKYStatus CKYBuffer_SetShortLE(CKYBuffer *buf, CKYOffset offset, unsigned short val);
-+CKYStatus CKYBuffer_SetLongLE(CKYBuffer *buf, CKYOffset offset, unsigned long val);
-+/* read a character from offset. If offset is beyond the end of the buffer,
-+ * then the function returns '0' */
-+CKYByte CKYBuffer_GetChar(const CKYBuffer *buf, CKYOffset offset);
-+/* These functions work in applet order */
-+unsigned short CKYBuffer_GetShort(const CKYBuffer *buf, CKYOffset offset);
-+unsigned long CKYBuffer_GetLong(const CKYBuffer *buf, CKYOffset offset);
-+/* These functions work in little endian order */
-+unsigned short CKYBuffer_GetShortLE(const CKYBuffer *buf, CKYOffset offset);
-+unsigned long CKYBuffer_GetLongLE(const CKYBuffer *buf, CKYOffset offset);
-+
-+/* clear out all the data in a buffer */
-+void CKYBuffer_Zero(CKYBuffer *buf);
-+
-+/* return the size (length) of a buffer. This is only the portion of the
-+ * buffer that has valid data set. */
-+CKYSize CKYBuffer_Size(const CKYBuffer *buf);
-+
-+/* return a pointer to the data buffer */
-+const CKYByte *CKYBuffer_Data(const CKYBuffer *buf);
-+
-+/* compare two buffers return :
-+ * 1 if the two buffers are equal,
-+ * 0 if they are not */
-+CKYBool CKYBuffer_IsEqual(const CKYBuffer *buf1, const CKYBuffer *buf2);
-+/* compares raw data with a buffer or equality */
-+CKYBool CKYBuffer_DataIsEqual(const CKYBuffer *buf1,
-+ const CKYByte *buf2, CKYSize buf2Len);
-+
-+/* free all the data associated with a buffer and initialize the buffer */
-+CKYStatus CKYBuffer_FreeData(CKYBuffer *buf);
-+
-+/*
-+ * APDU's are buffers that know about the APDU structure
-+ */
-+CKYStatus CKYAPDU_Init(CKYAPDU *apdu);
-+CKYStatus CKYAPDU_InitFromData(CKYAPDU *apdu, const CKYByte *data, CKYSize size);
-+CKYStatus CKYAPDU_FreeData(CKYAPDU *apdu);
-+
-+/* Access APDU header bytes */
-+CKYByte CKYAPDU_GetCLA(const CKYAPDU *apdu);
-+CKYStatus CKYAPDU_SetCLA(CKYAPDU *apdu, CKYByte b);
-+CKYByte CKYAPDU_GetINS(const CKYAPDU *apdu);
-+CKYStatus CKYAPDU_SetINS(CKYAPDU *apdu, CKYByte b);
-+CKYByte CKYAPDU_GetP1(const CKYAPDU *apdu);
-+CKYStatus CKYAPDU_SetP1(CKYAPDU *apdu, CKYByte b);
-+CKYByte CKYAPDU_GetP2(const CKYAPDU *apdu);
-+CKYStatus CKYAPDU_SetP2(CKYAPDU *apdu, CKYByte b);
-+
-+/* add sending date to the APDU */
-+/* Set resets the buffer, append, adds the data to the end. Lc in
-+ * the APDU header is automaticallu updated */
-+CKYStatus CKYAPDU_SetSendData(CKYAPDU *apdu, const CKYByte *data, CKYSize len);
-+CKYStatus CKYAPDU_SetSendDataBuffer(CKYAPDU *apdu, const CKYBuffer *buf);
-+CKYStatus CKYAPDU_AppendSendData(CKYAPDU *apdu, const CKYByte *data, CKYSize len);
-+CKYStatus CKYAPDU_AppendSendDataBuffer(CKYAPDU *apdu, const CKYBuffer *buf);
-+
-+/* set Le in the APDU header to the amount of bytes expected to be
-+ * returned. */
-+CKYStatus CKYAPDU_SetReceiveLen(CKYAPDU *apdu, CKYByte recvlen);
-+CKYStatus CKYAPDU_SetShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen);
-+CKYStatus CKYAPDU_SetReceiveLength(CKYAPDU *apdu, CKYSize recvlen);
-+CKYStatus CKYAPDU_AppendReceiveLen(CKYAPDU *apdu, CKYByte recvlen);
-+CKYStatus CKYAPDU_AppendShortReceiveLen(CKYAPDU *apdu, unsigned short recvlen);
-+CKYStatus CKYAPDU_AppendReceiveLength(CKYAPDU *apdu, CKYSize recvlen);
-+
-+/* set the parent loadmodule name */
-+void CKY_SetName(const char *name);
-+
-+CKY_END_PROTOS
-+
-+#endif /* CKY_BASE_H */
-diff -up ./esc/src/lib/coolkey/cky_basei.h.fix1 ./esc/src/lib/coolkey/cky_basei.h
---- ./esc/src/lib/coolkey/cky_basei.h.fix1 2018-04-26 11:44:38.437986192 -0700
-+++ ./esc/src/lib/coolkey/cky_basei.h 2018-04-26 11:44:38.437986192 -0700
-@@ -0,0 +1,35 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_BASE_H
-+#ifndef CKY_BASEI_H
-+#define CKY_BASEI_H 1
-+
-+#define CKYBUFFER_PRIVATE \
-+ CKYSize len; \
-+ CKYSize size; \
-+ CKYByte *data; \
-+ void *reserved;
-+
-+#define CKYAPDU_PRIVATE \
-+ CKYBuffer apduBuf; \
-+ void *reserved;
-+
-+#endif /* CKY_BASE_H */
-+#endif /* CKY_BASEI_H */
-diff -up ./esc/src/lib/coolkey/cky_card.c.fix1 ./esc/src/lib/coolkey/cky_card.c
---- ./esc/src/lib/coolkey/cky_card.c.fix1 2018-04-26 11:44:38.437986192 -0700
-+++ ./esc/src/lib/coolkey/cky_card.c 2018-04-26 11:44:38.437986192 -0700
-@@ -0,0 +1,1226 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#include
-+#include
-+#include
-+#include "cky_basei.h" /* friend class */
-+#include "cky_base.h"
-+#include "cky_card.h"
-+#include "dynlink.h"
-+
-+#ifndef WINAPI
-+#define WINAPI
-+typedef SCARD_READERSTATE *LPSCARD_READERSTATE;
-+#endif
-+
-+#ifndef SCARD_E_NO_READERS_AVAILABLE
-+#define SCARD_E_NO_READERS_AVAILABLE ((unsigned long)0x8010002EL)
-+#endif
-+
-+#define NEW(type,count) (type *)malloc((count)*sizeof(type))
-+
-+/*
-+ * protect against scard API not being installed.
-+ */
-+
-+typedef long (WINAPI * SCardEstablishContextFn) (
-+ unsigned long dwScope,
-+ const void * pvReserved1,
-+ const void * pvReserved2,
-+ LPSCARDCONTEXT phContext);
-+
-+typedef long (WINAPI * SCardReleaseContextFn) (
-+ SCARDCONTEXT hContext);
-+
-+typedef long (WINAPI * SCardBeginTransactionFn) (
-+ long hCard);
-+
-+typedef long (WINAPI * SCardEndTransactionFn) (
-+ long hCard,
-+ unsigned long dwDisposition);
-+
-+typedef long (WINAPI * SCardConnectFn) (
-+ SCARDCONTEXT hContext,
-+ const char *szReader,
-+ unsigned long dwShareMode,
-+ unsigned long dwPreferredProtocols,
-+ long *phCard,
-+ unsigned long *pdwActiveProtocol);
-+
-+typedef long (WINAPI * SCardDisconnectFn) (
-+ long hCard,
-+ unsigned long dwDisposition);
-+
-+typedef long (WINAPI * SCardTransmitFn) (
-+ long hCard,
-+ LPCSCARD_IO_REQUEST pioSendPci,
-+ const unsigned char *pbSendBuffer,
-+ unsigned long cbSendLength,
-+ LPSCARD_IO_REQUEST pioRecvPci,
-+ unsigned char *pbRecvBuffer,
-+ unsigned long *pcbRecvLength);
-+
-+typedef long (WINAPI * SCardReconnectFn) (
-+ long hCard,
-+ unsigned long dwShareMode,
-+ unsigned long dwPreferredProtocols,
-+ unsigned long dwInitialization,
-+ unsigned long *pdwActiveProtocol);
-+
-+typedef long (WINAPI * SCardListReadersFn) (
-+ SCARDCONTEXT hContext,
-+ const char *mszGroups,
-+ char *mszReaders,
-+ unsigned long *pcchReaders);
-+
-+typedef long (WINAPI * SCardStatusFn) (
-+ long hCard,
-+ char *mszReaderNames,
-+ unsigned long *pcchReaderLen,
-+ unsigned long *pdwState,
-+ unsigned long *pdwProtocol,
-+ unsigned char *pbAtr,
-+ unsigned long *pcbAtrLen);
-+
-+typedef long (WINAPI * SCardGetAttribFn) (
-+ long hCard,
-+ unsigned long dwAttId,
-+ char *pbAttr,
-+ unsigned long *pchAttrLen);
-+
-+typedef long (WINAPI * SCardGetStatusChangeFn) (
-+ SCARDCONTEXT hContext,
-+ unsigned long dwTimeout,
-+ LPSCARD_READERSTATE rgReaderStates,
-+ unsigned long cReaders);
-+
-+typedef long (WINAPI * SCardCancelFn) (
-+ SCARDCONTEXT hContext);
-+
-+typedef struct _SCard {
-+ SCardEstablishContextFn SCardEstablishContext;
-+ SCardReleaseContextFn SCardReleaseContext;
-+ SCardBeginTransactionFn SCardBeginTransaction;
-+ SCardEndTransactionFn SCardEndTransaction;
-+ SCardConnectFn SCardConnect;
-+ SCardDisconnectFn SCardDisconnect;
-+ SCardTransmitFn SCardTransmit;
-+ SCardReconnectFn SCardReconnect;
-+ SCardListReadersFn SCardListReaders;
-+ SCardStatusFn SCardStatus;
-+ SCardGetAttribFn SCardGetAttrib;
-+ SCardGetStatusChangeFn SCardGetStatusChange;
-+ SCardCancelFn SCardCancel;
-+ SCARD_IO_REQUEST *SCARD_PCI_T0_;
-+ SCARD_IO_REQUEST *SCARD_PCI_T1_;
-+} SCard;
-+
-+#define GET_ADDRESS(library, scard, name) \
-+ status= ckyShLibrary_getAddress(library, \
-+ (void**) &scard->name, MAKE_DLL_SYMBOL(name)); \
-+ if (status != CKYSUCCESS) { \
-+ goto fail; \
-+ }
-+
-+#ifdef WIN32
-+#define SCARD_LIB_NAME "winscard.dll"
-+#else
-+#ifdef MAC
-+#define SCARD_LIB_NAME "PCSC.Framework/PCSC"
-+#else
-+#ifdef LINUX
-+#define SCARD_LIB_NAME "libpcsclite.so"
-+#else
-+#ifndef SCARD_LIB_NAME
-+#error "define wincard library for this platform"
-+#endif
-+#endif
-+#endif
-+#endif
-+
-+static SCard *
-+ckySCard_Init(void)
-+{
-+ ckyShLibrary library;
-+ CKYStatus status;
-+ SCard *scard = NEW(SCard, 1);
-+
-+ if (!scard) {
-+ return NULL;
-+ }
-+
-+ library = ckyShLibrary_open(SCARD_LIB_NAME);
-+ if (!library) {
-+ goto fail;
-+ }
-+
-+ GET_ADDRESS(library, scard, SCardEstablishContext);
-+ GET_ADDRESS(library, scard, SCardReleaseContext);
-+ GET_ADDRESS(library, scard, SCardBeginTransaction);
-+ GET_ADDRESS(library, scard, SCardEndTransaction);
-+ /* expands to SCardConnectA on Windows */
-+ GET_ADDRESS(library, scard, SCardConnect);
-+ GET_ADDRESS(library, scard, SCardDisconnect);
-+ GET_ADDRESS(library, scard, SCardTransmit);
-+ GET_ADDRESS(library, scard, SCardReconnect);
-+ /* expands to SCardListReadersA on Windows */
-+ GET_ADDRESS(library, scard, SCardListReaders);
-+ /* expands to SCardStatusA on Windows */
-+ GET_ADDRESS(library, scard, SCardStatus);
-+#ifdef WIN32
-+ GET_ADDRESS(library, scard, SCardGetAttrib);
-+#endif
-+ /* SCardGetStatusChangeA */
-+ GET_ADDRESS(library, scard, SCardGetStatusChange);
-+ GET_ADDRESS(library, scard, SCardCancel);
-+
-+ status = ckyShLibrary_getAddress( library,
-+ (void**) &scard->SCARD_PCI_T0_, MAKE_DLL_SYMBOL(g_rgSCardT0Pci));
-+ if( status != CKYSUCCESS ) {
-+ goto fail;
-+ }
-+
-+ status = ckyShLibrary_getAddress( library,
-+ (void**) &scard->SCARD_PCI_T1_, MAKE_DLL_SYMBOL(g_rgSCardT1Pci));
-+ if( status != CKYSUCCESS ) {
-+ goto fail;
-+ }
-+ return scard;
-+
-+fail:
-+ if (library) {
-+ ckyShLibrary_close(library);
-+ }
-+ free(scard);
-+ return NULL;
-+}
-+/*
-+ * Implement CKYReaderNameLists and CKYCardConnectionLists
-+ */
-+/* make the list code happy */
-+static void
-+CKYReaderName_Destroy(char *data) {
-+ free(data);
-+}
-+
-+#include "cky_list.i" /* implemnentation of the lists define by cky_list.h */
-+CKYLIST_IMPLEMENT(CKYReaderName, char *)
-+CKYLIST_IMPLEMENT(CKYCardConnection, CKYCardConnection *)
-+
-+
-+/*
-+ * CKReader objects represent Readers attached to the system.
-+ * The objects themselves are really SCard SCARD_READERSTATE objects.
-+ * These objects are used in 2 ways:
-+ * 1) the application creates static SCARD_READERSTATE's and use
-+ * CKYReader_Init() to initialize the structure. In this case
-+ * the application can call any of the reader 'methods' (functions
-+ * starting with CKReader) on these objects. When finished the
-+ * application is responsible for calling CKYReader_FreeData() to free
-+ * any data held by the reader object.
-+ * 2) Acquire an array of readers with CKYReader_CreateArray(). In this
-+ * case the application can call any method on any particular array member
-+ * In the end the Application is responsible for calling
-+ * CKYReader_DestroyArray() to free the entire array.
-+ */
-+
-+void
-+CKYReader_Init(SCARD_READERSTATE *reader)
-+{
-+ reader->szReader = NULL;
-+ reader->pvUserData = 0;
-+ reader->cbAtr = 0;
-+ reader->dwCurrentState = SCARD_STATE_UNAWARE;
-+}
-+
-+void
-+CKYReader_FreeData(SCARD_READERSTATE *reader)
-+{
-+ if (reader->szReader) {
-+ free((void *)reader->szReader);
-+ }
-+ CKYReader_Init(reader);
-+}
-+
-+CKYStatus
-+CKYReader_SetReaderName(SCARD_READERSTATE *reader, const char *name)
-+{
-+ free((void *)reader->szReader);
-+ reader->szReader = strdup(name);
-+ return (reader->szReader)? CKYSUCCESS: CKYNOMEM;
-+}
-+
-+const char *
-+CKYReader_GetReaderName(const SCARD_READERSTATE *reader)
-+{
-+ return reader->szReader;
-+}
-+
-+/* see openSC or PCSC for the semantics of Known State and Event States */
-+CKYStatus
-+CKYReader_SetKnownState(SCARD_READERSTATE *reader, unsigned long state)
-+{
-+ reader->dwCurrentState = state;
-+ return CKYSUCCESS;
-+}
-+
-+unsigned long
-+CKYReader_GetKnownState(const SCARD_READERSTATE *reader)
-+{
-+ return reader->dwCurrentState;
-+}
-+
-+unsigned long
-+CKYReader_GetEventState(const SCARD_READERSTATE *reader)
-+{
-+ return reader->dwEventState;
-+}
-+
-+/* Caller must have init'ed the buffer before calling
-+ * any data in the existing buffer is overwritten */
-+CKYStatus
-+CKYReader_GetATR(const SCARD_READERSTATE *reader, CKYBuffer *buf)
-+{
-+ CKYStatus ret;
-+
-+ ret = CKYBuffer_Resize(buf, reader->cbAtr);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ return CKYBuffer_Replace(buf, 0, reader->rgbAtr, reader->cbAtr);
-+}
-+
-+SCARD_READERSTATE *
-+CKYReader_CreateArray(const CKYReaderNameList readerNames,
-+ unsigned long *returnReaderCount)
-+{
-+ unsigned long i,j;
-+ unsigned long readerCount;
-+ SCARD_READERSTATE *readers;
-+ CKYStatus ret;
-+
-+ readerCount=CKYReaderNameList_GetCount(readerNames);
-+ if (readerCount == 0) {
-+ return NULL;
-+ }
-+ readers = NEW(SCARD_READERSTATE, readerCount);
-+ if (readers == NULL) {
-+ return NULL;
-+ }
-+
-+ for (i=0; i < readerCount; i++) {
-+ CKYReader_Init(&readers[i]);
-+ ret = CKYReader_SetReaderName(&readers[i],
-+ CKYReaderNameList_GetValue(readerNames,i));
-+ if (ret != CKYSUCCESS) {
-+ break;
-+ }
-+ }
-+ if (ret != CKYSUCCESS) {
-+ for (j=0; j < i; j++) {
-+ CKYReader_FreeData(&readers[j]);
-+ }
-+ free(readers);
-+ return NULL;
-+ }
-+ if (returnReaderCount) {
-+ *returnReaderCount=readerCount;
-+ }
-+
-+ return readers;
-+}
-+
-+/*
-+ * add more reader states to an existing reader state array.
-+ * The existing reader will have a new pointer, which will be updated only
-+ * after the new one is complete, and before the old one is freed. The 'add'
-+ * array is not modified or freed.
-+ */
-+CKYStatus
-+CKYReader_AppendArray(SCARD_READERSTATE **array, unsigned long arraySize,
-+ const char **readerNames, unsigned long numReaderNames)
-+{
-+ unsigned long i,j;
-+ SCARD_READERSTATE *readers;
-+ SCARD_READERSTATE *old;
-+ CKYStatus ret = CKYSUCCESS;
-+
-+ readers = NEW(SCARD_READERSTATE, arraySize+numReaderNames);
-+ if (readers == NULL) {
-+ return CKYNOMEM;
-+ }
-+ /* copy the original readers, inheriting all the pointer memory */
-+ memcpy(readers, *array, arraySize*sizeof(SCARD_READERSTATE));
-+
-+ /* initialize and add the new reader states. */
-+ for (i=0; i < numReaderNames; i++) {
-+ CKYReader_Init(&readers[i+arraySize]);
-+ ret = CKYReader_SetReaderName(&readers[i+arraySize],readerNames[i]);
-+ if (ret != CKYSUCCESS) {
-+ break;
-+ }
-+ }
-+
-+ /* we failed, only free the new reader states, ownership of the new
-+ * ones will revert back to the original */
-+ if (ret != CKYSUCCESS) {
-+ for (j=0; j < i; j++) {
-+ CKYReader_FreeData(&readers[j+arraySize]);
-+ }
-+ free(readers);
-+ return ret;
-+ }
-+
-+ /* Now we swap the readers states */
-+ old = *array;
-+ *array = readers;
-+ /* it's now safe to free the old one */
-+ free(old);
-+
-+ return CKYSUCCESS;
-+}
-+
-+void
-+CKYReader_DestroyArray(SCARD_READERSTATE *reader, unsigned long readerCount)
-+{
-+ unsigned long i;
-+
-+ for (i=0; i < readerCount; i++) {
-+ CKYReader_FreeData(&reader[i]);
-+ }
-+ free(reader);
-+}
-+
-+/*
-+ * CKYCardContexts are wrapped access to the SCard Context, which is
-+ * part of the openSC/ Microsoft PCSC interface. Applications will
-+ * typically open one context to get access to the SCard Subsystem.
-+ *
-+ * To protect ourselves from systems without the SCard library installed,
-+ * the SCard calls are looked up from the library and called through
-+ * a function pointer.
-+ */
-+struct _CKYCardContext {
-+ SCARDCONTEXT context;
-+ SCard *scard;
-+ unsigned long scope;
-+ unsigned long lastError;
-+};
-+
-+
-+static CKYStatus
-+ckyCardContext_init(CKYCardContext *ctx)
-+{
-+ static SCard *scard;
-+
-+ ctx->lastError = 0;
-+ ctx->context = 0;
-+ if (!scard) {
-+ scard = ckySCard_Init();
-+ if (!scard) {
-+ return CKYNOSCARD;
-+ }
-+ }
-+ ctx->scard = scard;
-+ return CKYSUCCESS;
-+}
-+
-+static CKYStatus
-+ckyCardContext_release(CKYCardContext *ctx)
-+{
-+ unsigned long rv = ctx->scard->SCardReleaseContext(ctx->context);
-+ ctx->context = 0;
-+ if (rv != SCARD_S_SUCCESS) {
-+ ctx->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+static CKYStatus
-+ckyCardContext_establish(CKYCardContext *ctx, unsigned long scope)
-+{
-+ unsigned long rv;
-+
-+ if (ctx->context) {
-+ ckyCardContext_release(ctx);
-+ }
-+ rv = ctx->scard->SCardEstablishContext(scope, NULL, NULL, &ctx->context);
-+ if (rv != SCARD_S_SUCCESS) {
-+ ctx->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYCardContext *
-+CKYCardContext_Create(unsigned long scope)
-+{
-+ CKYCardContext *ctx;
-+ CKYStatus ret;
-+
-+ ctx = NEW(CKYCardContext, 1);
-+ if (ctx == NULL) {
-+ return NULL;
-+ }
-+ ret = ckyCardContext_init(ctx);
-+ if (ret != CKYSUCCESS) {
-+ CKYCardContext_Destroy(ctx);
-+ return NULL;
-+ }
-+ ctx->scope = scope;
-+ ret = ckyCardContext_establish(ctx, scope);
-+#ifdef MAC
-+/* Apple won't establish a connnection if pcscd is not running. Because of
-+ * the way securityd controls pcscd, this may not necessarily be an error
-+ * condition. Detect this case and continue. We'll establish the connection
-+ * later..
-+ */
-+ if (ctx->lastError == SCARD_F_INTERNAL_ERROR) {
-+ ctx->context = 0; /* make sure it's not established */
-+ return ctx;
-+ }
-+#endif
-+ if (ret != CKYSUCCESS) {
-+ CKYCardContext_Destroy(ctx);
-+ return NULL;
-+ }
-+ return ctx;
-+}
-+
-+CKYStatus
-+CKYCardContext_Destroy(CKYCardContext *ctx)
-+{
-+ CKYStatus ret = CKYSUCCESS;
-+ if (ctx == NULL) {
-+ return CKYSUCCESS;
-+ }
-+ if (ctx->context) {
-+ ret = ckyCardContext_release(ctx);
-+ }
-+ free(ctx);
-+ return ret;
-+}
-+
-+SCARDCONTEXT
-+CKYCardContext_GetContext(const CKYCardContext *ctx)
-+{
-+ return ctx->context;
-+}
-+
-+CKYStatus
-+CKYCardContext_ListReaders(CKYCardContext *ctx, CKYReaderNameList *readerNames)
-+{
-+ unsigned long readerLen;
-+ unsigned long rv;
-+ char * readerStr = NULL;
-+ char *cur;
-+ char ** readerList;
-+ int count,i;
-+
-+
-+ /* return NULL in the case nothing is found, or there is an error */
-+ *readerNames = NULL;
-+
-+ /* if we aren't established yet, do so now */
-+ if (!ctx->context) {
-+ CKYStatus ret = ckyCardContext_establish(ctx, ctx->scope);
-+ if (ret != CKYSUCCESS) {
-+
-+#ifdef MAC
-+ if (ctx->lastError == SCARD_F_INTERNAL_ERROR) {
-+ /* Still can't establish, just treat it as 'zero' readers */
-+ return CKYSUCCESS;
-+ }
-+#endif
-+ return ret;
-+ }
-+ }
-+
-+ /* get the initial length */
-+ readerLen = 0;
-+ rv = ctx->scard->SCardListReaders(ctx->context, NULL /*groups*/,
-+ NULL, &readerLen);
-+ /* handle the other errors from SCardListReaders */
-+ if (rv == SCARD_E_NO_READERS_AVAILABLE) {
-+ /* not really an error: there are no readers */
-+ return CKYSUCCESS;
-+ }
-+
-+ if( rv != SCARD_S_SUCCESS ) {
-+ ctx->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+
-+ /* if no readers, return OK and a NULL list */
-+ if (readerLen == 0) {
-+ return CKYSUCCESS;
-+ }
-+
-+ /*
-+ * Keep trying to read in the buffer, allowing that the required buffer
-+ * length may change between calls to SCardListReaders.
-+ */
-+ do {
-+ if (readerLen < 1 || readerLen > CKY_OUTRAGEOUS_MALLOC_SIZE) {
-+ return CKYNOMEM;
-+ }
-+ readerStr = NEW(char,readerLen);
-+ if (readerStr == NULL) {
-+ return CKYNOMEM;
-+ }
-+
-+ rv = ctx->scard->SCardListReaders(ctx->context, NULL /*groups*/,
-+ readerStr, &readerLen);
-+
-+ /* we've found it, pop out with readerStr allocated */
-+ if (rv == SCARD_S_SUCCESS) {
-+ break;
-+ }
-+
-+ /* Nope, free the reader we allocated */
-+ free(readerStr);
-+ readerStr = NULL;
-+
-+ } while( rv == SCARD_E_INSUFFICIENT_BUFFER );
-+
-+ /* handle the other errors from SCardListReaders */
-+ if (rv == SCARD_E_NO_READERS_AVAILABLE) {
-+ /* not really an error: there are no readers */
-+ ctx->lastError = SCARD_E_NO_READERS_AVAILABLE;
-+ return CKYSUCCESS;
-+ }
-+ if (rv != SCARD_S_SUCCESS) {
-+ /* stash the error and fail */
-+ ctx->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+
-+ /*
-+ * Windows returns the list of readers as a series of null terminated
-+ * strings, terminated with an additional NULL. For example, if there
-+ * are three readers name "Reader 1", "Reader 2", "Reader 3", the returned
-+ * readerStr would look like: "Reader 1\0Reader 2\0Reader N\0\0".
-+ *
-+ * We need to return a list of ReaderNames. This is currently a pointer
-+ * to an array of string pointers, terminated by a NULL.
-+ *
-+ * +--------------+
-+ * | Reader 1 ptr | -> "Reader 1"
-+ * +--------------+
-+ * | Reader 2 ptr | -> "Reader 2"
-+ * +--------------+
-+ * | Reader N ptr | -> "Reader N"
-+ * +--------------+
-+ * | NULL |
-+ * +--------------+
-+ *
-+ * NOTE: This code explicitly knows the underlying format for
-+ * CKYReaderNameLists defined in cky_list.i. If cky_list.i is changes,
-+ * this code will need to be changed as well.
-+ */
-+ /* find the count of readers */
-+ for (cur = readerStr, count = 0; *cur; cur += strlen(cur)+1, count++ )
-+ /* Empty */ ;
-+ readerList = NEW(char *,count+1);
-+ if (readerList == NULL) {
-+ goto fail;
-+ }
-+
-+ /* now copy the readers into the array */
-+ for (i=0, cur=readerStr; i < count ; cur+=strlen(cur) +1, i++) {
-+ readerList[i] = strdup(cur);
-+ if (readerList[i] == NULL) {
-+ goto fail;
-+ }
-+ }
-+ readerList[count] = NULL;
-+ free(readerStr);;
-+ *readerNames = (CKYReaderNameList) readerList;
-+ return CKYSUCCESS;
-+
-+fail:
-+ if (readerStr) {
-+ free(readerStr);
-+ }
-+ if (readerList) {
-+ CKYReaderNameList_Destroy((CKYReaderNameList) readerList);
-+ }
-+ return CKYNOMEM;
-+}
-+
-+/*
-+ * The original C++ API had to very similiar functions that returned
-+ * either reader names or connections based on ATR. This is a single
-+ * function that can return both. The exported interface calls this
-+ * one with one of the lists set to NULL.
-+ *
-+ * NOTE: this function "knows" the underlying format for lists and
-+ * hand builds the related lists.
-+ */
-+CKYStatus
-+ckyCardContext_findReadersByATR(CKYCardContext *ctx,
-+ CKYReaderNameList *returnReaders,
-+ CKYCardConnectionList *returnConn,
-+ const CKYBuffer *targetATR)
-+{
-+ CKYReaderNameList readerNames;
-+ CKYBuffer ATR;
-+ CKYCardConnection **connList = NULL;
-+ CKYCardConnection **connPtr = NULL;
-+ char **readerList = NULL;
-+ char **readerPtr = NULL;
-+ int readerCount, i;
-+ CKYStatus ret;
-+
-+ CKYBuffer_InitEmpty(&ATR);
-+
-+ /* if we aren't established yet, do so now */
-+ if (!ctx->context) {
-+ ret = ckyCardContext_establish(ctx, ctx->scope);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+
-+ /* initialize our returned values to empty */
-+ if (returnReaders) {
-+ *returnReaders = NULL;
-+ }
-+ if (returnConn) {
-+ *returnConn = NULL;
-+ }
-+
-+ ret = CKYCardContext_ListReaders(ctx, &readerNames);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+
-+ readerCount = CKYReaderNameList_GetCount(readerNames);
-+
-+ /* none found, return success */
-+ if (readerCount == 0) {
-+ CKYReaderNameList_Destroy(readerNames);
-+ return CKYSUCCESS;
-+ }
-+
-+ /* now initialize our name and connection lists */
-+ if (returnConn) {
-+ connList = NEW(CKYCardConnection *, readerCount);
-+ connPtr = connList;
-+ if (connList == NULL) {
-+ goto fail;
-+ }
-+ }
-+ if (returnReaders) {
-+ readerList = NEW(char *, readerCount);
-+ readerPtr = readerList;
-+ if (readerList == NULL) {
-+ goto fail;
-+ }
-+ }
-+
-+ ret = CKYBuffer_Resize(&ATR, CKY_MAX_ATR_LEN);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ /* now walk the reader list trying to get connections */
-+ for (i=0; i < readerCount ; i++) {
-+ CKYCardConnection * conn = CKYCardConnection_Create(ctx);
-+ unsigned long state;
-+ const char *thisReader = CKYReaderNameList_GetValue(readerNames, i);
-+
-+
-+ if (!conn) {
-+ goto loop;
-+ }
-+ ret = CKYCardConnection_Connect(conn, thisReader);
-+ if (ret != CKYSUCCESS) {
-+ goto loop;
-+ }
-+ ret = CKYCardConnection_GetStatus(conn, &state, &ATR);
-+ if (ret != CKYSUCCESS) {
-+ goto loop;
-+ }
-+ if (CKYBuffer_IsEqual(targetATR, &ATR)) {
-+ if (connPtr) {
-+ *connPtr++ = conn; /* adopt */
-+ conn = NULL;
-+ }
-+ if (readerPtr) {
-+ *readerPtr++ = strdup(thisReader);
-+ }
-+ }
-+
-+loop:
-+ /* must happen each time through the loop */
-+ if (conn) {
-+ CKYCardConnection_Destroy(conn);
-+ }
-+ }
-+
-+ /* done with the reader names now */
-+ CKYReaderNameList_Destroy(readerNames);
-+ /* and the ATR buffer */
-+ CKYBuffer_FreeData(&ATR);
-+
-+ /* terminate out lists and return them */
-+ if (readerPtr) {
-+ *readerPtr = NULL;
-+ *returnReaders = (CKYReaderNameList) readerList;
-+ }
-+ if (connPtr) {
-+ *connPtr = NULL;
-+ *returnConn = (CKYCardConnectionList) connList;
-+ }
-+ return CKYSUCCESS;
-+
-+fail:
-+ if (readerNames) {
-+ CKYReaderNameList_Destroy(readerNames);
-+ }
-+ if (connList) {
-+ free(connList);
-+ }
-+ if (readerList) {
-+ free(readerList);
-+ }
-+ CKYBuffer_FreeData(&ATR);
-+ return CKYNOMEM;
-+}
-+
-+CKYStatus
-+CKYCardContext_FindCardsByATR(CKYCardContext *ctx,
-+ CKYCardConnectionList *cardList, const CKYBuffer *targetATR)
-+{
-+ return ckyCardContext_findReadersByATR(ctx, NULL, cardList, targetATR);
-+}
-+
-+CKYStatus
-+CKYCardContext_FindReadersByATR(CKYCardContext *ctx,
-+ CKYReaderNameList *readerNames, const CKYBuffer *targetATR)
-+{
-+ return ckyCardContext_findReadersByATR(ctx, readerNames, NULL, targetATR);
-+}
-+
-+CKYCardConnection *
-+CKYCardContext_CreateConnection(CKYCardContext *ctx)
-+{
-+ return CKYCardConnection_Create(ctx);
-+}
-+
-+CKYStatus
-+CKYCardContext_WaitForStatusChange(CKYCardContext *ctx,
-+ SCARD_READERSTATE *readers, unsigned long readerCount,
-+ unsigned long timeout)
-+{
-+ unsigned long rv;
-+
-+ /* if we aren't established yet, do so now */
-+ if (!ctx->context) {
-+ CKYStatus ret = ckyCardContext_establish(ctx, ctx->scope);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ }
-+ rv = ctx->scard->SCardGetStatusChange(ctx->context, timeout,
-+ readers, readerCount);
-+ if (rv != SCARD_S_SUCCESS) {
-+ if ((rv == SCARD_E_NO_SERVICE) || (rv == SCARD_E_SERVICE_STOPPED)) {
-+ /* if we were stopped, don't reuse the old context,
-+ * pcsc-lite hangs */
-+ ckyCardContext_release(ctx);
-+ }
-+ ctx->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardContext_Cancel(CKYCardContext *ctx)
-+{
-+ unsigned long rv;
-+
-+ /* if we aren't established yet, we can't be in change status then */
-+ if (!ctx->context) {
-+ return CKYSUCCESS;
-+ }
-+ rv = ctx->scard->SCardCancel(ctx->context);
-+
-+ if (rv != SCARD_S_SUCCESS) {
-+ ctx->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+unsigned long
-+CKYCardContext_GetLastError(const CKYCardContext *ctx)
-+{
-+ return ctx->lastError;
-+}
-+
-+/*
-+ * Connections represent the connection to the actual smart cards.
-+ * Applications usually has one of these for each card inserted in
-+ * the system. Connections are where we can get information about
-+ * each card, as well as transmit commands (APDU's) to the card.
-+ */
-+/* In the originaly C++ library, lastError was set to the last return
-+ * code from any SCARD call. In this C version of the library, lastError
-+ * is the last non-successful SCARD call. lastError will be set
-+ * if the function returns CKYSCARDERR.
-+ */
-+struct _CKYCardConnection {
-+ const CKYCardContext *ctx;
-+ SCard *scard; /* cache a copy from the context */
-+ SCARDHANDLE cardHandle;
-+ unsigned long lastError;
-+ CKYBool inTransaction;
-+ unsigned long protocol;
-+};
-+
-+static void
-+ckyCardConnection_init(CKYCardConnection *conn, const CKYCardContext *ctx)
-+{
-+ conn->ctx = ctx;
-+ conn->scard = ctx->scard;
-+ conn->cardHandle = 0;
-+ conn->lastError = 0;
-+ conn->inTransaction = 0;
-+ conn->protocol = SCARD_PROTOCOL_T0;
-+}
-+
-+
-+CKYCardConnection *
-+CKYCardConnection_Create(const CKYCardContext *ctx)
-+{
-+ CKYCardConnection *conn;
-+
-+ /* don't even try if we don't have a Card Context */
-+ if (ctx == NULL) {
-+ return NULL;
-+ }
-+
-+ conn = NEW(CKYCardConnection, 1);
-+ if (conn == NULL) {
-+ return NULL;
-+ }
-+ ckyCardConnection_init(conn, ctx);
-+ return conn;
-+}
-+
-+
-+CKYStatus
-+CKYCardConnection_Destroy(CKYCardConnection *conn)
-+{
-+ if (conn == NULL) {
-+ return CKYSUCCESS;
-+ }
-+ if (conn->inTransaction) {
-+ CKYCardConnection_EndTransaction(conn);
-+ }
-+ CKYCardConnection_Disconnect(conn);
-+ free(conn);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_Connect(CKYCardConnection *conn, const char *readerName)
-+{
-+ CKYStatus ret;
-+ unsigned long rv;
-+
-+ ret = CKYCardConnection_Disconnect(conn);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ rv = conn->scard->SCardConnect( conn->ctx->context, readerName,
-+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &conn->cardHandle, &conn->protocol);
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_Disconnect(CKYCardConnection *conn)
-+{
-+ unsigned long rv;
-+ if (conn->cardHandle == 0) {
-+ return CKYSUCCESS;
-+ }
-+ rv = conn->scard->SCardDisconnect( conn->cardHandle, SCARD_LEAVE_CARD);
-+ conn->cardHandle = 0;
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYBool
-+CKYCardConnection_IsConnected(const CKYCardConnection *conn)
-+{
-+ return (conn->cardHandle != 0);
-+}
-+
-+unsigned long
-+CKYCardConnection_GetProtocol(const CKYCardConnection *conn)
-+{
-+ return conn->protocol;
-+}
-+
-+CKYStatus
-+ckyCardConnection_reconnectRaw(CKYCardConnection *conn, unsigned long init)
-+{
-+ unsigned long rv;
-+ unsigned long protocol;
-+
-+ rv = conn->scard->SCardReconnect(conn->cardHandle,
-+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 , init, &protocol);
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ conn->protocol = protocol;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_Reconnect(CKYCardConnection *conn)
-+{
-+ return ckyCardConnection_reconnectRaw(conn, SCARD_LEAVE_CARD);
-+}
-+
-+CKYStatus CKYCardConnection_Reset(CKYCardConnection *conn)
-+{
-+ return ckyCardConnection_reconnectRaw(conn, SCARD_RESET_CARD);
-+}
-+
-+CKYStatus
-+CKYCardConnection_BeginTransaction(CKYCardConnection *conn)
-+{
-+ unsigned long rv;
-+ rv = conn->scard->SCardBeginTransaction(conn->cardHandle);
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ conn->inTransaction = 1;
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_EndTransaction(CKYCardConnection *conn)
-+{
-+ unsigned long rv;
-+ if (!conn->inTransaction) {
-+ return CKYSUCCESS; /* C++ library returns success in this case, but
-+ * it may be better to return an error ? */
-+ }
-+ rv = conn->scard->SCardEndTransaction(conn->cardHandle, SCARD_LEAVE_CARD);
-+ conn->inTransaction = 0;
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_TransmitAPDU(CKYCardConnection *conn, CKYAPDU *apdu,
-+ CKYBuffer *response)
-+{
-+ CKYStatus ret;
-+ unsigned long rv;
-+
-+ ret = CKYBuffer_Resize(response, CKYAPDU_MAX_LEN);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+
-+ if( conn->protocol == SCARD_PROTOCOL_T0 ) {
-+ rv = conn->scard->SCardTransmit(conn->cardHandle,
-+ conn->scard->SCARD_PCI_T0_,
-+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-+ NULL, response->data, &response->len);
-+ } else {
-+ rv = conn->scard->SCardTransmit(conn->cardHandle,
-+ conn->scard->SCARD_PCI_T1_,
-+ CKYBuffer_Data(&apdu->apduBuf), CKYBuffer_Size(&apdu->apduBuf),
-+ NULL, response->data, &response->len);
-+ }
-+
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError =rv;
-+ return CKYSCARDERR;
-+ }
-+
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_ExchangeAPDU(CKYCardConnection *conn, CKYAPDU *apdu,
-+ CKYBuffer *response)
-+{
-+ CKYStatus ret;
-+ CKYBuffer getResponse;
-+ CKYSize size = 0;
-+
-+ ret = CKYCardConnection_TransmitAPDU(conn, apdu, response);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ CKYBuffer_InitEmpty(&getResponse);
-+
-+ /* automatically handle the response data protocol */
-+ while ((ret == CKYSUCCESS) &&
-+ (size = CKYBuffer_Size(response)) >= 2 &&
-+ (CKYBuffer_GetChar(response,size-2) == 0x61)) {
-+ /* get the response */
-+ CKYAPDU getResponseAPDU;
-+
-+ CKYBuffer_Zero(&getResponse);
-+ CKYAPDU_Init(&getResponseAPDU);
-+ CKYAPDU_SetCLA(&getResponseAPDU, 0x00);
-+ CKYAPDU_SetINS(&getResponseAPDU, 0xc0);
-+ CKYAPDU_SetP1(&getResponseAPDU, 0x00);
-+ CKYAPDU_SetP2(&getResponseAPDU, 0x00);
-+ CKYAPDU_SetReceiveLen(&getResponseAPDU,
-+ CKYBuffer_GetChar(response,size-1));
-+ ret = CKYCardConnection_TransmitAPDU(conn, &getResponseAPDU,
-+ &getResponse);
-+ CKYAPDU_FreeData(&getResponseAPDU);
-+ if ((ret == CKYSUCCESS) && (CKYBuffer_Size(&getResponse) >= 2)) {
-+ CKYBuffer_Resize(response, size-2);
-+ CKYBuffer_AppendCopy(response,&getResponse);
-+ }
-+ }
-+ CKYBuffer_FreeData(&getResponse);
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYCardConnection_GetStatus(CKYCardConnection *conn,
-+ unsigned long *state, CKYBuffer *ATR)
-+{
-+ unsigned long readerLen = 0;
-+ unsigned long protocol;
-+ unsigned long rv;
-+ CKYSize atrLen;
-+ char *readerStr;
-+ CKYStatus ret;
-+
-+
-+ /*
-+ * Get initial length. We have to do all this because the Muscle
-+ * implementation of PCSC requires us to supply a non-NULL argument
-+ * for readerName before it will tell us the ATR, which is all we really
-+ * care about.
-+ */
-+ rv = conn->scard->SCardStatus(conn->cardHandle,
-+ NULL /*readerName*/, &readerLen, state, &protocol, NULL, &atrLen);
-+ if ( rv != SCARD_S_SUCCESS ) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+
-+ do {
-+ if (readerLen < 1 || readerLen > CKY_OUTRAGEOUS_MALLOC_SIZE) {
-+ return CKYNOMEM;
-+ }
-+ /* Mac & Linux return '0' or ATR length, just use the max value */
-+ if (atrLen == 0) {
-+ atrLen = CKY_MAX_ATR_LEN;
-+ }
-+ if (atrLen < 1 || atrLen > CKY_OUTRAGEOUS_MALLOC_SIZE) {
-+ return CKYNOMEM;
-+ }
-+ ret = CKYBuffer_Resize(ATR, atrLen);
-+ if (ret != CKYSUCCESS) {
-+ return ret;
-+ }
-+ readerStr = NEW(char, readerLen);
-+ if (readerStr == NULL) {
-+ return CKYNOMEM;
-+ }
-+
-+ rv = conn->scard->SCardStatus(conn->cardHandle, readerStr, &readerLen,
-+ state, &protocol, ATR->data, &atrLen);
-+ ATR->len = atrLen;
-+ free(readerStr);
-+ } while (rv == SCARD_E_INSUFFICIENT_BUFFER);
-+
-+ if (rv != SCARD_S_SUCCESS) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYCardConnection_GetAttribute(CKYCardConnection *conn,
-+ unsigned long attrID, CKYBuffer *attrBuf)
-+{
-+#ifdef WIN32
-+ unsigned long len = 0;
-+ unsigned long rv;
-+
-+ /*
-+ * Get initial length. We have to do all this because the Muscle
-+ * implementation of PCSC requires us to supply a non-NULL argument
-+ * for readerName before it will tell us the ATR, which is all we really
-+ * care about.
-+ */
-+ rv = conn->scard->SCardGetAttrib(conn->cardHandle, attrID, NULL, &len);
-+ if ( rv != SCARD_S_SUCCESS ) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ CKYBuffer_Resize(attrBuf, len);
-+
-+ rv = conn->scard->SCardGetAttrib(conn->cardHandle, attrID,
-+ attrBuf->data, &attrBuf->len);
-+ if( rv != SCARD_S_SUCCESS ) {
-+ conn->lastError = rv;
-+ return CKYSCARDERR;
-+ }
-+ return CKYSUCCESS;
-+#else
-+ conn->lastError = -1;
-+ return CKYSCARDERR;
-+#endif
-+}
-+
-+const CKYCardContext *
-+CKYCardConnection_GetContext(const CKYCardConnection *conn)
-+{
-+ return conn->ctx;
-+}
-+
-+unsigned long
-+CKYCardConnection_GetLastError(const CKYCardConnection *conn)
-+{
-+ return conn->lastError;
-+}
-diff -up ./esc/src/lib/coolkey/cky_card.h.fix1 ./esc/src/lib/coolkey/cky_card.h
---- ./esc/src/lib/coolkey/cky_card.h.fix1 2018-04-26 11:44:38.439986181 -0700
-+++ ./esc/src/lib/coolkey/cky_card.h 2018-04-26 11:44:38.439986181 -0700
-@@ -0,0 +1,132 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_CARD_H
-+#define CKY_CARD_H 1
-+
-+#include
-+
-+#include "cky_base.h"
-+#include "cky_list.h"
-+
-+/*
-+ * hide the structure of CardConnections and CardContexts
-+ */
-+typedef struct _CKYCardContext CKYCardContext;
-+typedef struct _CKYCardConnection CKYCardConnection;
-+
-+/*
-+ * define CKYReaderNameList, CKYReaderNameIterator, CKYCardConnectionList, and
-+ * CKYCardConnectionIterator, and their associated functions.
-+ * See cky_list.h for these functions .
-+ */
-+
-+CKYLIST_DECLARE(CKYReaderName, char *)
-+CKYLIST_DECLARE(CKYCardConnection, CKYCardConnection *)
-+
-+CKY_BEGIN_PROTOS
-+void CKYReader_Init(SCARD_READERSTATE *reader);
-+void CKYReader_FreeData(SCARD_READERSTATE *reader);
-+
-+/*
-+ * "Accessors": for SCARD_READERSTATE structure as a class.
-+ * These functions take an SCARD_READERSTATE which can also be referenced
-+ * directly.
-+ */
-+CKYStatus CKYReader_SetReaderName(SCARD_READERSTATE *reader, const char *name);
-+const char *CKYReader_GetReaderName(const SCARD_READERSTATE *reader);
-+CKYStatus CKYReader_SetKnownState(SCARD_READERSTATE *reader,
-+ unsigned long state);
-+unsigned long CKYReader_GetKnownState(const SCARD_READERSTATE *reader);
-+unsigned long CKYReader_GetEventState(const SCARD_READERSTATE *reader);
-+CKYStatus CKYReader_GetATR(const SCARD_READERSTATE *reader, CKYBuffer *buf);
-+/* create an array of READERSTATEs from a LIST of Readers */
-+SCARD_READERSTATE *CKYReader_CreateArray(const CKYReaderNameList readerNames,
-+ unsigned long *readerCount);
-+/* frees the reader, then the full array */
-+void CKYReader_DestroyArray(SCARD_READERSTATE *reader, unsigned long count);
-+/* add more elements to a ReaderState array*/
-+CKYStatus
-+CKYReader_AppendArray(SCARD_READERSTATE **array, unsigned long arraySize,
-+ const char **readerNames, unsigned long numReaderNames);
-+
-+/*
-+ * card contexts wrap Microsoft's SCARDCONTEXT.
-+ */
-+/* create a new one. SCOPE must be SCOPE_USER */
-+CKYCardContext *CKYCardContext_Create(unsigned long scope);
-+/* destroy an existing one */
-+CKYStatus CKYCardContext_Destroy(CKYCardContext *context);
-+/* get the Windows handle associated with this context */
-+SCARDCONTEXT CKYCardContext_GetContext(const CKYCardContext *context);
-+/* Get a list of the installed readers */
-+CKYStatus CKYCardContext_ListReaders(CKYCardContext *context,
-+ CKYReaderNameList *readerNames);
-+/* get a list of card connections for cards matching our target ATR */
-+CKYStatus CKYCardContext_FindCardsByATR(CKYCardContext *context,
-+ CKYCardConnectionList *cardList,
-+ const CKYBuffer *targetATR);
-+/* get a list of readers with attached cards that match our target ATR */
-+CKYStatus CKYCardContext_FindReadersByATR(CKYCardContext *context,
-+ CKYReaderNameList *readerNames,
-+ const CKYBuffer *targetATR);
-+/* return if any of the readers in our array has changed in status */
-+CKYStatus CKYCardContext_WaitForStatusChange(CKYCardContext *context,
-+ SCARD_READERSTATE *readers,
-+ unsigned long readerCount,
-+ unsigned long timeout);
-+/* cancel any current operation (such as wait for status change) on this
-+ * context */
-+CKYStatus CKYCardContext_Cancel(CKYCardContext *context);
-+/* get the last underlying Windows SCARD error */
-+unsigned long CKYCardContext_GetLastError(const CKYCardContext *context);
-+
-+/*
-+ * manage the actual connection to a card.
-+ */
-+/* create a connection. A connection is not associated with a reader
-+ * until CKYCardConnection_Connect() is called.
-+ */
-+CKYCardConnection *CKYCardConnection_Create(const CKYCardContext *context);
-+CKYStatus CKYCardConnection_Destroy(CKYCardConnection *connection);
-+CKYStatus CKYCardConnection_BeginTransaction(CKYCardConnection *connection);
-+CKYStatus CKYCardConnection_EndTransaction(CKYCardConnection *connection);
-+CKYStatus CKYCardConnection_TransmitAPDU(CKYCardConnection *connection,
-+ CKYAPDU *apdu,
-+ CKYBuffer *response);
-+CKYStatus CKYCardConnection_ExchangeAPDU(CKYCardConnection *connection,
-+ CKYAPDU *apdu,
-+ CKYBuffer *response);
-+CKYStatus CKYCardConnection_Connect(CKYCardConnection *connection,
-+ const char *readerName);
-+CKYStatus CKYCardConnection_Disconnect(CKYCardConnection *connection);
-+unsigned long CKYCardConnection_GetProtocol(const CKYCardConnection *conn);
-+CKYBool CKYCardConnection_IsConnected(const CKYCardConnection *connection);
-+CKYStatus CKYCardConnection_Reconnect(CKYCardConnection *connection);
-+CKYStatus CKYCardConnection_GetStatus(CKYCardConnection *connection,
-+ unsigned long *state, CKYBuffer *ATR);
-+CKYStatus CKYCardConnection_GetAttribute(CKYCardConnection *connection,
-+ unsigned long attrID, CKYBuffer *attrBuf);
-+CKYStatus CKYCardConnection_Reset(CKYCardConnection *connection);
-+const CKYCardContext *CKYCardConnection_GetContext(const CKYCardConnection *cxt);
-+unsigned long CKYCardConnection_GetLastError(const CKYCardConnection *context);
-+
-+CKY_END_PROTOS
-+
-+#endif /* CKY_CARD_H */
-diff -up ./esc/src/lib/coolkey/cky_factory.c.fix1 ./esc/src/lib/coolkey/cky_factory.c
---- ./esc/src/lib/coolkey/cky_factory.c.fix1 2018-04-26 11:44:38.439986181 -0700
-+++ ./esc/src/lib/coolkey/cky_factory.c 2018-04-26 11:44:38.439986181 -0700
-@@ -0,0 +1,885 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#include "string.h"
-+#include "cky_base.h"
-+#include "cky_factory.h"
-+
-+/*
-+ * special commands can be issued at any time
-+ */
-+CKYStatus
-+CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ const CKYBuffer *AID)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_SELECT_FILE);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ return CKYAPDU_SetSendDataBuffer(apdu, AID);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_SelectCardManager(CKYAPDU *apdu)
-+{
-+ CKYByte c = 0;
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_SELECT_FILE);
-+ CKYAPDU_SetP1(apdu, 0x04);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ /* I can't find the documentation for this, but if you pass an empty
-+ * AID to SelectFile on the Cyberflex Access 32k, it selects the
-+ * CardManager applet. Good thing, because I couldn't find any other
-+ * way to accomplish this without knowing the AID of the CardManager. */
-+ return CKYAPDU_SetSendData(apdu,&c,0);
-+}
-+
-+/*
-+ * card manager commands must be issued with the card manager selected.
-+ */
-+CKYStatus
-+CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
-+ CKYAPDU_SetINS(apdu, ISO_INS_GET_DATA);
-+ CKYAPDU_SetP1(apdu, 0x9f);
-+ CKYAPDU_SetP2(apdu, 0x7f);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_CPLCDATA);
-+}
-+/*
-+ * applet commands must be issued with the appplet selected.
-+ */
-+CKYStatus
-+CKYAPDUFactory_ListKeys(CKYAPDU *apdu, CKYByte sequence)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_LIST_KEYS);
-+ CKYAPDU_SetP1(apdu, sequence);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_LIST_KEYS);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ComputeCryptInit(CKYAPDU *apdu, CKYByte keyNumber, CKYByte mode,
-+ CKYByte direction, CKYByte location)
-+{
-+ CKYByte data[5];
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_INIT);
-+ data[0] = mode;
-+ data[1] = direction;
-+ data[2] = location;
-+ data[3] = 0; /* future provide for init data */
-+ data[4] = 0;
-+ return CKYAPDU_SetSendData(apdu, data, sizeof(data));
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ComputeCryptProcess(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_PROCESS);
-+ if (data) {
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)CKYBuffer_Size(data));
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, data);
-+ } else {
-+ ret = CKYAPDU_SetSendData(apdu, &location, 1);
-+ }
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+
-+CKYStatus
-+CKYAPDUFactory_ComputeCryptFinal(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data, const CKYBuffer *sig)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_FINAL);
-+ if (data) {
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)CKYBuffer_Size(data));
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, data);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ if (sig) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)CKYBuffer_Size(sig));
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, sig);
-+ }
-+ } else {
-+ ret = CKYAPDU_SetSendData(apdu, &location, 1);
-+ }
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *publicData, const CKYBuffer *secretKey)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!publicData)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(publicData)))
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_KEY_AGREEMENT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, publicData);
-+ if (ret == CKYSUCCESS && secretKey && 0 < (len = CKYBuffer_Size(secretKey))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, secretKey);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber, CKYByte mode,
-+ CKYByte direction, CKYByte location,
-+ const CKYBuffer *idata, const CKYBuffer *sig)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!idata)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_CRYPT);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 5);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, mode);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, direction);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, idata);
-+ if (ret == CKYSUCCESS && sig && 0 < (len = CKYBuffer_Size(sig))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, sig);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_CreatePIN(CKYAPDU *apdu, CKYByte pinNumber, CKYByte maxAttempts,
-+ const char *pinValue)
-+{
-+ CKYSize len;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_CREATE_PIN);
-+ CKYAPDU_SetP1(apdu, pinNumber);
-+ CKYAPDU_SetP2(apdu, maxAttempts);
-+ len = strlen(pinValue);
-+ return CKYAPDU_SetSendData(apdu, (unsigned char *)pinValue, len);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte pinNumber, const char *pinValue)
-+{
-+ CKYSize len;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_VERIFY_PIN);
-+ CKYAPDU_SetP1(apdu, pinNumber);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ len = strlen(pinValue);
-+ return CKYAPDU_SetSendData(apdu, (unsigned char *)pinValue, len);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ChangePIN(CKYAPDU *apdu, CKYByte pinNumber, const char *oldPin,
-+ const char *newPin)
-+{
-+ CKYSize oldLen, newLen;
-+ CKYBuffer buf;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_CHANGE_PIN);
-+ CKYAPDU_SetP1(apdu, pinNumber);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ oldLen = strlen(oldPin);
-+ newLen = strlen(newPin);
-+ /* optimization, do a single malloc for the whole block */
-+ ret = CKYBuffer_Reserve(&buf, oldLen+newLen+4);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)oldLen);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendData(&buf, (unsigned char *)oldPin, oldLen);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)newLen);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendData(&buf, (unsigned char *)newPin, newLen);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ListPINs(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_LIST_PINS);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_LIST_PINS);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_Logout(CKYAPDU *apdu, CKYByte pinNumber)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_LOGOUT);
-+ CKYAPDU_SetP1(apdu, pinNumber);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID, CKYSize size,
-+ unsigned short readACL, unsigned short writeACL, unsigned short deleteACL)
-+{
-+ CKYBuffer buf;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_CREATE_OBJ);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ CKYBuffer_InitEmpty(&buf);
-+ /* optimization, do a single malloc for the whole block */
-+ ret = CKYBuffer_Reserve(&buf,0x0e);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,objectID);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,size);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf,readACL);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf,writeACL);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendShort(&buf,deleteACL);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_DeleteObject(CKYAPDU *apdu, unsigned long objectID, CKYByte zero)
-+{
-+ CKYBuffer buf;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_DELETE_OBJ);
-+ CKYAPDU_SetP1(apdu, zero);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ CKYBuffer_InitEmpty(&buf);
-+ ret = CKYBuffer_AppendLong(&buf,objectID);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *idata, const CKYBuffer *sig)
-+{
-+ CKYStatus ret = CKYINVALIDARGS;
-+ CKYSize len;
-+ CKYBuffer buf;
-+
-+ if (!idata)
-+ return ret;
-+
-+ if (!(len = CKYBuffer_Size(idata)) && location != CKY_DL_OBJECT)
-+ return ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_COMPUTE_ECC_SIGNATURE);
-+ CKYAPDU_SetP1(apdu, keyNumber);
-+ CKYAPDU_SetP2(apdu, CKY_CIPHER_ONE_STEP);
-+
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ ret = CKYBuffer_Reserve(&buf, 3);
-+
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendChar(&buf, location);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYBuffer_AppendShort(&buf, (unsigned short)len);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, idata);
-+ if (ret == CKYSUCCESS && sig && 0 < (len = CKYBuffer_Size(sig))) {
-+ CKYBuffer_Resize(&buf,2);
-+ CKYBuffer_SetShort(&buf, 0, (unsigned short)len);
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, &buf);
-+ if (ret == CKYSUCCESS)
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, sig);
-+ }
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ReadObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset, CKYByte size)
-+{
-+ CKYBuffer buf;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_READ_OBJ);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ CKYBuffer_InitEmpty(&buf);
-+ /* optimization, do a single malloc for the whole block */
-+ ret = CKYBuffer_Reserve(&buf,0x09);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,objectID);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,offset);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, size);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset,CKYSize size,CKYBuffer *data)
-+{
-+ CKYBuffer buf;
-+ CKYStatus ret = CKYSUCCESS;
-+ unsigned short dataSize = 0;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_WRITE_OBJ);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ CKYBuffer_InitEmpty(&buf);
-+
-+ dataSize = (unsigned short) CKYBuffer_Size(data);
-+
-+ if(!dataSize) {
-+ ret = CKYINVALIDARGS;
-+ goto fail;
-+ }
-+
-+ ret = CKYBuffer_AppendLong(&buf,objectID);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendLong(&buf,offset);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, size);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ ret = CKYAPDU_SetSendDataBuffer(apdu,&buf);
-+
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+ ret = CKYAPDU_AppendSendDataBuffer(apdu, data);
-+
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_ListObjects(CKYAPDU *apdu, CKYByte sequence)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_LIST_OBJECTS);
-+ CKYAPDU_SetP1(apdu, sequence);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_LIST_OBJECTS);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetStatus(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_STATUS);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_STATUS);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_Noop(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_NOP);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetBuildID(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_BUILDID);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_BUILDID);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetLifeCycle(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_LIFECYCLE);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_LIFE_CYCLE);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetLifeCycleV2(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_LIFECYCLE);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_LIFE_CYCLE_V2);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetRandom(CKYAPDU *apdu, CKYByte len)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_RANDOM);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, len);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_SeedRandom(CKYAPDU *apdu, const CKYBuffer *data)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_SEED_RANDOM);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetSendDataBuffer(apdu, data);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetIssuerInfo(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_ISSUER_INFO);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_ISSUER_INFO);
-+}
-+
-+CKYStatus
-+CKYAPDUFactory_GetBuiltinACL(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_COOLKEY);
-+ CKYAPDU_SetINS(apdu, CKY_INS_GET_BUILTIN_ACL);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CKY_SIZE_GET_BUILTIN_ACL);
-+}
-+
-+CKYStatus
-+CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type, const CKYBuffer *data)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, CAC_INS_SIGN_DECRYPT);
-+ CKYAPDU_SetP1(apdu, type);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetSendDataBuffer(apdu, data);
-+}
-+
-+CKYStatus
-+CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, CAC_INS_GET_CERTIFICATE);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, size);
-+}
-+
-+CKYStatus
-+CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte type, CKYByte count)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_GLOBAL_PLATFORM);
-+ CKYAPDU_SetINS(apdu, CAC_INS_READ_FILE);
-+ CKYAPDU_SetP1(apdu, (offset >> 8) & 0xff);
-+ CKYAPDU_SetP2(apdu, offset & 0xff);
-+ ret = CKYBuffer_Reserve(&buf, 2);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, type);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, count);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+CACAPDUFactory_GetProperties(CKYAPDU *apdu)
-+{
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, CAC_INS_GET_PROPERTIES);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, 0x00);
-+ return CKYAPDU_SetReceiveLen(apdu, CAC_SIZE_GET_PROPERTIES);
-+}
-+
-+CKYStatus
-+PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg,
-+ CKYByte key, int len, const CKYBuffer *data)
-+{
-+ CKYStatus ret;
-+ CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN :
-+ CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, PIV_INS_GEN_AUTHENTICATE);
-+ CKYAPDU_SetP1(apdu, alg);
-+ CKYAPDU_SetP2(apdu, key);
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, data);
-+ if (ret == CKYSUCCESS && chain == 0 && len != 0) {
-+ if (len >= 256) len = 0;
-+ ret = CKYAPDU_AppendReceiveLen(apdu, len);
-+ }
-+ return ret;
-+}
-+
-+CKYStatus
-+PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object, CKYByte count)
-+{
-+ CKYStatus ret;
-+ CKYBuffer buf;
-+ CKYByte objectSize;
-+
-+ CKYBuffer_InitEmpty(&buf);
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, 0xcb);
-+ CKYAPDU_SetP1(apdu, 0x3f);
-+ CKYAPDU_SetP2(apdu, 0xff);
-+
-+ objectSize = CKYBuffer_Size(object);
-+
-+ ret = CKYBuffer_Reserve(&buf, 2+objectSize);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, 0x5c);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendChar(&buf, objectSize);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYBuffer_AppendCopy(&buf, object);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, &buf);
-+ if (ret != CKYSUCCESS) {
-+ goto fail;
-+ }
-+ ret = CKYAPDU_AppendReceiveLen(apdu, count);
-+fail:
-+ CKYBuffer_FreeData(&buf);
-+ return ret;
-+}
-+
-+CKYStatus
-+P15APDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef, const CKYBuffer *pin)
-+{
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, CAC_INS_VERIFY_PIN);
-+ CKYAPDU_SetP1(apdu, 0x00);
-+ CKYAPDU_SetP2(apdu, keyRef);
-+ /* no pin, send an empty buffer */
-+ if (CKYBuffer_Size(pin) == 0) {
-+ return CKYAPDU_SetReceiveLen(apdu, 0);
-+ }
-+
-+ /* all CAC pins are 8 bytes exactly. If to long, truncate it */
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, pin);
-+ return ret;
-+
-+}
-+
-+CKYStatus
-+P15APDUFactory_ReadRecord(CKYAPDU *apdu, CKYByte record, CKYByte short_ef,
-+ CKYByte flags, CKYByte count)
-+{
-+ CKYByte control;
-+
-+ control = (short_ef << 3) & 0xf8;
-+ control |= flags & 0x07;
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_READ_RECORD);
-+ CKYAPDU_SetP1(apdu, record);
-+ CKYAPDU_SetP2(apdu, control);
-+ return CKYAPDU_SetReceiveLen(apdu, count);
-+}
-+
-+CKYStatus
-+P15APDUFactory_ReadBinary(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte count)
-+{
-+ CKYByte p1 = 0,p2 = 0;
-+ unsigned short max_offset = 0;
-+
-+ if (flags & P15_USE_SHORT_EF) {
-+ max_offset = 0xff;
-+ p1 = P15_USE_SHORT_EF | (short_ef & 0x7);
-+ p2 = offset & 0xff;
-+ } else {
-+ max_offset = 0x7fff;
-+ p1 = (offset >> 8) & 0x7f;
-+ p2 = offset & 0xff;
-+ }
-+ if (offset > max_offset) {
-+ return CKYINVALIDARGS;
-+ }
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_READ_BINARY);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ return CKYAPDU_SetReceiveLen(apdu, count);
-+}
-+
-+CKYStatus
-+P15APDUFactory_ManageSecurityEnvironment(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ CKYByte keyRef)
-+{
-+ CKYByte param[3];
-+
-+ CKYAPDU_SetCLA(apdu, CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_MANAGE_SECURITY_ENVIRONMENT);
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ param[0] = 0x83;
-+ param[1] = 1;
-+ param[2] = keyRef;
-+ return CKYAPDU_SetSendData(apdu, param, sizeof param);
-+}
-+
-+CKYStatus
-+P15APDUFactory_PerformSecurityOperation(CKYAPDU *apdu, CKYByte dir,
-+ int chain, CKYSize retLen, const CKYBuffer *data)
-+{
-+ CKYByte p1,p2;
-+ CKYStatus ret;
-+
-+ CKYAPDU_SetCLA(apdu, chain ? CKY_CLASS_ISO7816_CHAIN :
-+ CKY_CLASS_ISO7816);
-+ CKYAPDU_SetINS(apdu, ISO_INS_PERFORM_SECURITY_OPERATION);
-+ if (dir == CKY_DIR_DECRYPT) {
-+ p1 = ISO_PSO_DECRYPT_P1;
-+ p2 = ISO_PSO_DECRYPT_P2;
-+ } else {
-+ p1 = ISO_PSO_SIGN_P1;
-+ p2 = ISO_PSO_SIGN_P2;
-+ }
-+ CKYAPDU_SetP1(apdu, p1);
-+ CKYAPDU_SetP2(apdu, p2);
-+ ret = CKYAPDU_SetSendDataBuffer(apdu, data);
-+ if (ret == CKYSUCCESS && (chain == 0) && retLen != 0) {
-+ ret = CKYAPDU_AppendReceiveLength(apdu, retLen);
-+ }
-+ return ret;
-+}
-+
-+
-diff -up ./esc/src/lib/coolkey/cky_factory.h.fix1 ./esc/src/lib/coolkey/cky_factory.h
---- ./esc/src/lib/coolkey/cky_factory.h.fix1 2018-04-26 11:44:38.442986163 -0700
-+++ ./esc/src/lib/coolkey/cky_factory.h 2018-04-26 11:44:38.441986169 -0700
-@@ -0,0 +1,294 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_FACTORY_H
-+#define CKY_FACTORY_H 1
-+
-+#include "cky_base.h"
-+
-+/*
-+ * Various Class bytes
-+ */
-+#define CKY_CLASS_ISO7816 0x00
-+#define CKY_CLASS_ISO7816_CHAIN 0x10
-+#define CKY_CLASS_GLOBAL_PLATFORM 0x80
-+#define CKY_CLASS_SECURE 0x84
-+#define CKY_CLASS_COOLKEY 0xb0
-+
-+/*
-+ * Applet Instruction Bytes
-+ */
-+/* Card Manager */
-+#define ISO_INS_SELECT_FILE 0xa4
-+#define ISO_INS_GET_DATA 0xca
-+#define ISO_INS_READ_BINARY 0xb0
-+#define ISO_INS_READ_RECORD 0xb2
-+#define ISO_INS_MANAGE_SECURITY_ENVIRONMENT 0x22
-+#define ISO_INS_PERFORM_SECURITY_OPERATION 0x2a
-+
-+/* ISO Parameters: */
-+#define ISO_LOGIN_LOCAL 0x80
-+#define ISO_LOGIN_GLOBAL 0x00
-+#define ISO_MSE_SET 0x01
-+#define ISO_MSE_STORE 0xf2
-+#define ISO_MSE_RESTORE 0xf3
-+#define ISO_MSE_ERASE 0xf4
-+#define ISO_MSE_QUAL_VERIFY 0x80
-+#define ISO_MSE_QUAL_COMPUTE 0x40
-+#define ISO_MSE_AUTH 0xa4
-+#define ISO_MSE_SIGN 0xb6
-+#define ISO_MSE_KEA 0xb8
-+#define ISO_PSO_SIGN_P1 0x9e
-+#define ISO_PSO_SIGN_P2 0x9a
-+#define ISO_PSO_ENCRYPT_P1 0x86
-+#define ISO_PSO_ENCRYPT_P2 0x80
-+#define ISO_PSO_DECRYPT_P1 0x80
-+#define ISO_PSO_DECRYPT_P2 0x86
-+
-+/* deprecated */
-+#define CKY_INS_SETUP 0x2A
-+#define CKY_INS_GEN_KEYPAIR 0x30
-+#define CKY_INS_EXPORT_KEY 0x34
-+#define CKY_INS_UNBLOCK_PIN 0x46
-+#define CKY_INS_GET_CHALLENGE 0x62
-+#define CKY_INS_CAC_EXT_AUTH 0x38
-+#define CKY_INS_LOGOUT_ALL 0x60
-+
-+/* public */
-+#define CKY_INS_VERIFY_PIN 0x42
-+#define CKY_INS_LIST_OBJECTS 0x58
-+#define CKY_INS_LIST_KEYS 0x3A
-+#define CKY_INS_LIST_PINS 0x48
-+#define CKY_INS_GET_STATUS 0x3C
-+#define CKY_INS_GET_LIFECYCLE 0xF2
-+#define CKY_INS_GET_ISSUER_INFO 0xF6
-+#define CKY_INS_GET_BUILTIN_ACL 0xFA
-+#define CKY_INS_GET_BUILDID 0x70
-+#define CKY_INS_GET_RANDOM 0x72
-+#define CKY_INS_SEED_RANDOM 0x73
-+#define CKY_INS_NOP 0x71
-+
-+/* nonce validated only */
-+#define CKY_INS_LOGOUT 0x61
-+
-+/* nonce validated & Secure Channel */
-+#define CKY_INS_IMPORT_KEY 0x32
-+#define CKY_INS_COMPUTE_CRYPT 0x36
-+#define CKY_INS_COMPUTE_ECC_SIGNATURE 0x37
-+#define CKY_INS_COMPUTE_ECC_KEY_AGREEMENT 0x38
-+#define CKY_INS_CREATE_PIN 0x40
-+#define CKY_INS_CHANGE_PIN 0x44
-+#define CKY_INS_CREATE_OBJ 0x5A
-+#define CKY_INS_DELETE_OBJ 0x52
-+#define CKY_INS_READ_OBJ 0x56
-+#define CKY_INS_WRITE_OBJ 0x54
-+
-+/* Secure channel only */
-+#define CKY_INS_INIT_UPDATE 0x50
-+#define CKY_INS_SEC_EXT_AUTH 0x82
-+#define CKY_INS_SEC_SET_LIFECYCLE 0xF0
-+#define CKY_INS_SEC_SET_PIN 0x04
-+#define CKY_INS_SEC_READ_IOBUF 0x08
-+#define CKY_INS_SEC_START_ENROLLMENT 0x0C
-+
-+
-+/* CAC */
-+#define CAC_INS_GET_CERTIFICATE 0x36
-+#define CAC_INS_SIGN_DECRYPT 0x42
-+#define CAC_INS_VERIFY_PIN 0x20
-+#define CAC_INS_GET_PROPERTIES 0x56
-+#define CAC_INS_READ_FILE 0x52
-+
-+#define CAC_SIZE_GET_PROPERTIES 48
-+#define CAC_P1_STEP 0x80
-+#define CAC_P1_FINAL 0x00
-+
-+/* PIV */
-+#define PIV_INS_GEN_AUTHENTICATE 0x87
-+
-+/*
-+ * Fixed return sized from various commands
-+ */
-+#define CKY_SIZE_GET_CPLCDATA 45
-+#define CKY_SIZE_LIST_KEYS 11
-+#define CKY_SIZE_LIST_PINS 2
-+#define CKY_SIZE_LIST_OBJECTS 14
-+#define CKY_SIZE_GET_STATUS 16
-+#define CKY_SIZE_GET_LIFE_CYCLE 1
-+#define CKY_SIZE_GET_LIFE_CYCLE_V2 4
-+#define CKY_SIZE_GET_BUILDID 4
-+#define CKY_SIZE_GET_ISSUER_INFO 0xe0
-+#define CKY_SIZE_GET_BUILTIN_ACL 7
-+
-+/*
-+ * Crypt functions
-+ */
-+/* functions */
-+#define CKY_CIPHER_INIT 1
-+#define CKY_CIPHER_PROCESS 2
-+#define CKY_CIPHER_FINAL 3
-+#define CKY_CIPHER_ONE_STEP 4 /* init and final in one APDU */
-+
-+/* modes */
-+#define CKY_RSA_NO_PAD 0x00
-+#define CKY_RSA_PAD_PKCS1 0x01
-+#define CKY_DSA_SHA 0x10
-+#define CKY_DES_CBC_NOPAD 0x20
-+#define CKY_DES_ECB_NOPAD 0x21
-+
-+/* operations (Cipher Direction) */
-+#define CKY_DIR_NONE 0x00
-+#define CKY_DIR_SIGN 0x01
-+#define CKY_DIR_VERIFY 0x02
-+#define CKY_DIR_ENCRYPT 0x03
-+#define CKY_DIR_DECRYPT 0x04
-+
-+/* Data Location */
-+#define CKY_DL_APDU 0x01
-+#define CKY_DL_OBJECT 0x02
-+
-+/* Key Types */
-+#define CKY_KEY_RSA_PUBLIC 0x01
-+#define CKY_KEY_RSA_PRIVATE 0x02
-+#define CKY_KEY_RSA_PRIVATE_CRT 0x03
-+#define CKY_KEY_DSA_PUBLIC 0x04
-+#define CKY_KEY_DSA_PRIVATE 0x05
-+#define CKY_KEY_DES 0x06
-+#define CKY_KEY_3DES 0x07
-+#define CKY_KEY_3DES3 0x08
-+
-+/* List Operators */
-+#define CKY_LIST_RESET 0x00
-+#define CKY_LIST_NEXT 0x01
-+
-+/* Max Size for a read block */
-+#define CKY_MAX_READ_CHUNK_SIZE 255
-+#define CKY_MAX_WRITE_CHUNK_SIZE 240
-+
-+/* Life Cycle State */
-+#define CKY_APPLICATION_LOGICALLY_DELETED 0x00
-+#define CKY_APPLICATION_INSTALLED 0x03
-+#define CKY_APPLICATION_SELECTABLE 0x07
-+#define CKY_APPLICATION_PERSONALIZED 0x0f
-+#define CKY_APPLICATION_BLOCKED 0x7f
-+#define CKY_APPLICATION_LOCKED 0xff
-+#define CKY_CARDM_MANAGER_OP_READER 0x01
-+#define CKY_CARDM_MANAGER_INITIALIZED 0x03
-+#define CKY_CARDM_MANAGER_SECURED 0x0f
-+#define CKY_CARDM_MANAGER_LOCKED 0x7f
-+#define CKY_CARDM_MANAGER_TERMINATED 0xff
-+
-+/* Read Record Flags */
-+#define P15_READ_P1 0x4
-+#define P15_READ_P1_TO_LAST 0x5
-+#define P15_READ_LAST_TO_P1 0x6
-+#define P15_READ_FIRST 0x0
-+#define P15_READ_LAST 0x1
-+#define P15_READ_NEXT 0x2
-+#define P15_READ_PREV 0x3
-+
-+/* Read Binary Flags */
-+#define P15_USE_SHORT_EF 0x80
-+
-+/*
-+ * The following factories 'Fill in' APDUs for each of the
-+ * functions described below. Nonces are not automatically added.
-+ * APDU's are for COOLKEY version 1.0 protocol. Callers should pass
-+ * in Already inited apdu's . Callers are responsible for freeing.
-+ * the APDU data, even in event of failure.
-+ */
-+CKY_BEGIN_PROTOS
-+
-+/* function based factorys */
-+CKYStatus CKYAPDUFactory_SelectFile(CKYAPDU *apdu, CKYByte p1, CKYByte p2,
-+ const CKYBuffer *AID);
-+CKYStatus CKYAPDUFactory_SelectCardManager(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_GetCPLCData(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_ListKeys(CKYAPDU *apdu, CKYByte sequence);
-+CKYStatus CKYAPDUFactory_ComputeCryptInit(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte mode, CKYByte direction, CKYByte location);
-+CKYStatus CKYAPDUFactory_ComputeCryptProcess(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data);
-+CKYStatus CKYAPDUFactory_ComputeCryptFinal(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location, const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeCryptOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte mode, CKYByte direction, CKYByte location,
-+ const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeECCSignatureOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *data, const CKYBuffer *sig);
-+CKYStatus CKYAPDUFactory_ComputeECCKeyAgreementOneStep(CKYAPDU *apdu, CKYByte keyNumber,
-+ CKYByte location,
-+ const CKYBuffer *publicData, const CKYBuffer *secretKey);
-+CKYStatus CKYAPDUFactory_CreatePIN(CKYAPDU *apdu, CKYByte pinNumber,
-+ CKYByte maxAttempts, const char *pinValue);
-+CKYStatus CKYAPDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte pinNumber,
-+ const char *pinValue);
-+CKYStatus CKYAPDUFactory_ChangePIN(CKYAPDU *apdu, CKYByte pinNUmber,
-+ const char *oldPin, const char *newPin);
-+CKYStatus CKYAPDUFactory_ListPINs(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_Logout(CKYAPDU *apdu, CKYByte pinNumber);
-+CKYStatus CKYAPDUFactory_WriteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset,CKYSize size,CKYBuffer *data);
-+/* Future add WriteObject */
-+CKYStatus CKYAPDUFactory_CreateObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYSize size, unsigned short readACL, unsigned short writeACL,
-+ unsigned short deleteACL);
-+CKYStatus CKYAPDUFactory_DeleteObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYByte zero);
-+CKYStatus CKYAPDUFactory_ReadObject(CKYAPDU *apdu, unsigned long objectID,
-+ CKYOffset offset, CKYByte size);
-+CKYStatus CKYAPDUFactory_ListObjects(CKYAPDU *apdu, CKYByte sequence);
-+CKYStatus CKYAPDUFactory_GetStatus(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_Noop(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_GetBuildID(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_GetLifeCycle(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_GetLifeCycleV2(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_GetRandom(CKYAPDU *apdu, CKYByte len);
-+CKYStatus CKYAPDUFactory_SeedRandom(CKYAPDU *apdu, const CKYBuffer *data);
-+CKYStatus CKYAPDUFactory_GetIssuerInfo(CKYAPDU *apdu);
-+CKYStatus CKYAPDUFactory_GetBuiltinACL(CKYAPDU *apdu);
-+
-+CKYStatus CACAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte type,
-+ const CKYBuffer *data);
-+CKYStatus CACAPDUFactory_GetCertificate(CKYAPDU *apdu, CKYSize size);
-+CKYStatus CACAPDUFactory_ReadFile(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte type, CKYByte count);
-+CKYStatus CACAPDUFactory_GetProperties(CKYAPDU *apdu);
-+
-+CKYStatus PIVAPDUFactory_GetData(CKYAPDU *apdu, const CKYBuffer *object,
-+ CKYByte count);
-+CKYStatus PIVAPDUFactory_SignDecrypt(CKYAPDU *apdu, CKYByte chain, CKYByte alg,
-+ CKYByte key, int len, const CKYBuffer *data);
-+
-+CKYStatus P15APDUFactory_VerifyPIN(CKYAPDU *apdu, CKYByte keyRef,
-+ const CKYBuffer *pin);
-+CKYStatus P15APDUFactory_ReadRecord(CKYAPDU *apdu, CKYByte record,
-+ CKYByte short_ef, CKYByte flags, CKYByte count);
-+CKYStatus P15APDUFactory_ReadBinary(CKYAPDU *apdu, unsigned short offset,
-+ CKYByte short_ef, CKYByte flags, CKYByte count);
-+CKYStatus P15APDUFactory_ManageSecurityEnvironment(CKYAPDU *apdu,
-+ CKYByte p1, CKYByte p2, CKYByte key);
-+CKYStatus P15APDUFactory_PerformSecurityOperation(CKYAPDU *apdu, CKYByte dir,
-+ int chain, CKYSize retLen, const CKYBuffer *data);
-+
-+
-+CKY_END_PROTOS
-+
-+#endif /* CKY_FACTORY_H */
-diff -up ./esc/src/lib/coolkey/cky_list.h.fix1 ./esc/src/lib/coolkey/cky_list.h
---- ./esc/src/lib/coolkey/cky_list.h.fix1 2018-04-26 11:44:38.442986163 -0700
-+++ ./esc/src/lib/coolkey/cky_list.h 2018-04-26 11:44:38.442986163 -0700
-@@ -0,0 +1,75 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_LIST_H
-+#define CKY_LIST_H 1
-+/*
-+ * Macro to declare methods and types for CoolKey Lists.
-+ */
-+#define CKYLIST_DECLARE(name, type) \
-+typedef void *name##List; \
-+typedef void *name##Iterator; \
-+ \
-+CKY_BEGIN_PROTOS \
-+/* get the number of elements in the name##List */ \
-+unsigned long name##List_GetCount(name##List list); \
-+ \
-+/* returns the 'index'th element of the list. \
-+ * This provides one way of walking the list... \
-+ * \
-+ * // acquire name##List list \
-+ * int count; \
-+ * int i; \
-+ * \
-+ * count = name##List_GetCount(list); \
-+ * for (i=0; i < count; i++) { \
-+ * const type value = name##List_GetValue(list, i); \
-+ * \
-+ * // Process value \
-+ * } \
-+ */ \
-+const type name##List_GetValue(name##List list, unsigned long index); \
-+ \
-+/* * Destroy a list */ \
-+void name##List_Destroy(name##List list); \
-+ \
-+/* \
-+ * The following iterators allows someone to easily walk the list using \
-+ * the following sample code. These functions hide the underlying \
-+ * implementation. \
-+ * \
-+ * // acquire name##List list \
-+ * name##Iterator iter; \
-+ * \
-+ * for (iter = name##List_GetIterator(list); !name##Iterator_End(inter); \
-+ * iter = name##Interator_Next(iter) ) { \
-+ * const type value = name##Interator_GetValue(iter); \
-+ * \
-+ * // Process value \
-+ * } \
-+ * \
-+ */ \
-+name##Iterator name##List_GetIterator(name##List list); \
-+CKYBool name##Iterator_End(name##Iterator iter); \
-+name##Iterator name##Iterator_Next(name##Iterator iter); \
-+const type name##Iterator_GetValue(name##Iterator iter); \
-+CKY_END_PROTOS \
-+/* end of Declarations */
-+
-+#endif /* CKY_LIST_H */
-diff -up ./esc/src/lib/coolkey/cky_list.i.fix1 ./esc/src/lib/coolkey/cky_list.i
---- ./esc/src/lib/coolkey/cky_list.i.fix1 2018-04-26 11:44:38.442986163 -0700
-+++ ./esc/src/lib/coolkey/cky_list.i 2018-04-26 11:44:38.442986163 -0700
-@@ -0,0 +1,145 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifndef CKY_LIST_I
-+#define CKY_LIST_I 1
-+
-+#define CKYLIST_IMPLEMENT(name,type) \
-+ \
-+/* \
-+ * name##List is implemented as a pointer to a NULL terminated array of \
-+ * type##s. A NULL name##List is valid and means a list with '0' elements \
-+ * The actual type is a void * and the follow functions are designed to \
-+ * hide the underlying structure of name##List. \
-+ */ \
-+ \
-+/* get the number of elements in the reader List */ \
-+unsigned long \
-+name##List_GetCount(name##List list) \
-+{ \
-+ type *current; \
-+ int count; \
-+ \
-+ if (list == NULL) { \
-+ return 0; \
-+ } \
-+ \
-+ for (count=0, current = (type *)list; *current; current++, count++) { \
-+ /* EMPTY */ ; \
-+ } \
-+ \
-+ return count; \
-+} \
-+ \
-+ \
-+/* returns the 'index'th element of the list. \
-+ * index is not checked for overruns in this implementation. \
-+ * \
-+ * This provides one way of walking the list... \
-+ * \
-+ * // acquire name##List list \
-+ * int count; \
-+ * int i; \
-+ * \
-+ * count = name##List_GetCount(list); \
-+ * for (i=0; i < count; i++) { \
-+ * const type value = name##List_GetValue(list, i); \
-+ * \
-+ * // Process value \
-+ * } \
-+ */ \
-+const type \
-+name##List_GetValue(name##List list, unsigned long index) \
-+{ \
-+ type *array = (type *)list; \
-+ \
-+ /* should probably be an assert */ \
-+ if (list == NULL) { \
-+ return NULL; \
-+ } \
-+ return array[index]; \
-+} \
-+ \
-+/* Destroy a list */ \
-+void \
-+name##List_Destroy(name##List list) \
-+{ \
-+ type *cur; \
-+ if (list == NULL) { \
-+ return ; \
-+ } \
-+ \
-+ for (cur =(type *)list; *cur; cur++) { \
-+ name##_Destroy(*cur); \
-+ } \
-+ free(list); \
-+} \
-+ \
-+/* \
-+ * The following iterators allows someone to easily walk the list using \
-+ * the following sample code. These functions hide the underlying \
-+ * implementation. \
-+ * \
-+ * // acquire name##List list \
-+ * name##Iterator iter; \
-+ * \
-+ * for (iter = name##List_GetIterator(list); !name##Iterator_End(inter); \
-+ * iter = name##Iterator_Next(iter) ) { \
-+ * const type value = name##Iterator_GetValue(iter); \
-+ * // process value \
-+ * } \
-+ * \
-+ */ \
-+name##Iterator \
-+name##List_GetIterator(name##List list) \
-+{ \
-+ return (name##Iterator) list; \
-+} \
-+ \
-+CKYBool \
-+name##Iterator_End(name##Iterator iter) \
-+{ \
-+ if (iter == NULL) { \
-+ return 1; \
-+ } \
-+ return *(type *)iter == NULL; \
-+} \
-+ \
-+name##Iterator \
-+name##Iterator_Next(name##Iterator iter) \
-+{ \
-+ if (iter == NULL) { \
-+ return NULL; \
-+ } \
-+ return (name##Iterator) (((type *)iter)+1); \
-+} \
-+ \
-+const type \
-+name##Iterator_GetValue(name##Iterator iter) \
-+{ \
-+ /* assert(iter != NULL); */ \
-+ return *(type *)iter; \
-+} \
-+ \
-+/* \
-+ * add functions to create lists, & add elements to lists \
-+ */ \
-+
-+
-+#endif /* CKY_LIST_I */
-diff -up ./esc/src/lib/coolkey/CoolKey.cpp.fix1 ./esc/src/lib/coolkey/CoolKey.cpp
---- ./esc/src/lib/coolkey/CoolKey.cpp.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/CoolKey.cpp 2018-04-26 11:44:38.443986158 -0700
-@@ -22,8 +22,6 @@
-
- #include "prthread.h"
- #include "pk11func.h"
--#include "cky_base.h"
--#include "cky_applet.h"
-
- #include "NSSManager.h"
- #include "CoolKeyHandler.h"
-@@ -475,6 +473,268 @@ HRESULT CoolKeyNotify(const CoolKey *aKe
- return S_OK;
- }
-
-+HRESULT CoolKeyGetCUIDDirectly(char *aBuff, int aBuffLen, const char *readerName) {
-+
-+ CKYBuffer cuid;
-+ CKYBuffer_InitEmpty(&cuid);
-+ CKYCardConnection *conn = NULL;
-+ CKYStatus status;
-+ HRESULT result = E_FAIL;
-+ CKYCardContext *cardCtxt = NULL;
-+ CKYISOStatus apduRC = 0;
-+
-+ const CKYByte * cuidBytes = NULL;
-+
-+
-+ if ( !aBuff || aBuffLen < 25 || !readerName)
-+ {
-+ goto done;
-+ }
-+
-+ cardCtxt = CKYCardContext_Create(SCARD_SCOPE_USER);
-+ assert(cardCtxt);
-+ if (!cardCtxt) {
-+ goto done;
-+ }
-+
-+ conn = CKYCardConnection_Create(cardCtxt);
-+ assert(conn);
-+ if (!conn) {
-+ goto done;
-+ }
-+
-+ status = CKYCardConnection_Connect(conn, readerName);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ CKYCardConnection_BeginTransaction(conn);
-+
-+ status = CKYApplet_GetCUID(conn, &cuid, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ cuidBytes = CKYBuffer_Data(&cuid);
-+
-+ result = CoolKeyBinToHex(cuidBytes,
-+ CKYBuffer_Size(&cuid),
-+ (unsigned char *) aBuff,
-+ aBuffLen,
-+ 1);
-+
-+ result = S_OK;
-+done:
-+
-+ if (conn) {
-+ CKYCardConnection_EndTransaction(conn);
-+ CKYCardConnection_Disconnect(conn);
-+ CKYCardConnection_Destroy(conn);
-+ }
-+ if (cardCtxt) {
-+ CKYCardContext_Destroy(cardCtxt);
-+ }
-+
-+ CKYBuffer_FreeData(&cuid);
-+
-+ return result;
-+
-+
-+}
-+
-+HRESULT CoolKeyGetATRDirectly(char *aBuff, int aBuffLen,const char *readerName) {
-+
-+ CKYBuffer ATR;
-+ CKYBuffer_InitEmpty(&ATR);
-+ CKYCardConnection *conn = NULL;
-+ CKYStatus status;
-+ HRESULT result = E_FAIL;
-+ CKYCardContext *cardCtxt = NULL;
-+
-+ const CKYByte * atrBytes = NULL;
-+
-+ if ( !aBuff || aBuffLen < 25 || !readerName)
-+ {
-+ goto done;
-+ }
-+
-+ cardCtxt = CKYCardContext_Create(SCARD_SCOPE_USER);
-+ assert(cardCtxt);
-+ if (!cardCtxt) {
-+ goto done;
-+ }
-+
-+ conn = CKYCardConnection_Create(cardCtxt);
-+ assert(conn);
-+ if (!conn) {
-+ goto done;
-+ }
-+
-+ status = CKYCardConnection_Connect(conn, readerName);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ CKYCardConnection_BeginTransaction(conn);
-+ unsigned long state;
-+
-+ status = CKYCardConnection_GetStatus(conn, &state, &ATR);
-+ if (status != CKYSUCCESS) {
-+ result = E_FAIL;
-+ goto done;
-+ }
-+
-+ atrBytes = CKYBuffer_Data(&ATR);
-+
-+ result = CoolKeyBinToHex(atrBytes,
-+ CKYBuffer_Size(&ATR),
-+ (unsigned char *) aBuff,
-+ aBuffLen,
-+ 1);
-+
-+
-+ if(result != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ result = S_OK;
-+ done:
-+
-+ if (conn) {
-+ CKYCardConnection_EndTransaction(conn);
-+ CKYCardConnection_Disconnect(conn);
-+ CKYCardConnection_Destroy(conn);
-+ }
-+ if (cardCtxt) {
-+ CKYCardContext_Destroy(cardCtxt);
-+ }
-+
-+ CKYBuffer_FreeData(&ATR);
-+
-+ return result;
-+}
-+
-+HRESULT CoolKeyGetLifeCycleDirectly(CKYByte *personalized,const char *readerName) {
-+ CKYCardConnection *conn = NULL;
-+ CKYStatus status;
-+ HRESULT result = E_FAIL;
-+
-+ CKYISOStatus apduRC = 0;
-+
-+ CKYCardContext *cardCtxt = NULL;
-+
-+ if ( personalized == NULL || !readerName)
-+ {
-+ goto done;
-+ }
-+
-+ cardCtxt = CKYCardContext_Create(SCARD_SCOPE_USER);
-+ assert(cardCtxt);
-+ if (!cardCtxt) {
-+ goto done;
-+ }
-+
-+ conn = CKYCardConnection_Create(cardCtxt);
-+ assert(conn);
-+ if (!conn) {
-+ goto done;
-+ }
-+
-+ status = CKYCardConnection_Connect(conn, readerName);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ CKYCardConnection_BeginTransaction(conn);
-+ unsigned long state;
-+ status = CKYApplet_SelectCoolKeyManager(conn, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ *personalized = 0xff;
-+ goto done;
-+ }
-+
-+ //We know we have selected the applet, even if the subsequent
-+ // LifeCycle call fails.
-+ *personalized = 0x7;
-+ status = CKYApplet_GetLifeCycle(conn, personalized,&apduRC);
-+
-+ if(result != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ result = S_OK;
-+ done:
-+
-+ if (conn) {
-+ CKYCardConnection_EndTransaction(conn);
-+ CKYCardConnection_Disconnect(conn);
-+ CKYCardConnection_Destroy(conn);
-+ }
-+ if (cardCtxt) {
-+ CKYCardContext_Destroy(cardCtxt);
-+ }
-+
-+ return result;
-+}
-+
-+HRESULT CoolKeyGetCPLCDataDirectly(CKYAppletRespGetCPLCData *cplc,const char *readerName) {
-+
-+ CKYCardConnection *conn = NULL;
-+ CKYStatus status;
-+ HRESULT result = E_FAIL;
-+ CKYISOStatus apduRC = 0;
-+ CKYCardContext *cardCtxt = NULL;
-+
-+ if ( cplc == NULL || !readerName)
-+ {
-+ goto done;
-+ }
-+
-+ cardCtxt = CKYCardContext_Create(SCARD_SCOPE_USER);
-+ assert(cardCtxt);
-+ if (!cardCtxt) {
-+ goto done;
-+ }
-+
-+ conn = CKYCardConnection_Create(cardCtxt);
-+ assert(conn);
-+ if (!conn) {
-+ goto done;
-+ }
-+
-+ status = CKYCardConnection_Connect(conn, readerName);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ CKYCardConnection_BeginTransaction(conn);
-+ unsigned long state;
-+
-+ status = CKYApplet_SelectCardManager(conn, &apduRC);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ status = CKYApplet_GetCPLCData(conn, cplc,
-+ &apduRC);
-+ if (status != CKYSUCCESS) {
-+ goto done;
-+ }
-+
-+ result = S_OK;
-+ done:
-+
-+ if (conn) {
-+ CKYCardConnection_EndTransaction(conn);
-+ CKYCardConnection_Disconnect(conn);
-+ CKYCardConnection_Destroy(conn);
-+ }
-+ if (cardCtxt) {
-+ CKYCardContext_Destroy(cardCtxt);
-+ }
-+
-+ return result;
-+}
-
-
- static std::list g_ActiveKeyList;
-diff -up ./esc/src/lib/coolkey/CoolKeyHandler.cpp.fix1 ./esc/src/lib/coolkey/CoolKeyHandler.cpp
---- ./esc/src/lib/coolkey/CoolKeyHandler.cpp.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/CoolKeyHandler.cpp 2018-04-26 11:44:38.445986146 -0700
-@@ -44,6 +44,8 @@
- #include "CoolKeyHandler.h"
- #include "SlotUtils.h"
-
-+static const char *cac_manu_id= "Common Access Card";
-+static const char *piv_manu_id= "piv II ";
-
- //static char *test_extended_login = "s=325&msg_type=13&invalid_login=0&blocked=0&error=&required_parameter0=id%3DUSER%5FID%26name%3DUser+ID%26desc%3DUser+ID%26type%3Dstring%26option%3Doption1%2Coption2%2Coption3&required_parameter1=id%3DUSER%5FPWD%26name%3DUser+Password%26desc%3DUser+Password%26type%3Dpassword%26option%3D&required_parameter2=id%3DUSER%5FPIN%26name%3DPIN%26desc%3DOne+time+PIN+received+via+mail%26type%3Dpassword%26option%3D";
-
-@@ -1141,12 +1143,10 @@ HRESULT CoolKeyHandler::HttpBeginOpReque
- const char *atr = GetATRForKeyID(&mKey);
- if (!atr )
- {
-- HttpDisconnect();
-- RemoveKeyFromActiveKeyList(&mKey);
-- return E_FAIL;
-+ sprintf(buffer,"tokenATR=%s","unknown-atr");
-+ } else {
-+ sprintf(buffer,"tokenATR=%s",atr);
- }
--
-- sprintf(buffer,"tokenATR=%s",atr);
-
- ext_buffer = buffer;
-
-@@ -1190,6 +1190,41 @@ HRESULT CoolKeyHandler::HttpBeginOpReque
- }
- }
-
-+CKYBuffer *CoolKeyHandler::processTokenPDU(CoolKeyHandler *context, CKYAPDU *apdu)
-+{
-+ char tBuff[56];
-+ CKYStatus status = CKYSUCCESS;
-+ PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CoolKeyHandler::processTokenPDU:\n",GetTStamp(tBuff,56)));
-+ if(!apdu || !context)
-+ {
-+ CoolKeyLogMsg( PR_LOG_ERROR, "%s apdu message. Bad input data. \n",GetTStamp(tBuff,56));
-+ return NULL;
-+ }
-+
-+ CKYBuffer *response = NULL;
-+ status = CKYBuffer_InitEmpty(response);
-+
-+ if(status != CKYSUCCESS) {
-+ CoolKeyLogMsg( PR_LOG_ERROR, "%s apdu message. Out of memory. \n",GetTStamp(tBuff,56));
-+ return NULL;
-+ }
-+
-+ status = CKYCardConnection_ExchangeAPDU(context->GetCardConnection(),
-+ apdu, response);
-+
-+ if (status != CKYSUCCESS) {
-+ CoolKeyLogMsg( PR_LOG_ERROR,
-+ "%s Processing apdu message. Can't write apdu to card! status %d response[0] %x response[1] %x error %d \n"
-+ ,GetTStamp(tBuff,56) ,status,CKYBuffer_GetChar(response,0),CKYBuffer_GetChar(response,1),
-+ CKYCardConnection_GetLastError(context->GetCardConnection()));
-+
-+ return response;
-+ }
-+
-+ return response;
-+
-+}
-+
- void CoolKeyHandler::HttpProcessTokenPDU(CoolKeyHandler *context,eCKMessage_TOKEN_PDU_REQUEST *req)
- {
- char tBuff[56];
-@@ -1606,7 +1641,12 @@ void CoolKeyHandler::HttpProcessEndOp(Co
- void NotifyEndResult(CoolKeyHandler* context, int operation, int result, int description)
- {
- char tBuff[56];
-- RefreshInfoFlagsForKeyID(context->GetAutoCoolKey());
-+
-+ CoolKeyInfo *info = GetCoolKeyInfoByKeyID(context->GetAutoCoolKey());
-+ CKHGetCoolKeyInfo(info->mSlot,info);
-+
-+
-+ //RefreshInfoFlagsForKeyID(context->GetAutoCoolKey());
-
- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CoolKeyHandler::NotifyEndResult context %p op %d result %d description %d:\n",GetTStamp(tBuff,56),context,operation,result,description));
-
-@@ -2024,14 +2064,14 @@ getCUIDFromTokenInfo(CK_TOKEN_INFO *toke
- isxdigit(tokenInfo->manufacturerID[3]) ) {
- // one format has top 2 bytes of CUID (4 hex digits) in manufacturer,
- // and the rest in the module
-- cp = copySerialNumber(cp, (const char *)tokenInfo->manufacturerID, 4);
-- cp = copySerialNumber(cp,(const char *)tokenInfo->model,
-- sizeof(tokenInfo->model));
-+ cp = copySerialNumber(cp, (const char *)tokenInfo->manufacturerID, 2);
-+ cp = copySerialNumber(cp,(const char *)tokenInfo->serialNumber,
-+ sizeof(tokenInfo->serialNumber));
- } else {
- // otherwise it's just the concatenation of the model and serial
- // fields
- cp = copySerialNumber(cp, (const char *)tokenInfo->model,
-- sizeof(tokenInfo->model));
-+ 2);
- cp = copySerialNumber(cp, (const char *)tokenInfo->serialNumber,
- sizeof(tokenInfo->serialNumber));
- }
-@@ -2055,126 +2095,155 @@ CKHGetInfoFlags(PK11SlotInfo *aSlot)
- }
-
- CoolKeyInfo *
--CKHGetCoolKeyInfo(PK11SlotInfo *aSlot)
-+CKHGetCoolKeyInfo(PK11SlotInfo *aSlot,CoolKeyInfo *currentInfo)
- {
- char tBuff[56];
- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo:\n",GetTStamp(tBuff,56)));
-- PK11GenericObject *obj = NULL;
- SECItem label, ATR;
- CK_TOKEN_INFO tokenInfo;
- CoolKeyInfo *info = NULL;
- SECStatus status;
-- HRESULT hres;
-- int atrSize;
-- char *atrString;
-- SECItem isCOOLKey;
-+ HRESULT hres,atrRes,cuidRes,cycleRes;
-
-+ CKYBuffer cardATR;
-+ CKYBuffer_InitEmpty(&cardATR);
-+ char *readerName = PK11_GetSlotName(aSlot);
-+
- memset((void *) &tokenInfo,0,sizeof(tokenInfo));
- ATR.data = NULL; // initialize for error processing
- label.data = NULL; // initialize for error processing
-- isCOOLKey.data = NULL;
-
-
- int isACOOLKey = 0;
-+ int isACAC = 0;
-+ int isAPIV = 0;
-
-- /* if it's one of "ours" it'll have a reader object */
-- obj = PK11_FindGenericObjects(aSlot, CKO_MOZILLA_READER);
-- if (obj == NULL) {
-- goto failed;
-- }
-+ int hasApplet = 0;
-+ int isPersonalized = 0;
-
-- // get the reader name (though we probably don't need it anymore
-- status = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_LABEL, &label);
-- if (status != SECSuccess) {
-- goto failed;
-- }
-+ CKYByte lifeCycle = 0;
-+
-+ char atrChar[100];
-+ memset((void*) atrChar,0,sizeof(atrChar));
-+
-+ char cuidChar[100];
-+ memset((void*) cuidChar,0 ,sizeof(cuidChar));
-
-- // get the ATR (though, again, we probably don't need it
-- status = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_MOZILLA_ATR, &ATR);
-- // PK11_DestroyGenericObjects(obj);
-- if (status != SECSuccess) {
-- goto failed;
-- }
- // get the CUID/Serial number (we *WILL* continue to need it )
- status = PK11_GetTokenInfo(aSlot,&tokenInfo);
- if (status != SECSuccess) {
- goto failed;
- }
-
-- //get the are we a CoolKey value
-+ tokenInfo.flags=0; //Ignore what opensc says, get the info ourselves later.
-+ //Get the life cycle state:
-
-- status = PK11_ReadRawAttribute(PK11_TypeGeneric, obj, CKA_MOZILLA_IS_COOL_KEY, &isCOOLKey);
-+ cycleRes = CoolKeyGetLifeCycleDirectly(&lifeCycle,readerName);
-
-- PK11_DestroyGenericObjects(obj);
-- obj = NULL;
-+ if(lifeCycle == 0x7) { // applet only
-+ hasApplet = 1;
-+ }
-
-- if (status != SECSuccess) {
-- goto failed;
-+ if(lifeCycle == 0xF) { //personalized
-+ hasApplet = 1;
-+ isPersonalized = 1;
- }
-
-- if(isCOOLKey.len == 1)
-- {
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: CKA_MOZILLA_IS_COOL_KEY %d.\n",GetTStamp(tBuff,56),(int) isCOOLKey.data[0]));
-+ //Let's see if we can get the ATR by force explicitly
-+
-+ atrRes = CoolKeyGetATRDirectly(atrChar,100,readerName);
-
-- isACOOLKey=(int) isCOOLKey.data[0];
-- }
-+ if(atrRes == E_FAIL) {
-+ goto failed;
-+ }
-
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->flags %u.\n",GetTStamp(tBuff,56),tokenInfo.flags));
--
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->label %s.\n",GetTStamp(tBuff,56),(char *)tokenInfo.label));
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->manufacturerID %s.\n",GetTStamp(tBuff,56),(char *)tokenInfo.manufacturerID));
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->model %s.\n",GetTStamp(tBuff,56),(char *)tokenInfo.model));
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->serialNumber %s.\n",GetTStamp(tBuff,56),(char *)tokenInfo.serialNumber));
-+ // Figure out the token type by process of elimination
-+ // CAC has a manu id of "Common Access Card" and
-+ // PIV has a manu id of "piv II "
-+
-+ // Since we are configured to only be notified of coolkey's, cac's and piv's
-+ // non blank coolkeys will be identified by NOT being cac or piv in the manu id field.
-+
-+ if(!strcmp((const char *) tokenInfo.manufacturerID,cac_manu_id)) {
-+ isACAC = 1;
-+ } else if(!strcmp((const char *) tokenInfo.manufacturerID, piv_manu_id)) {
-+ isAPIV = 1;
-+ } else {
-+ isACOOLKey = 1;
-+ }
-
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->firmwareVersion.major %d info->firmwareVersion.minor %d \n",GetTStamp(tBuff,56),(int)tokenInfo.firmwareVersion.major,(int) tokenInfo.firmwareVersion.minor));
-+ // OK, we have everything we need, now build the COOLKEYInfo structure.
-+ // either create a new one or use the one we have already and refresh it
-+ if(currentInfo == NULL) {
-+ info = new CoolKeyInfo();
-+ } else {
-+ info = currentInfo;
-
-+ if(info->mReaderName) {
-+ free(info->mReaderName);
-+ }
-+ if(info->mCUID) {
-+ free(info->mCUID);
-+ }
-+ if(info->mATR) {
-+ free(info->mATR);
-+ }
-+ info->mInfoFlags = 0;
-+ }
-
-- // OK, we have everything we need, now build the COOLKEYInfo structure.
-- info = new CoolKeyInfo();
- if (!info) {
- goto failed;
- }
-
-- atrSize = ATR.len*2+5;
-- atrString = (char *)malloc(atrSize);
-- hres = CoolKeyBinToHex(ATR.data, ATR.len,
-- (unsigned char *) atrString, atrSize, true);
-- /* shouldn't the be != S_SUCCESS? */
-- if (hres == E_FAIL) {
-- free(atrString);
-- goto failed;
-+ //Massage the tokenInfo so it adhered to when coolkey was doing it.
-+ if(hasApplet) {
-+ tokenInfo.firmwareVersion.major = 1;
- }
-- SECITEM_FreeItem(&ATR,PR_FALSE);
-- ATR.data = NULL;
-
-+ if(isPersonalized) {
-+ tokenInfo.flags |= CKF_TOKEN_INITIALIZED;
-+ }
-
-- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: info->atr %s.\n",GetTStamp(tBuff,56),(char *)atrString));
-+ info->mInfoFlags = MapGetFlags(&tokenInfo);
-
-+ info->mReaderName = strdup(readerName);
-
-- info->mATR = atrString;
-- info->mReaderName= (char *)malloc(label.len+1);
-- if (!info->mReaderName) {
-- goto failed;
-+ info->mCUID = (char *)malloc(35); /* should be a define ! */
-+
-+ if(strlen(atrChar) > 0) {
-+ info->mATR = strdup(atrChar);
- }
-- memcpy(info->mReaderName, label.data, label.len);
-- info->mReaderName[label.len] = 0;
-- info->mInfoFlags = MapGetFlags(&tokenInfo);
-
-- info->mCUID = (char *)malloc(35); /* should be a define ! */
- if (!info->mCUID) {
- goto failed;
- }
-+
- hres = getCUIDFromTokenInfo(&tokenInfo, info->mCUID);
- /* shouldn't the be != S_SUCCESS? */
- if (hres == E_FAIL) {
- goto failed;
- }
-
-+ //Check for blank cuid and put something there
-+
-+ if(isACOOLKey && strlen(info->mCUID) == 0 )
-+ {
-+ //Let's try to get the cuid directly from the token.
-+
-+ cuidRes = CoolKeyGetCUIDDirectly(cuidChar, 100, readerName);
-+
-+ if(cuidRes != S_OK) {
-+ strcpy(info->mCUID, "blank-token");
-+ } else {
-+ strcpy(info->mCUID, cuidChar);
-+ }
-+ }
-+
- PR_LOG( coolKeyLogHN, PR_LOG_DEBUG, ("%s CKHGetCoolKeyInfo: tokenInfo.label length %d.\n",GetTStamp(tBuff,56),strlen((char *) tokenInfo.label)));
-
- // Give the CAC card some sort of unique key ID
-
-- if(strlen(info->mCUID) == 0)
-+ if(isACAC && strlen(info->mCUID) == 0)
- {
- strncpy(info->mCUID,(char *)tokenInfo.label,35);
- info->mCUID[34] = 0;
-@@ -2186,26 +2255,20 @@ CKHGetCoolKeyInfo(PK11SlotInfo *aSlot)
- info->mInfoFlags |= COOLKEY_INFO_IS_REALLY_A_COOLKEY_MASK;
- }
-
-- SECITEM_FreeItem(&ATR,PR_FALSE);
- SECITEM_FreeItem(&label,PR_FALSE);
-- SECITEM_FreeItem(&isCOOLKey,PR_FALSE);
-
- info->mSlot = PK11_ReferenceSlot(aSlot);
- info->mSeries = PK11_GetSlotSeries(aSlot);
- return info;
-
- failed:
-- if (ATR.data) {
-- SECITEM_FreeItem(&ATR,PR_FALSE);
-- }
- if (label.data) {
- SECITEM_FreeItem(&label,PR_FALSE);
- }
-- if (obj) {
-- PK11_DestroyGenericObjects(obj);
-- }
- if (info) {
- delete info;
- }
-+
-+ CKYBuffer_FreeData(&cardATR);
- return NULL;
- }
-diff -up ./esc/src/lib/coolkey/CoolKeyHandler.h.fix1 ./esc/src/lib/coolkey/CoolKeyHandler.h
---- ./esc/src/lib/coolkey/CoolKeyHandler.h.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/CoolKeyHandler.h 2018-04-26 11:44:38.445986146 -0700
-@@ -115,7 +115,10 @@ class CoolKeyHandler
- HRESULT Renew(void);
- HRESULT Format(const char *aTokenType);
- HRESULT Disconnect();
--
-+
-+ //APDU related
-+
-+ CKYBuffer *processTokenPDU(CoolKeyHandler *context, CKYAPDU *apdu);
-
- //Http Related
-
-@@ -259,7 +262,7 @@ eCKMessage *AllocateMessage(eCKMessage::
-
-
- void DisplayEndDialog(int operation, int result, int description);
--CoolKeyInfo *CKHGetCoolKeyInfo(PK11SlotInfo *aSlot);
-+CoolKeyInfo *CKHGetCoolKeyInfo(PK11SlotInfo *aSlot,CoolKeyInfo *currentInfo);
- unsigned int CKHGetInfoFlags(PK11SlotInfo *aSlot);
-
- #endif /* CoolKeyHandler.h__ */
-diff -up ./esc/src/lib/coolkey/CoolKey.h.fix1 ./esc/src/lib/coolkey/CoolKey.h
---- ./esc/src/lib/coolkey/CoolKey.h.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/CoolKey.h 2018-04-26 11:44:38.446986140 -0700
-@@ -32,6 +32,9 @@
- #include
- #include
-
-+#include "cky_base.h"
-+#include "cky_applet.h"
-+
- ////////////////////////////////////////////////////////////////////////
- //
- // Public Structures and Functions:
-@@ -185,7 +188,6 @@ COOLKEY_API HRESULT CoolKeyInitializeLog
- COOLKEY_API HRESULT CoolKeyLogMsg(int logLevel, const char *fmt, ...);
-
- COOLKEY_API HRESULT CoolKeyLogNSSStatus();
--
- //Utility time function
- char *GetTStamp(char *aTime,int aSize);
- }
-@@ -262,8 +264,10 @@ const char *CoolKeyGetKeyID(const char *
- const char *CoolKeyGetConfig(const char *aName);
- HRESULT CoolKeySetConfig(const char *aName,const char *aValue);
- CoolKeyBadCertHandler CoolKeyGetBadCertHandler();
--
--
-+HRESULT CoolKeyGetATRDirectly(char *aBuff, int aBuffLen, const char *readerName);
-+HRESULT CoolKeyGetCUIDDirectly(char *aBuff, int aBuffLen, const char *readerName);
-+HRESULT CoolKeyGetCPLCDataDirectly(CKYAppletRespGetCPLCData *cplc,const char *readerName);
-+HRESULT CoolKeyGetLifeCycleDirectly(CKYByte *personalized,const char *readerName);
-
- }
-
-diff -up ./esc/src/lib/coolkey/CoolKey_Message.cpp.fix1 ./esc/src/lib/coolkey/CoolKey_Message.cpp
---- ./esc/src/lib/coolkey/CoolKey_Message.cpp.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/CoolKey_Message.cpp 2018-04-26 11:44:38.446986140 -0700
-@@ -941,7 +941,7 @@ void eCKMessage_BEGIN_OP::encode(string
-
- int size = extensions.length();
-
-- if(aOutputVal[size -1 ] == '&')
-+ if(extensions[size -1 ] == '&')
- {
- extensions.erase(size -1);
- }
-diff -up ./esc/src/lib/coolkey/dynlink.c.fix1 ./esc/src/lib/coolkey/dynlink.c
---- ./esc/src/lib/coolkey/dynlink.c.fix1 2018-04-26 11:44:38.447986134 -0700
-+++ ./esc/src/lib/coolkey/dynlink.c 2018-04-26 11:44:38.447986134 -0700
-@@ -0,0 +1,37 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#ifdef HAVE_CONFIG_H
-+#include
-+#endif
-+
-+#ifdef WIN32
-+#include "dynlink_win.c"
-+#else
-+#ifdef MAC
-+#include "dynlink_mac.c"
-+#else
-+#ifdef HAVE_DLFCN_H
-+#include "dynlink_unix.c"
-+#else
-+#error "Platform not supported... add dynlink_PLAT.c and update dynlink.c"
-+#endif
-+#endif
-+#endif
-+
-diff -up ./esc/src/lib/coolkey/dynlink.h.fix1 ./esc/src/lib/coolkey/dynlink.h
---- ./esc/src/lib/coolkey/dynlink.h.fix1 2018-04-26 11:44:38.447986134 -0700
-+++ ./esc/src/lib/coolkey/dynlink.h 2018-04-26 11:44:38.447986134 -0700
-@@ -0,0 +1,54 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+/*
-+ * the following header file is private to the CoolKey library.
-+ * This is because CoolKey library is supposed to operate in the PKCS #11
-+ * module which needs to be independent of runtimes like NSPR. Longer term
-+ * there should be a generic version of this which uses the application
-+ * runtime, and pkcs #11 supplies it's only copy of these functions.
-+ */
-+#ifndef CKY_SHLIB_H
-+#define CKY_SHLIB_H 1
-+
-+#undef QUOTE
-+#undef QUOTE_MACRO
-+#define QUOTE(arg) #arg
-+#define QUOTE_MACRO(arg) QUOTE(arg)
-+
-+/* Hmmm maybe this should be hidden in getAddress? */
-+#ifdef MAC
-+#define DLL_SYM_PREFIX "_"
-+#else
-+#define DLL_SYM_PREFIX
-+#endif
-+
-+#define MAKE_DLL_SYMBOL(name) DLL_SYM_PREFIX QUOTE(name)
-+
-+typedef void *ckyShLibrary;
-+
-+ckyShLibrary ckyShLibrary_open(const char *libname);
-+CKYStatus ckyShLibrary_close(ckyShLibrary libHandle);
-+CKYStatus ckyShLibrary_getAddress(ckyShLibrary libHandle,
-+ void **func, const char *funcName);
-+
-+#ifdef MAC
-+void ckyShLibrary_setParent(char *name);
-+#endif
-+#endif
-diff -up ./esc/src/lib/coolkey/dynlink_mac.c.fix1 ./esc/src/lib/coolkey/dynlink_mac.c
---- ./esc/src/lib/coolkey/dynlink_mac.c.fix1 2018-04-26 11:44:38.447986134 -0700
-+++ ./esc/src/lib/coolkey/dynlink_mac.c 2018-04-26 11:44:38.447986134 -0700
-@@ -0,0 +1,147 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ ***** END COPYRIGHT BLOCK *****/
-+
-+#include
-+#include
-+#include "cky_base.h"
-+#include "dynlink.h"
-+#include "string.h"
-+#include "stdlib.h"
-+
-+#define EXEPATH "@executable_path/"
-+#define SYSPATH "/System/Library/Frameworks/"
-+
-+static char *ckyShLibrary_parent = NULL;
-+
-+/* allow the parent library to set our name */
-+void
-+ckyShLibrary_setParent(char *p)
-+{
-+ ckyShLibrary_parent = p;
-+}
-+
-+#ifdef nodef
-+/* get the parent librarie's path */
-+char *
-+ckyShLibrary_getParentPath()
-+{
-+ char *result;
-+ char *image_name;
-+ int i, count = _dyld_image_count();
-+
-+ if (ckyShLibrary_parent == NULL) {
-+ return NULL;
-+ }
-+
-+ for (i = 0; i < count; i++) {
-+ image_name = _dyld_get_image_name(i);
-+ if (strstr(image_name, ckyShLibrary_parent) != NULL) {
-+ result = malloc(strlen(image_name)+1);
-+ if (result != NULL) {
-+ char *truncate;
-+ strcpy(result, image_name);
-+ truncate = strrchr(result,'/');
-+ if (truncate) {
-+ *(truncate+1) = 0;
-+ }
-+ }
-+ return result;
-+ }
-+ }
-+ return NULL;
-+}
-+#endif
-+
-+ckyShLibrary
-+ckyShLibrary_open(const char *libname)
-+{
-+ const struct mach_header *library;
-+ /*char *parentPath = ckyShLibrary_getParentPath(); */
-+ char *libPath = NULL;
-+ int len = sizeof(SYSPATH);
-+
-+#ifdef notdef
-+ if (parentPath) {
-+ int pLen = strlen(parentPath)+1;
-+ if (pLen > len) {
-+ len = pLen;
-+ }
-+ }
-+#endif
-+
-+ libPath = malloc(len+strlen(libname)+1);
-+ /* if we couldn't get the space, just use the LD_LIBPATH */
-+ if (libPath) {
-+#ifdef notdef
-+ /* first try the parent DLL path if known */
-+ if (parentPath) {
-+ /* then try the path of the shared library */
-+ strcpy(libPath,parentPath);
-+ strcat(libPath,libname);
-+ free(parentPath);
-+ library = NSAddImage(libPath,
-+ NSADDIMAGE_OPTION_RETURN_ON_ERROR |
-+ NSADDIMAGE_OPTION_WITH_SEARCHING);
-+ if (library) {
-+ free(libPath);
-+ return (ckyShLibrary)library;
-+ }
-+ }
-+#endif
-+ /* the try the executable's lib path */
-+ strcpy(libPath,SYSPATH);
-+ strcat(libPath,libname);
-+ library = NSAddImage(libPath,
-+ NSADDIMAGE_OPTION_RETURN_ON_ERROR |
-+ NSADDIMAGE_OPTION_WITH_SEARCHING);
-+ free(libPath);
-+ if (library) {
-+ return (ckyShLibrary)library;
-+ }
-+ }
-+
-+ /* finally grab it from the system libpath */
-+ library = NSAddImage(libname,
-+ NSADDIMAGE_OPTION_RETURN_ON_ERROR |
-+ NSADDIMAGE_OPTION_WITH_SEARCHING);
-+ return (ckyShLibrary)library;
-+}
-+
-+CKYStatus
-+ckyShLibrary_close(ckyShLibrary _lib)
-+{
-+ // Can't unload an image on Mac OS X.
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+ckyShLibrary_getAddress(const ckyShLibrary _lib, void ** func,
-+ const char *funcName)
-+{
-+ const struct mach_header *library = (const struct mach_header *)_lib;
-+ NSSymbol symbol;
-+ symbol = NSLookupSymbolInImage(library, funcName,
-+ NSLOOKUPSYMBOLINIMAGE_OPTION_BIND |
-+ NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR);
-+ if( symbol == NULL ) {
-+ return CKYLIBFAIL;
-+ }
-+ *func = NSAddressOfSymbol(symbol);
-+ return CKYSUCCESS;
-+}
-diff -up ./esc/src/lib/coolkey/dynlink_unix.c.fix1 ./esc/src/lib/coolkey/dynlink_unix.c
---- ./esc/src/lib/coolkey/dynlink_unix.c.fix1 2018-04-26 11:44:38.447986134 -0700
-+++ ./esc/src/lib/coolkey/dynlink_unix.c 2018-04-26 11:44:38.447986134 -0700
-@@ -0,0 +1,66 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#include
-+#include
-+#if !defined(MAC) && !defined(HPUX)
-+#include
-+#endif
-+#include
-+
-+#include "cky_base.h"
-+#include "dynlink.h"
-+
-+ckyShLibrary
-+ckyShLibrary_open(const char *libname)
-+{
-+ void *library;
-+
-+ library = dlopen(libname, RTLD_LAZY);
-+ return library;
-+}
-+
-+CKYStatus
-+ckyShLibrary_close(ckyShLibrary library)
-+{
-+ int rv;
-+
-+ if (library == NULL) {
-+ return CKYSUCCESS;
-+ }
-+
-+ rv = dlclose(library);
-+ if( rv != 0 ) {
-+ return CKYLIBFAIL;
-+ }
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+ckyShLibrary_getAddress(const ckyShLibrary library, void **func,
-+ const char *funcName)
-+{
-+ assert(library);
-+ void* f = dlsym(library, funcName);
-+ if( f == NULL ) {
-+ return CKYLIBFAIL;
-+ }
-+ *func = f;
-+ return CKYSUCCESS;
-+}
-diff -up ./esc/src/lib/coolkey/dynlink_win.c.fix1 ./esc/src/lib/coolkey/dynlink_win.c
---- ./esc/src/lib/coolkey/dynlink_win.c.fix1 2018-04-26 11:44:38.447986134 -0700
-+++ ./esc/src/lib/coolkey/dynlink_win.c 2018-04-26 11:44:38.447986134 -0700
-@@ -0,0 +1,66 @@
-+/* ***** BEGIN COPYRIGHT BLOCK *****
-+ * Copyright (C) 2005 Red Hat, Inc.
-+ * All rights reserved.
-+ *
-+ * 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 version
-+ * 2.1 of the License.
-+ *
-+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-+ * ***** END COPYRIGHT BLOCK ***** */
-+
-+#include
-+#include "cky_base.h"
-+#include "dynlink.h"
-+
-+
-+ckyShLibrary
-+ckyShLibrary_open(const char *libname)
-+{
-+ HMODULE library;
-+ library = LoadLibrary(libname);
-+
-+ return (ckyShLibrary) library;
-+}
-+
-+CKYStatus
-+ckyShLibrary_close(ckyShLibrary _lib)
-+{
-+ HMODULE library = (HMODULE) _lib;
-+ BOOL ret;
-+
-+ if( library == NULL ) {
-+ return CKYSUCCESS;
-+ }
-+
-+ ret = FreeLibrary(library);
-+ library = NULL;
-+
-+ if (!ret) {
-+ return CKYLIBFAIL;
-+ }
-+
-+ return CKYSUCCESS;
-+}
-+
-+CKYStatus
-+ckyShLibrary_getAddress(const ckyShLibrary _lib, void **func,
-+ const char *funcName)
-+{
-+ const HMODULE library = (const HMODULE) _lib;
-+
-+ *func = (void *)GetProcAddress(library, funcName);
-+ if (*func == NULL) {
-+ return CKYLIBFAIL;
-+ }
-+
-+ return CKYSUCCESS;
-+}
-diff -up ./esc/src/lib/coolkey/manifest.mn.fix1 ./esc/src/lib/coolkey/manifest.mn
---- ./esc/src/lib/coolkey/manifest.mn.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/manifest.mn 2018-04-26 11:44:38.448986129 -0700
-@@ -22,14 +22,13 @@ XULRUNNER_BASE=$(CORE_DEPTH)/dist/$(OBJD
- SYS_INC = /usr/include
- MODULE = ckymanager
- LIBRARY_NAME = $(MODULE)
--REQUIRES = httpchunked nss nspr ckyapplet
-+REQUIRES = httpchunked nss nspr
- ifndef MOZ_OFFSET
- MOZ_OFFSET = mozilla-1.7.13
- endif
- DEFINES += -I$(CORE_DEPTH)/esc/app/xpcom -I$(SYS_INC)/nspr4 -I$(SYS_INC)/nss3 -I$(SYS_INC)/PCSC -I$(SYS_INC)/$(MOZ_OFFSET)/nspr -I$(SYS_INC)/$(MOZ_OFFSET)/nss -I$(XULRUNNER_BASE)/dist/public/nss -I$(XULRUNNER_BASE)/dist/include/nspr -I$(GECKO_SDK_PATH)/include/nspr -I$(GECKO_SDK_PATH)/include/nss -fno-strict-aliasing
- MAPFILE = $(OBJDIR)/ckymanager.def
-
--#EXTRA_LIBS += -L$(DIST)/lib -lckyapplet
-
- CPPSRCS = \
- NSSManager.cpp \
-@@ -39,7 +38,13 @@ CPPSRCS = \
- CoolKey.cpp \
- SmartCardMonitoringThread.cpp \
- $(NULL)
--
-+CSRCS =\
-+ cky_applet.c \
-+ cky_base.c \
-+ cky_card.c \
-+ cky_factory.c \
-+ dynlink_unix.c \
-+ $(NULL)
- EXPORTS = \
- CoolKey.h \
- $(NULL)
-diff -up ./esc/src/lib/coolkey/NSSManager.cpp.fix1 ./esc/src/lib/coolkey/NSSManager.cpp
---- ./esc/src/lib/coolkey/NSSManager.cpp.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/NSSManager.cpp 2018-04-26 11:44:38.448986129 -0700
-@@ -102,7 +102,7 @@ HRESULT NSSManager::InitNSS(const char *
-
- char modSpec[512];
-
-- sprintf(modSpec,"library=\"%s\" name=\"%s\" parameters=\"%s\" NSS=\"slotParams={0x00000002=[slotFlags='PublicCerts']}\"\n",COOLKEY_PKCS11_LIBRARY,COOLKEY_NAME,PROMISCUOUS_PARAMETER);
-+ sprintf(modSpec,"library=\"%s\" name=\"%s\" NSS=\"slotParams={0x00000002=[slotFlags='PublicCerts']}\"\n",COOLKEY_PKCS11_LIBRARY,COOLKEY_NAME,PROMISCUOUS_PARAMETER);
-
- PR_LOG( coolKeyLogNSS, PR_LOG_DEBUG, ("%s InitNSS: modSpec %s\n",GetTStamp(tBuff,56),modSpec));
-
-diff -up ./esc/src/lib/coolkey/NSSManager.h.fix1 ./esc/src/lib/coolkey/NSSManager.h
---- ./esc/src/lib/coolkey/NSSManager.h.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/NSSManager.h 2018-04-26 11:44:38.458986071 -0700
-@@ -18,7 +18,7 @@
- #ifdef DARWIN
- #define COOLKEY_PKCS11_LIBRARY "/Library/Application Support/CoolKey/PKCS11/libcoolkeypk11.dylib"
- #else
--#define COOLKEY_PKCS11_LIBRARY DLL_PREFIX"coolkeypk11."DLL_SUFFIX
-+#define COOLKEY_PKCS11_LIBRARY "onepin-opensc-pkcs11."DLL_SUFFIX
- #endif
-
- #define COOLKEY_NAME "COOL Key Module"
-diff -up ./esc/src/lib/coolkey/SmartCardMonitoringThread.cpp.fix1 ./esc/src/lib/coolkey/SmartCardMonitoringThread.cpp
---- ./esc/src/lib/coolkey/SmartCardMonitoringThread.cpp.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/coolkey/SmartCardMonitoringThread.cpp 2018-04-26 11:44:38.460986059 -0700
-@@ -81,7 +81,7 @@ void SmartCardMonitoringThread::Insert(P
- PR_LOG( coolKeyLogSC, PR_LOG_DEBUG,
- ("%s SmartCardMonitoringThread::Insert Key. \n",GetTStamp(tBuff,56)));
-
-- CoolKeyInfo *info = CKHGetCoolKeyInfo(aSlot);
-+ CoolKeyInfo *info = CKHGetCoolKeyInfo(aSlot,NULL);
- if (info) {
- if (!InsertCoolKeyInfoIntoCoolKeyList(info)) {
- AutoCoolKey key(eCKType_CoolKey, info->mCUID);
-diff -up ./esc/src/lib/NssHttpClient/manifest.mn.fix1 ./esc/src/lib/NssHttpClient/manifest.mn
---- ./esc/src/lib/NssHttpClient/manifest.mn.fix1 2017-07-24 16:46:36.000000000 -0700
-+++ ./esc/src/lib/NssHttpClient/manifest.mn 2018-04-26 11:44:38.462986047 -0700
-@@ -31,7 +31,7 @@ endif
-
-
- MAPFILE = $(OBJDIR)/httpchunked.def
--DEFINES = -I$(SYS_INC)/nspr4 -I$(SYS_INC)/nss3 -I$(SYS_INC)/$(MOZ_OFFSET)/nspr -I$(SYS_INC)/$(MOZ_OFFSET)/nss -I$(XULRUNNER_BASE)/dist/public/nss -I$(XULRUNNER_BASE)/dist/include/nspr -I$(GECKO_SDK_PATH)/include/nspr -I$(GECKO_SDK_PATH)/include/nss
-+DEFINES = -I$(SYS_INC)/nspr4 -I$(SYS_INC)/nss3 -I$(SYS_INC)/$(MOZ_OFFSET)/nspr -I$(SYS_INC)/$(MOZ_OFFSET)/nss -I$(XULRUNNER_BASE)/dist/public/nss -I$(XULRUNNER_BASE)/dist/include/nspr -I$(GECKO_SDK_PATH)/include/nspr -I$(GECKO_SDK_PATH)/include/nss -I$(SYS_INC)/PCSC -I$(CORE_DEPTH)/src/lib/coolkey
-
- CPPSRCS = \
- Cache.cpp \
diff --git a/esc-1.1.1-fix2.patch b/esc-1.1.1-fix2.patch
deleted file mode 100644
index 95c2642..0000000
--- a/esc-1.1.1-fix2.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -up ./esc/src/xulrunner/xulrunner-mozconfig.fix2 ./esc/src/xulrunner/xulrunner-mozconfig
---- ./esc/src/xulrunner/xulrunner-mozconfig.fix2 2018-04-30 13:48:53.944086197 -0700
-+++ ./esc/src/xulrunner/xulrunner-mozconfig 2018-04-30 13:49:22.804921349 -0700
-@@ -37,6 +37,7 @@ ac_add_options --disable-skia
- ac_add_options --with-system-nspr
- ac_add_options --with-system-nss
- ac_add_options --disable-crashreporter
-+ac_add_options --disable-startupcache
-
- export BUILD_OFFICIAL=1
- export MOZILLA_OFFICIAL=1
diff --git a/esc-1.1.1-fix3.patch b/esc-1.1.1-fix3.patch
deleted file mode 100644
index d80da89..0000000
--- a/esc-1.1.1-fix3.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp.fix3 ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp
---- ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp.fix3 2018-06-07 18:38:45.365998075 -0700
-+++ ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp 2018-06-07 18:40:52.597296294 -0700
-@@ -10,7 +10,7 @@
-
- #include "mozilla/ArrayUtils.h"
- #include "mozilla/Attributes.h"
--
-+#include
- #include
- #include
- #include
diff --git a/esc-1.1.1-fix4.patch b/esc-1.1.1-fix4.patch
deleted file mode 100644
index 8490dd5..0000000
--- a/esc-1.1.1-fix4.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-diff -up ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/config/system-headers.fix4 ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/config/system-headers
---- ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/config/system-headers.fix4 2018-06-08 16:19:38.502459087 -0700
-+++ ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/config/system-headers 2018-06-08 16:20:33.330152105 -0700
-@@ -1067,6 +1067,7 @@ sys/statvfs.h
- sys/syscall.h
- sys/sysctl.h
- sys/sysinfo.h
-+sys/sysmacros.h
- sys/sysmp.h
- sys/syssgi.h
- sys/system_properties.h
-diff -up ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp.fix4 ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp
---- ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp.fix4 2018-06-08 16:17:21.337227098 -0700
-+++ ./esc/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/xpcom/io/nsLocalFileUnix.cpp 2018-06-08 16:18:16.820916423 -0700
-@@ -10,7 +10,6 @@
-
- #include "mozilla/ArrayUtils.h"
- #include "mozilla/Attributes.h"
--#include
- #include
- #include
- #include
-@@ -28,6 +27,7 @@
- #define USE_LINUX_QUOTACTL
- #include
- #include
-+#include
- #ifndef BLOCK_SIZE
- #define BLOCK_SIZE 1024 /* kernel block size */
- #endif
diff --git a/esc.spec b/esc.spec
index 7d4fd44..af654ec 100644
--- a/esc.spec
+++ b/esc.spec
@@ -1,99 +1,49 @@
Name: esc
-Version: 1.1.1
-Release: 5%{?dist}
+Version: 1.1.2
+Release: 2%{?dist}
Summary: Enterprise Security Client Smart Card Client
License: GPL+
URL: http://directory.fedora.redhat.com/wiki/CoolKey
Group: Applications/Internet
-%global freetype_version 2.1.9
-%global libnotify_version 0.7.0
-%global libvpx_version 1.0.0
-Patch1: esc-1.1.1-fix1.patch
-Patch2: esc-1.1.1-fix2.patch
-Patch3: esc-1.1.1-fix3.patch
-Patch4: esc-1.1.1-fix4.patch
-
-BuildRequires: gcc
-BuildRequires: gcc-c++
-BuildRequires: doxygen fontconfig-devel
+#BuildRequires: doxygen fontconfig-devel
BuildRequires: glib2-devel atk-devel
BuildRequires: pkgconfig
BuildRequires: nspr-devel nss-devel nss-static
-BuildRequires: libX11-devel libXt-devel
+#BuildRequires: libX11-devel libXt-devel
BuildRequires: pcsc-lite-devel
-BuildRequires: desktop-file-utils zip binutils
-BuildRequires: libnotify-devel >= %{libnotify_version}
-BuildRequires: dbus-devel
-BuildRequires: libpng-devel
-BuildRequires: libjpeg-devel
-BuildRequires: zip
-BuildRequires: bzip2-devel
-BuildRequires: zlib-devel
-BuildRequires: libIDL-devel
-BuildRequires: gtk2-devel
-BuildRequires: krb5-devel
-BuildRequires: pango-devel
-BuildRequires: freetype-devel >= %{freetype_version}
-BuildRequires: libXt-devel
-BuildRequires: libXrender-devel
-BuildRequires: hunspell-devel
-BuildRequires: startup-notification-devel
-BuildRequires: alsa-lib-devel
-BuildRequires: mesa-libGL-devel
-BuildRequires: libcurl-devel
-BuildRequires: libvpx-devel >= %{libvpx_version}
-BuildRequires: autoconf213
-BuildRequires: pulseaudio-libs-devel
+BuildRequires: desktop-file-utils
BuildRequires: pkgconfig(gconf-2.0)
-BuildRequires: yasm
BuildRequires: dbus-glib-devel
-BuildRequires: libffi-devel
-BuildRequires: sqlite-devel
+BuildRequires: glib2-devel
BuildRequires: opensc
-Requires: sqlite
+BuildRequires: gobject-introspection-devel
+BuildRequires: gtk3-devel
+BuildRequires: gjs-devel
+BuildRequires: gcc-c++
Requires: pcsc-lite nss nspr
-Requires: zip dbus >= 0.90 libnotify >= 0.4.2
-Requires: mozilla-filesystem
-Requires: nspr-devel
-Requires: nss-devel
-Requires: libjpeg-devel
-Requires: zip
-Requires: bzip2-devel
-Requires: zlib-devel
-Requires: libIDL-devel
-Requires: gtk2-devel
-Requires: krb5-devel
-Requires: pango-devel
-Requires: freetype-devel >= %{freetype_version}
-Requires: libXt-devel
-Requires: libXrender-devel
-Requires: hunspell-devel
-Requires: sqlite-devel
-Requires: startup-notification-devel
-Requires: alsa-lib-devel
-Requires: libnotify-devel
-Requires: mesa-libGL-devel
-Requires: libvpx-devel >= %{libvpx_version}
+Requires: dbus
Requires: opensc
+Requires: gjs
+Requires: gobject-introspection
+Requires: gtk3
+Requires: glib2
# 390 does not have smartCards
ExcludeArch: s390 s390x
#xulrunner doesn't seem to support these right now
#Temporary anyway, since xulrunner is going away soon.
-ExcludeArch: aarch64 i686
# We can't allow the internal xulrunner to leak out
AutoReqProv: 0
%define debug_build 0
-#%define __prelink_undo_cmd %{nil}
%define escname %{name}-%{version}
%define escdir %{_libdir}/%{escname}
%define escbindir %{_bindir}
@@ -104,10 +54,6 @@ AutoReqProv: 0
%define autostartdir %{_sysconfdir}/xdg/autostart
%define pixmapdir %{_datadir}/pixmaps
%define docdir %{_defaultdocdir}/%{escname}
-%define escappdir src/app/xpcom
-%define escxuldir src/app/xul/esc
-%define escxulchromeicons %{escxuldir}/chrome/icons/default
-%define escdaemon escd
Source0: http://pki.fedoraproject.org/pki/sources/%name/%{escname}.tar.bz2
Source1: http://pki.fedoraproject.org/pki/sources/%name/esc
@@ -125,137 +71,75 @@ cryptographic smartcards.
#patch esc
-%patch1 -p1 -b .fix1
-%patch2 -p1 -b .fix2
-%patch3 -p1 -b .fix3
-%patch4 -p1 -b .fix4
-
-r=$(uname -r | sed -e 's/\(^[^.]*\.[^.]*\).*/\1/')
-[ -f esc/coreconf/Linux$r.mk ] || ln -s Linux3.5.mk esc/coreconf/Linux$r.mk
-
%build
echo $RPM_BUILD_DIR
-%define geckoversion `rpm -qi xulrunner | grep Version | sed 's/[\t ]//g;/^$/d' | sed 's/Version://'`
-
-GECKO_BASE_PATH=$RPM_BUILD_DIR/%{escname}/%{name}/src/xulrunner/xulrunner-45.9.0/firefox-45.9.0esr/objdir
-GECKO_SDK_PATH=$GECKO_BASE_PATH/dist/xulrunner-sdk
-GECKO_BIN_PATH=$GECKO_BASE_PATH/dist/xulrunner-sdk/sdk/bin
-GECKO_INCLUDE_PATH=%{_includedir}/xulrunner-%{geckoversion}
-GECKO_IDL_PATH=$GECKO_BASE_PATH/dist/xulrunner-sdk/idl
-
-%ifarch x86_64 %{power64} ia64 aarch64
-USE_64=1
-export USE_64
-%endif
-
-export GECKO_SDK_PATH
-export GECKO_BIN_PATH
-export GECKO_INCLUDE_PATH
-export GECKO_IDL_PATH
-# last setup call moved the current directory
+echo "build section" $PWD
cd esc
-#cd ../..
-
-cp %{SOURCE3} %{escxuldir}/%{esc_chromepath}
-rm -f %{escxulchromeicons}/*.ico
-cp %{escxulchromeicons}/esc-window.xpm %{escxulchromeicons}/default.xpm
-
-
-#xulrunner based flags.
-
-make HAVE_LIB_NOTIFY=1 ESC_VERSION=%{version}-%{release} USE_XUL_SDK=1
+./autogen.sh
+make
%install
-cd esc/src/app/xpcom
+echo "install section" $PWD
+cd esc
+make DESTDIR=$RPM_BUILD_ROOT install
mkdir -p $RPM_BUILD_ROOT/%{escbindir}
mkdir -p $RPM_BUILD_ROOT/%{icondir}
mkdir -p $RPM_BUILD_ROOT/%{_datadir}/%{appdir}
-mkdir -p $RPM_BUILD_ROOT/%{autostartdir}
mkdir -p $RPM_BUILD_ROOT/%{pixmapdir}
mkdir -p $RPM_BUILD_ROOT/%{docdir}
-
+echo "dir: " $RPM_BUILD_ROOT/%{escbindir}/%{name}
sed -e 's;\$LIBDIR;'%{_libdir}';g' %{SOURCE1} > $RPM_BUILD_ROOT/%{escbindir}/%{name}
-
-
-chmod 755 $RPM_BUILD_ROOT/%{escbindir}/esc
+chmod 755 $RPM_BUILD_ROOT/%{escbindir}/%{name}
mkdir -p $RPM_BUILD_ROOT/%{escdir}
+mkdir -p $RPM_BUILD_ROOT/%{escdir}/lib
-%ifarch x86_64 %{power64} ia64 aarch64
-USE_64=1
-export USE_64
-%endif
+cp $RPM_BUILD_ROOT/usr/local/bin/* $RPM_BUILD_ROOT/%{escdir}
+
+cp -rf $RPM_BUILD_ROOT/usr/local/lib $RPM_BUILD_ROOT/%{escdir}
+
+rm $RPM_BUILD_ROOT/%{escdir}/lib/*.a
+rm $RPM_BUILD_ROOT/%{escdir}/lib/*.la
-make USE_XUL_SDK=1 install DESTDIR=$RPM_BUILD_ROOT/%{escdir}
+rm -rf $RPM_BUILD_ROOT/usr/local
-rm -rf $RPM_BUILD_ROOT/%{escdir}/usr
-
-cd ../../../dist/*DBG*/esc_build/esc
-
-cp %{esc_chromepath}/esc.png $RPM_BUILD_ROOT/%{icondir}
+cp %{SOURCE3} $RPM_BUILD_ROOT/%{icondir}
ln -s $RPMBUILD_ROOT%{icondir}/esc.png $RPM_BUILD_ROOT/%{pixmapdir}/esc.png
cp %{SOURCE2} $RPM_BUILD_ROOT/%{_datadir}/%{appdir}
-cp %{SOURCE2} $RPM_BUILD_ROOT/%{autostartdir}
cd %{_builddir}
cp %{escname}/esc/LICENSE $RPM_BUILD_ROOT/%{docdir}
-rm -f $RPM_BUILD_ROOT/%{escdir}/esc
-#rm -rf $RPM_BUILD_ROOT/%{escdir}/xulrunner
-
-echo "xulrunner/xulrunner ./application.ini \$* &" > $RPM_BUILD_ROOT/%{escdir}/esc
-
-chmod 755 $RPM_BUILD_ROOT/%{escdir}/esc
-chmod 755 -R $RPM_BUILD_ROOT/%{escdir}/chrome
-chmod 755 -R $RPM_BUILD_ROOT/%{escdir}/defaults
-chmod 755 $RPM_BUILD_ROOT/%{escdir}/application.ini
-
-
%files
%{!?_licensedir:%global license %%doc}
%license %{docdir}/LICENSE
-%{escdir}/esc
-%attr(755, root, root) %{escdir}/esc
-%{escdir}/escd
%{escbindir}/esc
-%{escdir}/application.ini
+%{escdir}/lib
+%{escdir}/esc.js
%{escdir}/opensc.esc.conf
-%dir %{escdir}/chrome
-%dir %{escdir}/defaults
-%{escdir}/chrome.manifest
-%{escdir}/chrome/chrome.manifest
-%{escdir}/chrome/content
-%{escdir}/chrome/locale
-%{escdir}/chrome/icons/default
-%{escdir}/components
-%{escdir}/defaults/preferences/esc-prefs.js
-
-%{escdir}/xulrunner
%{icondir}/esc.png
%{pixmapdir}/esc.png
-%{autostartdir}/esc.desktop
%{_datadir}/%{appdir}/esc.desktop
-%preun
-
-killall --exact -q escd
-exit 0
-
%changelog
-* Fri Jul 13 2018 Fedora Release Engineering - 1.1.1-5
-- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
-
+* Wed Aug 01 2018 Jack Magne - 1.1.2-1
+- Remove uneeded Requires and no longer put in autostart directory.
+* Mon Jul 30 2018 Jack Magne - 1.1.2-1
+- Build bare bones esc, without xulrunner, using gjs / gobject
+- introspection.
+* Thu Jun 07 2018 Jack Magne - 1.1.1-5
+- Rebuild.
* Mon Apr 23 2018 Jack Magne - 1.1.1-4
- Remove coolkey dependencies, replace with opensc.
* Wed Feb 07 2018 Fedora Release Engineering - 1.1.1-3
diff --git a/sources b/sources
index fe8f33b..f69e5bf 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (esc-1.1.1.tar.bz2) = f8f34c74e6b513c83af5eb55c5c0402506d40fbe4dfaeffd900790fc06e5ae8d6edb07674a156c346621a3b891e2026592c3f4be3fa83e8399b68a40edcc82cd
+SHA512 (esc-1.1.2.tar.bz2) = ffcc5bdb95b93862790a223bde2ac7d8f5cd9788ea05815a8c6f55f1e1e9b41ef0bc19c7d7c4e97ee313e5bb1696da486d4d2f2719ea11b9ac8491d25d85969f