[SmartcardServices-Changes] [62] releases/Apple/Mac OS X 10.5.6
source_changes at macosforge.org
source_changes at macosforge.org
Mon Sep 7 14:49:09 PDT 2009
Revision: 62
http://trac.macosforge.org/projects/smartcardservices/changeset/62
Author: geddis at apple.com
Date: 2009-09-07 14:49:09 -0700 (Mon, 07 Sep 2009)
Log Message:
-----------
Added Paths:
-----------
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/APPLE_LICENSE
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/Makefile.installPhase
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/SmartCardServices.xcodeproj/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/SmartCardServices.xcodeproj/project.pbxproj
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/MacOS/CM4040
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/MacOS/CRYPTOCardPCCard
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Resources/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Resources/English.lproj/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Resources/English.lproj/InfoPlist.strings
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/MacOS/SCR24X_Apple_Driver
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Resources/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Resources/English.lproj/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Resources/English.lproj/InfoPlist.strings
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/PKCS11/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/PKCS11/pkcs11.shlb
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/MacOS/CC-PC-Card
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/MacOS/SCR24XHndlr
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/MacOS/ifd-ASEIIIeUSB
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/Info.plist
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/MacOS/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/MacOS/ifdok_cm4040_macos-2.0.0.dylib
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcscd.8
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctest.8
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctool.8
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/sc_auth.8
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/scripts/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/scripts/sc_auth
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/pbx/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/pbx/config.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/usbserial.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDprivate.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/global.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/pcscdefines.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/specific/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/specific/MacOSX/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/specific/MacOSX/tools_mosx.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSC.exp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/config.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.l
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.l
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_generic.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_macosx.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdhandler.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/mscdefines.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/muscletest.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdaemon.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscexport.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcsclite.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_generic.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_macosx.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_generic.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_macosx.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_unix.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/testpcsc.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_generic.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_macosx.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.l
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/utils/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/utils/bundleTool.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_clnt.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg_srv.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/wintypes.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.cpp
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_unix.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_win32.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_crypt.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_digest.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_dual.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_ext.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_general.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_key.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_object.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_parallel.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_random.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_session.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_sign.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_token.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_verify.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_async.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_bio.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_error.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_log.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_object.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_prefs.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_session.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_slot.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_state.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_thread.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_unixdll.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_util.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_win32dll.c
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11f.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11t.h
releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/thread_generic.h
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/APPLE_LICENSE
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/APPLE_LICENSE (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/APPLE_LICENSE 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,372 @@
+APPLE PUBLIC SOURCE LICENSE
+Version 1.1 - April 19,1999
+
+Please read this License carefully before downloading this software.
+By downloading and using this software, you are agreeing to be bound
+by the terms of this License. If you do not or cannot agree to the
+terms of this License, please do not download or use the software.
+
+1. General; Definitions. This License applies to any program or other
+work which Apple Computer, Inc. ("Apple") publicly announces as
+subject to this Apple Public Source License and which contains a
+notice placed by Apple identifying such program or work as "Original
+Code" and stating that it is subject to the terms of this Apple Public
+Source License version 1.1 (or subsequent version thereof), as it may
+be revised from time to time by Apple ("License"). As used in this
+License:
+
+1.1 "Affected Original Code" means only those specific portions of
+Original Code that allegedly infringe upon any party's intellectual
+property rights or are otherwise the subject of a claim of
+infringement.
+
+1.2 "Applicable Patent Rights" mean: (a) in the case where Apple is
+the grantor of rights, (i) claims of patents that are now or hereafter
+acquired, owned by or assigned to Apple and (ii) that cover subject
+matter contained in the Original Code, but only to the extent
+necessary to use, reproduce and/or distribute the Original Code
+without infringement; and (b) in the case where You are the grantor of
+rights, (i) claims of patents that are now or hereafter acquired,
+owned by or assigned to You and (ii) that cover subject matter in Your
+Modifications, taken alone or in combination with Original Code.
+
+1.3 "Covered Code" means the Original Code, Modifications, the
+combination of Original Code and any Modifications, and/or any
+respective portions thereof.
+
+1.4 "Deploy" means to use, sublicense or distribute Covered Code other
+than for Your internal research and development (R&D), and includes
+without limitation, any and all internal use or distribution of
+Covered Code within Your business or organization except for R&D use,
+as well as direct or indirect sublicensing or distribution of Covered
+Code by You to any third party in any form or manner.
+
+1.5 "Larger Work" means a work which combines Covered Code or portions
+thereof with code not governed by the terms of this License.
+
+1.6 "Modifications" mean any addition to, deletion from, and/or change
+to, the substance and/or structure of Covered Code. When code is
+released as a series of files, a Modification is: (a) any addition to
+or deletion from the contents of a file containing Covered Code;
+and/or (b) any new file or other representation of computer program
+statements that contains any part of Covered Code.
+
+1.7 "Original Code" means (a) the Source Code of a program or other
+work as originally made available by Apple under this License,
+including the Source Code of any updates or upgrades to such programs
+or works made available by Apple under this License, and that has been
+expressly identified by Apple as such in the header file(s) of such
+work; and (b) the object code compiled from such Source Code and
+originally made available by Apple under this License.
+
+1.8 "Source Code" means the human readable form of a program or other
+work that is suitable for making modifications to it, including all
+modules it contains, plus any associated interface definition files,
+scripts used to control compilation and installation of an executable
+(object code).
+
+1.9 "You" or "Your" means an individual or a legal entity exercising
+rights under this License. For legal entities, "You" or "Your"
+includes any entity which controls, is controlled by, or is under
+common control with, You, where "control" means (a) the power, direct
+or indirect, to cause the direction or management of such entity,
+whether by contract or otherwise, or (b) ownership of fifty percent
+(50%) or more of the outstanding shares or beneficial ownership of
+such entity.
+
+2. Permitted Uses; Conditions & Restrictions. Subject to the terms
+and conditions of this License, Apple hereby grants You, effective on
+the date You accept this License and download the Original Code, a
+world-wide, royalty-free, non- exclusive license, to the extent of
+Apple's Applicable Patent Rights and copyrights covering the Original
+Code, to do the following:
+
+2.1 You may use, copy, modify and distribute Original Code, with or
+without Modifications, solely for Your internal research and
+development, provided that You must in each instance:
+
+(a) retain and reproduce in all copies of Original Code the copyright
+and other proprietary notices and disclaimers of Apple as they appear
+in the Original Code, and keep intact all notices in the Original Code
+that refer to this License;
+
+(b) include a copy of this License with every copy of Source Code of
+Covered Code and documentation You distribute, and You may not offer
+or impose any terms on such Source Code that alter or restrict this
+License or the recipients' rights hereunder, except as permitted under
+Section 6; and
+
+(c) completely and accurately document all Modifications that you have
+made and the date of each such Modification, designate the version of
+the Original Code you used, prominently include a file carrying such
+information with the Modifications, and duplicate the notice in
+Exhibit A in each file of the Source Code of all such Modifications.
+
+2.2 You may Deploy Covered Code, provided that You must in each
+ instance:
+
+(a) satisfy all the conditions of Section 2.1 with respect to the
+Source Code of the Covered Code;
+
+(b) make all Your Deployed Modifications publicly available in Source
+Code form via electronic distribution (e.g. download from a web site)
+under the terms of this License and subject to the license grants set
+forth in Section 3 below, and any additional terms You may choose to
+offer under Section 6. You must continue to make the Source Code of
+Your Deployed Modifications available for as long as you Deploy the
+Covered Code or twelve (12) months from the date of initial
+Deployment, whichever is longer;
+
+(c) if You Deploy Covered Code containing Modifications made by You,
+inform others of how to obtain those Modifications by filling out and
+submitting the information found at
+http://www.apple.com/publicsource/modifications.html, if available;
+and
+
+(d) if You Deploy Covered Code in object code, executable form only,
+include a prominent notice, in the code itself as well as in related
+documentation, stating that Source Code of the Covered Code is
+available under the terms of this License with information on how and
+where to obtain such Source Code.
+
+3. Your Grants. In consideration of, and as a condition to, the
+licenses granted to You under this License:
+
+(a) You hereby grant to Apple and all third parties a non-exclusive,
+royalty-free license, under Your Applicable Patent Rights and other
+intellectual property rights owned or controlled by You, to use,
+reproduce, modify, distribute and Deploy Your Modifications of the
+same scope and extent as Apple's licenses under Sections 2.1 and 2.2;
+and
+
+(b) You hereby grant to Apple and its subsidiaries a non-exclusive,
+worldwide, royalty-free, perpetual and irrevocable license, under Your
+Applicable Patent Rights and other intellectual property rights owned
+or controlled by You, to use, reproduce, execute, compile, display,
+perform, modify or have modified (for Apple and/or its subsidiaries),
+sublicense and distribute Your Modifications, in any form, through
+multiple tiers of distribution.
+
+4. Larger Works. You may create a Larger Work by combining Covered
+Code with other code not governed by the terms of this License and
+distribute the Larger Work as a single product. In each such
+instance, You must make sure the requirements of this License are
+fulfilled for the Covered Code or any portion thereof.
+
+5. Limitations on Patent License. Except as expressly stated in
+Section 2, no other patent rights, express or implied, are granted by
+Apple herein. Modifications and/or Larger Works may require
+additional patent licenses from Apple which Apple may grant in its
+sole discretion.
+
+6. Additional Terms. You may choose to offer, and to charge a fee
+for, warranty, support, indemnity or liability obligations and/or
+other rights consistent with the scope of the license granted herein
+("Additional Terms") to one or more recipients of Covered
+Code. However, You may do so only on Your own behalf and as Your sole
+responsibility, and not on behalf of Apple. You must obtain the
+recipient's agreement that any such Additional Terms are offered by
+You alone, and You hereby agree to indemnify, defend and hold Apple
+harmless for any liability incurred by or claims asserted against
+Apple by reason of any such Additional Terms.
+
+7. Versions of the License. Apple may publish revised and/or new
+versions of this License from time to time. Each version will be
+given a distinguishing version number. Once Original Code has been
+published under a particular version of this License, You may continue
+to use it under the terms of that version. You may also choose to use
+such Original Code under the terms of any subsequent version of this
+License published by Apple. No one other than Apple has the right to
+modify the terms applicable to Covered Code created under this
+License.
+
+8. NO WARRANTY OR SUPPORT. The Original Code may contain in whole or
+in part pre-release, untested, or not fully tested works. The
+Original Code may contain errors that could cause failures or loss of
+data, and may be incomplete or contain inaccuracies. You expressly
+acknowledge and agree that use of the Original Code, or any portion
+thereof, is at Your sole and entire risk. THE ORIGINAL CODE IS
+PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND
+AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF SECTIONS 8 AND
+9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY REFERRED TO AS
+"APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR CONDITIONS, EXPRESS
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+AND/OR CONDITIONS OF MERCHANTABILITY OR SATISFACTORY QUALITY AND
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY
+RIGHTS. APPLE DOES NOT WARRANT THAT THE FUNCTIONS CONTAINED IN THE
+ORIGINAL CODE WILL MEET YOUR REQUIREMENTS, OR THAT THE OPERATION OF
+THE ORIGINAL CODE WILL BE UNINTERRUPTED OR ERROR- FREE, OR THAT
+DEFECTS IN THE ORIGINAL CODE WILL BE CORRECTED. NO ORAL OR WRITTEN
+INFORMATION OR ADVICE GIVEN BY APPLE OR AN APPLE AUTHORIZED
+REPRESENTATIVE SHALL CREATE A WARRANTY OR IN ANY WAY INCREASE THE
+SCOPE OF THIS WARRANTY. You acknowledge that the Original Code is not
+intended for use in the operation of nuclear facilities, aircraft
+navigation, communication systems, or air traffic control machines in
+which case the failure of the Original Code could lead to death,
+personal injury, or severe physical or environmental damage.
+
+9. Liability.
+
+9.1 Infringement. If any portion of, or functionality implemented by,
+the Original Code becomes the subject of a claim of infringement,
+Apple may, at its option: (a) attempt to procure the rights necessary
+for Apple and You to continue using the Affected Original Code; (b)
+modify the Affected Original Code so that it is no longer infringing;
+or (c) suspend Your rights to use, reproduce, modify, sublicense and
+distribute the Affected Original Code until a final determination of
+the claim is made by a court or governmental administrative agency of
+competent jurisdiction and Apple lifts the suspension as set forth
+below. Such suspension of rights will be effective immediately upon
+Apple's posting of a notice to such effect on the Apple web site that
+is used for implementation of this License. Upon such final
+determination being made, if Apple is legally able, without the
+payment of a fee or royalty, to resume use, reproduction,
+modification, sublicensing and distribution of the Affected Original
+Code, Apple will lift the suspension of rights to the Affected
+Original Code by posting a notice to such effect on the Apple web site
+that is used for implementation of this License. If Apple suspends
+Your rights to Affected Original Code, nothing in this License shall
+be construed to restrict You, at Your option and subject to applicable
+law, from replacing the Affected Original Code with non-infringing
+code or independently negotiating for necessary rights from such third
+party.
+
+9.2 LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES SHALL APPLE BE
+LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR INABILITY TO
+USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER UNDER A THEORY
+OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY
+OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF
+ANY REMEDY. In no event shall Apple's total liability to You for all
+damages under this License exceed the amount of fifty dollars
+($50.00).
+
+10. Trademarks. This License does not grant any rights to use the
+trademarks or trade names "Apple", "Apple Computer", "Mac OS X", "Mac
+OS X Server" or any other trademarks or trade names belonging to Apple
+(collectively "Apple Marks") and no Apple Marks may be used to endorse
+or promote products derived from the Original Code other than as
+permitted by and in strict compliance at all times with Apple's third
+party trademark usage guidelines which are posted at
+http://www.apple.com/legal/guidelinesfor3rdparties.html.
+
+11. Ownership. Apple retains all rights, title and interest in and to
+the Original Code and any Modifications made by or on behalf of Apple
+("Apple Modifications"), and such Apple Modifications will not be
+automatically subject to this License. Apple may, at its sole
+discretion, choose to license such Apple Modifications under this
+License, or on different terms from those contained in this License or
+may choose not to license them at all. Apple's development, use,
+reproduction, modification, sublicensing and distribution of Covered
+Code will not be subject to this License.
+
+12. Termination.
+
+12.1 Termination. This License and the rights granted hereunder will
+ terminate:
+
+(a) automatically without notice from Apple if You fail to comply with
+any term(s) of this License and fail to cure such breach within 30
+days of becoming aware of such breach; (b) immediately in the event of
+the circumstances described in Section 13.5(b); or (c) automatically
+without notice from Apple if You, at any time during the term of this
+License, commence an action for patent infringement against Apple.
+
+12.2 Effect of Termination. Upon termination, You agree to
+immediately stop any further use, reproduction, modification,
+sublicensing and distribution of the Covered Code and to destroy all
+copies of the Covered Code that are in your possession or control.
+All sublicenses to the Covered Code which have been properly granted
+prior to termination shall survive any termination of this License.
+Provisions which, by their nature, should remain in effect beyond the
+termination of this License shall survive, including but not limited
+to Sections 3, 5, 8, 9, 10, 11, 12.2 and 13. Neither party will be
+liable to the other for compensation, indemnity or damages of any sort
+solely as a result of terminating this License in accordance with its
+terms, and termination of this License will be without prejudice to
+any other right or remedy of either party.
+
+13. Miscellaneous.
+
+13.1 Government End Users. The Covered Code is a "commercial item" as
+defined in FAR 2.101. Government software and technical data rights
+in the Covered Code include only those rights customarily provided to
+the public as defined in this License. This customary commercial
+license in technical data and software is provided in accordance with
+FAR 12.211 (Technical Data) and 12.212 (Computer Software) and, for
+Department of Defense purchases, DFAR 252.227-7015 (Technical Data --
+Commercial Items) and 227.7202-3 (Rights in Commercial Computer
+Software or Computer Software Documentation). Accordingly, all U.S.
+Government End Users acquire Covered Code with only those rights set
+forth herein.
+
+13.2 Relationship of Parties. This License will not be construed as
+creating an agency, partnership, joint venture or any other form of
+legal association between You and Apple, and You will not represent to
+the contrary, whether expressly, by implication, appearance or
+otherwise.
+
+13.3 Independent Development. Nothing in this License will impair
+Apple's right to acquire, license, develop, have others develop for
+it, market and/or distribute technology or products that perform the
+same or similar functions as, or otherwise compete with,
+Modifications, Larger Works, technology or products that You may
+develop, produce, market or distribute.
+
+13.4 Waiver; Construction. Failure by Apple to enforce any provision
+of this License will not be deemed a waiver of future enforcement of
+that or any other provision. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+will not apply to this License.
+
+13.5 Severability. (a) If for any reason a court of competent
+jurisdiction finds any provision of this License, or portion thereof,
+to be unenforceable, that provision of the License will be enforced to
+the maximum extent permissible so as to effect the economic benefits
+and intent of the parties, and the remainder of this License will
+continue in full force and effect. (b) Notwithstanding the foregoing,
+if applicable law prohibits or restricts You from fully and/or
+specifically complying with Sections 2 and/or 3 or prevents the
+enforceability of either of those Sections, this License will
+immediately terminate and You must immediately discontinue any use of
+the Covered Code and destroy all copies of it that are in your
+possession or control.
+
+13.6 Dispute Resolution. Any litigation or other dispute resolution
+between You and Apple relating to this License shall take place in the
+Northern District of California, and You and Apple hereby consent to
+the personal jurisdiction of, and venue in, the state and federal
+courts within that District with respect to this License. The
+application of the United Nations Convention on Contracts for the
+International Sale of Goods is expressly excluded.
+
+13.7 Entire Agreement; Governing Law. This License constitutes the
+entire agreement between the parties with respect to the subject
+matter hereof. This License shall be governed by the laws of the
+United States and the State of California, except that body of
+California law concerning conflicts of law.
+
+Where You are located in the province of Quebec, Canada, the following
+clause applies: The parties hereby confirm that they have requested
+that this License and all related documents be drafted in English. Les
+parties ont exige que le present contrat et tous les documents
+connexes soient rediges en anglais.
+
+EXHIBIT A.
+
+"Portions Copyright (c) 1999-2000 Apple Computer, Inc. All Rights
+Reserved. This file contains Original Code and/or Modifications of
+Original Code as defined in and that are subject to the Apple Public
+Source License Version 1.1 (the "License"). You may not use this file
+except in compliance with the License. Please obtain a copy of the
+License at http://www.apple.com/publicsource and read it before using
+this file.
+
+The Original Code and all software distributed under the License are
+distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+License for the specific language governing rights and limitations
+under the License."
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/Makefile.installPhase
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/Makefile.installPhase (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/Makefile.installPhase 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,83 @@
+# The other phases do nothing
+
+MAN_DIR=$(DSTROOT)/usr/share/man/man8
+PCSCDIR=$(DSTROOT)/usr/libexec/SmartCardServices
+PKCS11_DIR=$(DSTROOT)/Library/Application\ Support/Mozilla/
+EXTENSIONS_DIR=$(DSTROOT)/System/Library/Extensions
+SCRIPTS_LOCATION=$(DSTROOT)/usr/sbin
+
+build:
+ @echo null build.
+
+debug:
+ @echo null debug.
+
+profile:
+ @echo null profile.
+
+install:
+ mkdir -p $(PCSCDIR)
+ mkdir -p $(PCSCDIR)/drivers
+ mkdir -p $(PCSCDIR)/services
+ chmod 755 $(PCSCDIR)
+ cp -r installPhase/drivers/*.bundle $(PCSCDIR)/drivers/
+ -rm -rf $(PCSCDIR)/drivers/*.bundle/CVS
+ -rm -rf $(PCSCDIR)/drivers/*.bundle/Contents/CVS
+ -rm -rf $(PCSCDIR)/drivers/*.bundle/Contents/MacOS/CVS
+ chmod 755 $(PCSCDIR)/drivers/*.bundle
+ chmod 755 $(PCSCDIR)/drivers/*.bundle/Contents
+ chmod 755 $(PCSCDIR)/drivers/*.bundle/Contents/MacOS
+ chmod 644 $(PCSCDIR)/drivers/*.bundle/Contents/*.*
+ chmod 644 $(PCSCDIR)/drivers/*.bundle/Contents/MacOS/*
+ /usr/bin/strip -S $(PCSCDIR)/drivers/*.bundle/Contents/MacOS/*
+ mkdir -p $(EXTENSIONS_DIR)
+ chmod 755 $(DSTROOT)/System
+ chmod 755 $(DSTROOT)/System/Library
+ chmod 755 $(EXTENSIONS_DIR)
+ cp -r installPhase/Extensions/*.kext $(EXTENSIONS_DIR)/
+ -rm -rf $(EXTENSIONS_DIR)/*.kext/CVS
+ -rm -rf $(EXTENSIONS_DIR)/*.kext/Contents/CVS
+ -rm -rf $(EXTENSIONS_DIR)/*.kext/Contents/MacOS/CVS
+ -rm -rf $(EXTENSIONS_DIR)/*.kext/Contents/Resources/CVS
+ -rm -rf $(EXTENSIONS_DIR)/*.kext/Contents/Resources/*.lproj/CVS
+ chmod 755 $(EXTENSIONS_DIR)/*.kext
+ chmod 755 $(EXTENSIONS_DIR)/*.kext/Contents
+ chmod 755 $(EXTENSIONS_DIR)/*.kext/Contents/MacOS
+ -chmod 755 $(EXTENSIONS_DIR)/*.kext/Contents/Resources
+ -chmod 755 $(EXTENSIONS_DIR)/*.kext/Contents/Resources/*.lproj
+ chmod 644 $(EXTENSIONS_DIR)/*.kext/Contents/*.*
+ chmod 644 $(EXTENSIONS_DIR)/*.kext/Contents/MacOS/*
+ -chmod 644 $(EXTENSIONS_DIR)/*.kext/Contents/Resources/*.lproj/*.*
+ /usr/bin/strip -S $(EXTENSIONS_DIR)/*.kext/Contents/MacOS/*
+
+ mkdir -p $(SCRIPTS_LOCATION)
+
+ cp installPhase/scripts/sc_auth $(SCRIPTS_LOCATION)
+ chown root:admin $(SCRIPTS_LOCATION)/sc_auth
+ chmod 755 $(SCRIPTS_LOCATION)/sc_auth
+
+# Copy over man pages
+
+ mkdir -p $(MAN_DIR)
+ cp installPhase/man/pcscd.8 $(MAN_DIR)
+ cp installPhase/man/pcsctool.8 $(MAN_DIR)
+ cp installPhase/man/pcsctest.8 $(MAN_DIR)
+ cp installPhase/man/sc_auth.8 $(MAN_DIR)
+ chown root:wheel $(MAN_DIR)/sc_auth.8
+
+# Deleting CVS subdirectories from the copy phase
+
+ rm -rf `find $(PCSCDIR)/drivers -name CVS`
+
+ mkdir -p $(PKCS11_DIR)
+ cp installPhase/PKCS11/pkcs11.shlb $(PKCS11_DIR)
+ chmod 755 $(PKCS11_DIR)/pkcs11.shlb
+
+installhdrs:
+ @echo null installhdrs.
+
+installsrc:
+ @echo null installsrc.
+
+clean:
+ @echo null clean.
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/SmartCardServices.xcodeproj/project.pbxproj
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/SmartCardServices.xcodeproj/project.pbxproj (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/SmartCardServices.xcodeproj/project.pbxproj 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,2762 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 42;
+ objects = {
+
+/* Begin PBXAggregateTarget section */
+ F5294A510090C54E01CD285A /* World */ = {
+ isa = PBXAggregateTarget;
+ buildConfigurationList = C27AD1F80987FCDC001272E0 /* Build configuration list for PBXAggregateTarget "World" */;
+ buildPhases = (
+ );
+ dependencies = (
+ F520A5F60257B49C01D97E8A /* PBXTargetDependency */,
+ F520E3A001F6204201B94B28 /* PBXTargetDependency */,
+ F520E3A301F6204201B94B28 /* PBXTargetDependency */,
+ F511213B0272FA1C017BB957 /* PBXTargetDependency */,
+ F5448E810379FE0101B94948 /* PBXTargetDependency */,
+ F5448E820379FE0501B94948 /* PBXTargetDependency */,
+ 2CBB607506CA6DDE006AA7C8 /* PBXTargetDependency */,
+ F5448E830379FE0801B94948 /* PBXTargetDependency */,
+ F5448E840379FE0C01B94948 /* PBXTargetDependency */,
+ F54DC28B0397F35F01115D8D /* PBXTargetDependency */,
+ );
+ name = World;
+ productName = World;
+ };
+/* End PBXAggregateTarget section */
+
+/* Begin PBXBuildFile section */
+ 2CBB606506CA69F9006AA7C8 /* GSCISPlugin.c in Sources */ = {isa = PBXBuildFile; fileRef = 2CBB606306CA69F9006AA7C8 /* GSCISPlugin.c */; };
+ 2CBB606606CA69F9006AA7C8 /* GSCISPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CBB606406CA69F9006AA7C8 /* GSCISPlugin.h */; };
+ 2CC9AB8406CC02F30048A811 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ 5236DD1F0B9DDBD7007CEF56 /* readerstate.h in Headers */ = {isa = PBXBuildFile; fileRef = 5236DD1D0B9DDBD7007CEF56 /* readerstate.h */; };
+ 527CF60E0AA5192B007589FF /* pcscdmonitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527CF60A0AA5192B007589FF /* pcscdmonitor.cpp */; };
+ 527CF60F0AA5192B007589FF /* pcscdmonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 527CF60B0AA5192B007589FF /* pcscdmonitor.h */; };
+ 527CF6100AA5192B007589FF /* pcscdserver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 527CF60C0AA5192B007589FF /* pcscdserver.cpp */; };
+ 527CF6110AA5192B007589FF /* pcscdserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 527CF60D0AA5192B007589FF /* pcscdserver.h */; };
+ 528629490A87EA8E004FE8DC /* hotplug_macosx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5286293C0A87EA8E004FE8DC /* hotplug_macosx.cpp */; };
+ 5286294A0A87EA8E004FE8DC /* PCSCDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5286293D0A87EA8E004FE8DC /* PCSCDevice.cpp */; };
+ 5286294B0A87EA8E004FE8DC /* PCSCDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 5286293E0A87EA8E004FE8DC /* PCSCDevice.h */; };
+ 5286294C0A87EA8E004FE8DC /* PCSCDriverBundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5286293F0A87EA8E004FE8DC /* PCSCDriverBundle.cpp */; };
+ 5286294D0A87EA8E004FE8DC /* PCSCDriverBundle.h in Headers */ = {isa = PBXBuildFile; fileRef = 528629400A87EA8E004FE8DC /* PCSCDriverBundle.h */; };
+ 5286294E0A87EA8E004FE8DC /* PCSCDriverBundles.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 528629410A87EA8E004FE8DC /* PCSCDriverBundles.cpp */; };
+ 5286294F0A87EA8E004FE8DC /* PCSCDriverBundles.h in Headers */ = {isa = PBXBuildFile; fileRef = 528629420A87EA8E004FE8DC /* PCSCDriverBundles.h */; };
+ 52C3C1480BA5D46900436862 /* readerstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5236DD1C0B9DDBD7007CEF56 /* readerstate.cpp */; };
+ 52C3C14D0BA5D54100436862 /* readerstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5236DD1C0B9DDBD7007CEF56 /* readerstate.cpp */; };
+ 52C85D900B9FA79F002DA856 /* security_utilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D58C080A87FEA000DC3F19 /* security_utilities.framework */; };
+ 52D00D1C0A9252350093277A /* reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 52D00D1A0A9252350093277A /* reader.h */; };
+ 52D00D1D0A9252350093277A /* reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52D00D1B0A9252350093277A /* reader.cpp */; };
+ 52D2492D0BA07E1100F9827A /* winscard_msg_srv.c in Sources */ = {isa = PBXBuildFile; fileRef = 52D2492C0BA07E1100F9827A /* winscard_msg_srv.c */; };
+ 52D58C090A87FEA000DC3F19 /* security_utilities.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52D58C080A87FEA000DC3F19 /* security_utilities.framework */; };
+ 52D58C560A8803A800DC3F19 /* thread_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A60254242101B94B21 /* thread_macosx.c */; };
+ 52DBCAAF0BB851C8007D06A5 /* PCSC.exp in Sources */ = {isa = PBXBuildFile; fileRef = 52DBCAAE0BB851C8007D06A5 /* PCSC.exp */; };
+ 52E0D59E0BA7006D008DFDDF /* winscard.c in Sources */ = {isa = PBXBuildFile; fileRef = 52E0D59D0BA7006D008DFDDF /* winscard.c */; };
+ C2F2094B0662B851001DFD06 /* sys_macosx.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C2F2094A0662B851001DFD06 /* sys_macosx.cpp */; };
+ F503CACF025425E601B94B21 /* testpcsc.c in Sources */ = {isa = PBXBuildFile; fileRef = F503CACD025425E601B94B21 /* testpcsc.c */; };
+ F503CADD025428F601B94B21 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F503CADB025428F601B94B21 /* CoreFoundation.framework */; };
+ F503CADE025428F601B94B21 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F503CADC025428F601B94B21 /* IOKit.framework */; };
+ F503CAE00254294101B94B21 /* libl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F503CADF0254294101B94B21 /* libl.a */; };
+ F503CAE402542A9201B94B21 /* wintypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94AD0254242101B94B21 /* wintypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F503CAE502542A9201B94B21 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F503CADB025428F601B94B21 /* CoreFoundation.framework */; };
+ F511212D0272F8D9017BB957 /* bundleTool.c in Sources */ = {isa = PBXBuildFile; fileRef = F511212C0272F8D9017BB957 /* bundleTool.c */; };
+ F52A94520254232701B94B21 /* atrhandler.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94510254232701B94B21 /* atrhandler.c */; };
+ F52A94AE0254242101B94B21 /* atrhandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A948F0254242101B94B21 /* atrhandler.h */; };
+ F52A94AF0254242101B94B21 /* configfile.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94910254242101B94B21 /* configfile.h */; };
+ F52A94B00254242101B94B21 /* debuglog.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94930254242101B94B21 /* debuglog.h */; };
+ F52A94B10254242101B94B21 /* dyn_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94940254242101B94B21 /* dyn_generic.h */; };
+ F52A94B20254242101B94B21 /* eventhandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94970254242101B94B21 /* eventhandler.h */; };
+ F52A94B30254242101B94B21 /* hotplug.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94990254242101B94B21 /* hotplug.h */; };
+ F52A94B40254242101B94B21 /* ifdhandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A949A0254242101B94B21 /* ifdhandler.h */; };
+ F52A94B50254242101B94B21 /* ifdwrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A949C0254242101B94B21 /* ifdwrapper.h */; };
+ F52A94B60254242101B94B21 /* pcsclite.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A949E0254242101B94B21 /* pcsclite.h */; };
+ F52A94B70254242101B94B21 /* prothandler.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A00254242101B94B21 /* prothandler.h */; };
+ F52A94B80254242101B94B21 /* readerfactory.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A20254242101B94B21 /* readerfactory.h */; };
+ F52A94B90254242101B94B21 /* sys_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A30254242101B94B21 /* sys_generic.h */; };
+ F52A94BA0254242101B94B21 /* thread_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A50254242101B94B21 /* thread_generic.h */; };
+ F52A94BB0254242101B94B21 /* winscard_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A80254242101B94B21 /* winscard_msg.h */; };
+ F52A94BC0254242101B94B21 /* winscard_svc.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94AA0254242101B94B21 /* winscard_svc.h */; };
+ F52A94BD0254242101B94B21 /* winscard.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94AC0254242101B94B21 /* winscard.h */; };
+ F52A94BE0254242101B94B21 /* wintypes.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94AD0254242101B94B21 /* wintypes.h */; };
+ F52A94BF0254242101B94B21 /* configfile.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94900254242101B94B21 /* configfile.c */; settings = {COMPILER_FLAGS = "-DYY_NO_UNPUT"; }; };
+ F52A94C00254242101B94B21 /* debuglog.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94920254242101B94B21 /* debuglog.c */; };
+ F52A94C10254242101B94B21 /* dyn_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94950254242101B94B21 /* dyn_macosx.c */; };
+ F52A94C20254242101B94B21 /* eventhandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52A94960254242101B94B21 /* eventhandler.cpp */; };
+ F52A94C40254242101B94B21 /* ifdwrapper.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A949B0254242101B94B21 /* ifdwrapper.c */; };
+ F52A94C50254242101B94B21 /* pcscdaemon.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A949D0254242101B94B21 /* pcscdaemon.c */; };
+ F52A94C60254242101B94B21 /* prothandler.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A949F0254242101B94B21 /* prothandler.c */; };
+ F52A94C70254242101B94B21 /* readerfactory.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A10254242101B94B21 /* readerfactory.c */; };
+ F52A94C90254242101B94B21 /* thread_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A60254242101B94B21 /* thread_macosx.c */; };
+ F52A94CA0254242101B94B21 /* winscard_msg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A70254242101B94B21 /* winscard_msg.cpp */; };
+ F52A94CB0254242101B94B21 /* winscard_svc.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A90254242101B94B21 /* winscard_svc.c */; };
+ F52A94D5025424AC01B94B21 /* thread_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A50254242101B94B21 /* thread_generic.h */; };
+ F52A94D6025424AC01B94B21 /* pcsclite.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A949E0254242101B94B21 /* pcsclite.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F52A94D7025424AC01B94B21 /* mscdefines.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94CD025424AC01B94B21 /* mscdefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F52A94D8025424AC01B94B21 /* musclecard.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94CF025424AC01B94B21 /* musclecard.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F52A94D9025424AC01B94B21 /* winscard_msg.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94A80254242101B94B21 /* winscard_msg.h */; };
+ F52A94DA025424AC01B94B21 /* tokenfactory.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94D1025424AC01B94B21 /* tokenfactory.h */; };
+ F52A94DB025424AC01B94B21 /* winscard.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94AC0254242101B94B21 /* winscard.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ F52A94DC025424AC01B94B21 /* dyn_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94940254242101B94B21 /* dyn_generic.h */; };
+ F52A94DD025424AC01B94B21 /* debuglog.h in Headers */ = {isa = PBXBuildFile; fileRef = F52A94930254242101B94B21 /* debuglog.h */; settings = {ATTRIBUTES = (); }; };
+ F52A94DE025424AC01B94B21 /* musclecard.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94CE025424AC01B94B21 /* musclecard.c */; };
+ F52A94DF025424AC01B94B21 /* dyn_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94950254242101B94B21 /* dyn_macosx.c */; };
+ F52A94E0025424AC01B94B21 /* tokenfactory.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94D0025424AC01B94B21 /* tokenfactory.c */; };
+ F52A94E1025424AC01B94B21 /* tokenparser.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94D2025424AC01B94B21 /* tokenparser.c */; settings = {COMPILER_FLAGS = "-DYY_NO_UNPUT"; }; };
+ F52A94E3025424AC01B94B21 /* debuglog.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94920254242101B94B21 /* debuglog.c */; };
+ F52A94E4025424AC01B94B21 /* winscard_clnt.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94D4025424AC01B94B21 /* winscard_clnt.c */; };
+ F52A94E5025424F101B94B21 /* winscard_msg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A70254242101B94B21 /* winscard_msg.cpp */; };
+ F52A94E7025424F101B94B21 /* sys_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = F52A94A40254242101B94B21 /* sys_unix.c */; };
+ F537A7B40379EB7B01B94948 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = F537A7B30379EB7B01B94948 /* config.h */; };
+ F5448E140379EEA101B94948 /* musclecardApplet.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E120379EEA101B94948 /* musclecardApplet.c */; };
+ F5448E150379EEA101B94948 /* musclecardApplet.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E130379EEA101B94948 /* musclecardApplet.h */; };
+ F5448E180379EEC301B94948 /* cryptoflex.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E160379EEC301B94948 /* cryptoflex.c */; };
+ F5448E190379EEC301B94948 /* cryptoflex.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E170379EEC301B94948 /* cryptoflex.h */; };
+ F5448E1C0379EEDD01B94948 /* commonAccessCard.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E1A0379EEDD01B94948 /* commonAccessCard.c */; };
+ F5448E1D0379EEDD01B94948 /* commonAccessCard.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E1B0379EEDD01B94948 /* commonAccessCard.h */; };
+ F5448E3F0379EF2501B94948 /* cryptoki_unix.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E1E0379EF2501B94948 /* cryptoki_unix.h */; };
+ F5448E400379EF2501B94948 /* cryptoki.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E1F0379EF2501B94948 /* cryptoki.h */; };
+ F5448E410379EF2501B94948 /* p11_crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E200379EF2501B94948 /* p11_crypt.c */; };
+ F5448E420379EF2501B94948 /* p11_digest.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E210379EF2501B94948 /* p11_digest.c */; };
+ F5448E430379EF2501B94948 /* p11_dual.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E220379EF2501B94948 /* p11_dual.c */; };
+ F5448E440379EF2501B94948 /* p11_ext.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E230379EF2501B94948 /* p11_ext.c */; };
+ F5448E450379EF2501B94948 /* p11_general.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E240379EF2501B94948 /* p11_general.c */; };
+ F5448E460379EF2501B94948 /* p11_key.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E250379EF2501B94948 /* p11_key.c */; };
+ F5448E470379EF2501B94948 /* p11_object.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E260379EF2501B94948 /* p11_object.c */; };
+ F5448E480379EF2501B94948 /* p11_parallel.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E270379EF2501B94948 /* p11_parallel.c */; };
+ F5448E490379EF2501B94948 /* p11_random.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E280379EF2501B94948 /* p11_random.c */; };
+ F5448E4A0379EF2501B94948 /* p11_session.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E290379EF2501B94948 /* p11_session.c */; };
+ F5448E4B0379EF2501B94948 /* p11_sign.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E2A0379EF2501B94948 /* p11_sign.c */; };
+ F5448E4C0379EF2501B94948 /* p11_token.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E2B0379EF2501B94948 /* p11_token.c */; };
+ F5448E4D0379EF2501B94948 /* p11_verify.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E2C0379EF2501B94948 /* p11_verify.c */; };
+ F5448E4E0379EF2501B94948 /* p11x_async.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E2D0379EF2501B94948 /* p11x_async.c */; };
+ F5448E4F0379EF2501B94948 /* p11x_bio.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E2E0379EF2501B94948 /* p11x_bio.c */; };
+ F5448E500379EF2501B94948 /* p11x_error.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E2F0379EF2501B94948 /* p11x_error.c */; };
+ F5448E510379EF2501B94948 /* p11x_log.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E300379EF2501B94948 /* p11x_log.c */; };
+ F5448E520379EF2501B94948 /* p11x_msc.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E310379EF2501B94948 /* p11x_msc.c */; };
+ F5448E530379EF2501B94948 /* p11x_msc.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E320379EF2501B94948 /* p11x_msc.h */; };
+ F5448E540379EF2501B94948 /* p11x_object.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E330379EF2501B94948 /* p11x_object.c */; };
+ F5448E550379EF2501B94948 /* p11x_prefs.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E340379EF2501B94948 /* p11x_prefs.c */; };
+ F5448E560379EF2501B94948 /* p11x_session.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E350379EF2501B94948 /* p11x_session.c */; };
+ F5448E570379EF2501B94948 /* p11x_slot.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E360379EF2501B94948 /* p11x_slot.c */; };
+ F5448E580379EF2501B94948 /* p11x_state.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E370379EF2501B94948 /* p11x_state.c */; };
+ F5448E590379EF2501B94948 /* p11x_thread.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E380379EF2501B94948 /* p11x_thread.c */; };
+ F5448E5B0379EF2501B94948 /* p11x_util.c in Sources */ = {isa = PBXBuildFile; fileRef = F5448E3A0379EF2501B94948 /* p11x_util.c */; };
+ F5448E5C0379EF2501B94948 /* pkcs11.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E3B0379EF2501B94948 /* pkcs11.h */; };
+ F5448E5D0379EF2501B94948 /* pkcs11f.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E3C0379EF2501B94948 /* pkcs11f.h */; };
+ F5448E5E0379EF2501B94948 /* pkcs11t.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E3D0379EF2501B94948 /* pkcs11t.h */; };
+ F5448E5F0379EF2501B94948 /* thread_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F5448E3E0379EF2501B94948 /* thread_generic.h */; };
+ F5448E6A0379F08001B94948 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ F5448E6B0379F08001B94948 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ F5448E6C0379F08001B94948 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ F5448E6D0379F08001B94948 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ F5448E6E0379F08001B94948 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ F5448E6F0379F08001B94948 /* PCSC.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E630379F08001B94948 /* PCSC.framework */; };
+ F5448E760379F15F01B94948 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F5448E750379F15F01B94948 /* libz.dylib */; };
+ F555DF360274962801D2E99F /* powermgt_macosx.c in Sources */ = {isa = PBXBuildFile; fileRef = F555DF350274962801D2E99F /* powermgt_macosx.c */; };
+ F555DF380274968F01D2E99F /* powermgt_generic.h in Headers */ = {isa = PBXBuildFile; fileRef = F555DF370274968F01D2E99F /* powermgt_generic.h */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXBundleTarget section */
+ 2CBB605A06CA6944006AA7C8 /* GSCISPlugin */ = {
+ isa = PBXBundleTarget;
+ buildConfigurationList = C27AD1DF0987FCDC001272E0 /* Build configuration list for PBXBundleTarget "GSCISPlugin" */;
+ buildPhases = (
+ 2CBB605506CA6944006AA7C8 /* Headers */,
+ 2CBB605606CA6944006AA7C8 /* Resources */,
+ 2CBB605706CA6944006AA7C8 /* Sources */,
+ 2CBB605806CA6944006AA7C8 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = GSCISPlugin;
+ productInstallPath = /usr/libexec/SmartCardServices/services;
+ productName = GSCISPlugin;
+ productReference = 2CBB605B06CA6944006AA7C8 /* GSCISPlugin.bundle */;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>gscisPlugin</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.gscisplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>GSCISPLUGIN</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>2.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>34733</string>
+</dict>
+</plist>
+";
+ };
+ F537A7D10379ED7501B94948 /* PKCS11 */ = {
+ isa = PBXBundleTarget;
+ buildConfigurationList = C27AD1D50987FCDC001272E0 /* Build configuration list for PBXBundleTarget "PKCS11" */;
+ buildPhases = (
+ F537A7CC0379ED7501B94948 /* Headers */,
+ F537A7CD0379ED7501B94948 /* Resources */,
+ F537A7CE0379ED7501B94948 /* Sources */,
+ F537A7CF0379ED7501B94948 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = PKCS11;
+ productInstallPath = /usr/libexec/SmartCardServices/pkcs11;
+ productName = pkcs11;
+ productReference = F537A7D20379ED7501B94948 /* pkcs11.bundle */;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string></string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.pkcs11</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>PKCS11</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>6.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>34733</string>
+</dict>
+</plist>
+";
+ };
+ F5448E020379EE2A01B94948 /* MCardPlugin */ = {
+ isa = PBXBundleTarget;
+ buildConfigurationList = C27AD1DA0987FCDC001272E0 /* Build configuration list for PBXBundleTarget "MCardPlugin" */;
+ buildPhases = (
+ F5448DFD0379EE2A01B94948 /* Headers */,
+ F5448DFE0379EE2A01B94948 /* Resources */,
+ F5448DFF0379EE2A01B94948 /* Sources */,
+ F5448E000379EE2A01B94948 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = MCardPlugin;
+ productInstallPath = /usr/libexec/SmartCardServices/services;
+ productName = MCardPlugin;
+ productReference = F5448E030379EE2A01B94948 /* mscMuscleCard.bundle */;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>mscMuscleCard</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.mcardplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>MCARDPLUGIN</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>6.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>34733</string>
+ <key>spAtrValue</key>
+ <string>3B751300009C02020102</string>
+ <key>spDefaultApplication</key>
+ <string>A00000000101</string>
+ <key>spProductName</key>
+ <string>MuscleCard Applet</string>
+ <key>spVendorName</key>
+ <string>MUSCLE</string>
+</dict>
+</plist>
+";
+ };
+ F5448E090379EE3601B94948 /* CACPlugin */ = {
+ isa = PBXBundleTarget;
+ buildConfigurationList = C27AD1E40987FCDC001272E0 /* Build configuration list for PBXBundleTarget "CACPlugin" */;
+ buildPhases = (
+ F5448E040379EE3601B94948 /* Headers */,
+ F5448E050379EE3601B94948 /* Resources */,
+ F5448E060379EE3601B94948 /* Sources */,
+ F5448E070379EE3601B94948 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = CACPlugin;
+ productInstallPath = /usr/libexec/SmartCardServices/services;
+ productName = CACPlugin;
+ productReference = F5448E0A0379EE3601B94948 /* commonAccessCard.bundle */;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>commonAccessCard</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.cacplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>CACPLUGIN</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>6.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>34733</string>
+ <key>spAtrValue</key>
+ <array>
+ <string>3B6500009C02020102</string>
+ <string>3B7D110000003180718E6486D60100819000</string>
+ <string>3B7F1100000031C053CAC4016452D90400829000</string>
+ <string>3B6500009C02020702</string>
+ </array>
+ <key>spDefaultApplication</key>
+ <string>A0000000790101</string>
+ <key>spProductName</key>
+ <string>Common Access Card</string>
+ <key>spVendorName</key>
+ <string>Department of Defense</string>
+</dict>
+</plist>
+";
+ };
+ F5448E100379EE6401B94948 /* CFlexPlugin */ = {
+ isa = PBXBundleTarget;
+ buildConfigurationList = C27AD1E90987FCDC001272E0 /* Build configuration list for PBXBundleTarget "CFlexPlugin" */;
+ buildPhases = (
+ F5448E0B0379EE6401B94948 /* Headers */,
+ F5448E0C0379EE6401B94948 /* Resources */,
+ F5448E0D0379EE6401B94948 /* Sources */,
+ F5448E0E0379EE6401B94948 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = CFlexPlugin;
+ productInstallPath = /usr/libexec/SmartCardServices/services;
+ productName = CFlexPlugin;
+ productReference = F5448E110379EE6401B94948 /* slbCryptoflex.bundle */;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>slbCryptoflex</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.cflexplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>CFLEXPLUGIN</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>6.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>34733</string>
+ <key>spAtrValue</key>
+ <string>3B959440FF6301010201</string>
+ <key>spDefaultApplication</key>
+ <string>A00000000101</string>
+ <key>spProductName</key>
+ <string>Cryptoflex 16K</string>
+ <key>spVendorName</key>
+ <string>SchlumbergerSema</string>
+</dict>
+</plist>
+";
+ };
+/* End PBXBundleTarget section */
+
+/* Begin PBXContainerItemProxy section */
+ 2CBB607406CA6DDE006AA7C8 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 2CBB605A06CA6944006AA7C8;
+ remoteInfo = GSCISPlugin;
+ };
+ 4CFE9C05059254C8007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F5448E020379EE2A01B94948;
+ remoteInfo = MCardPlugin;
+ };
+ 4CFE9C06059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F5294A800090C73501CD285A;
+ remoteInfo = pcscd;
+ };
+ 4CFE9C07059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F5448E100379EE6401B94948;
+ remoteInfo = CFlexPlugin;
+ };
+ 4CFE9C09059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F538896903953B79012F6BBF;
+ remoteInfo = InstallPhase;
+ };
+ 4CFE9C0A059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F5448E090379EE3601B94948;
+ remoteInfo = CACPlugin;
+ };
+ 4CFE9C0B059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F537A7D10379ED7501B94948;
+ remoteInfo = PKCS11;
+ };
+ 4CFE9C0C059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F51121270272F895017BB957;
+ remoteInfo = pcsctool;
+ };
+ 4CFE9C0D059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F5294AD40090CAE601CD285A;
+ remoteInfo = pcsctest;
+ };
+ 4CFE9C0E059254C9007119DE /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = F5294A4F0090C4CA01CD285A /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = F52A93D402541D8C01B94B21;
+ remoteInfo = PCSC;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+ 2CBB605B06CA6944006AA7C8 /* GSCISPlugin.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = GSCISPlugin.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ 2CBB606306CA69F9006AA7C8 /* GSCISPlugin.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = GSCISPlugin.c; path = src/GSCISPlugin/GSCISPlugin.c; sourceTree = SOURCE_ROOT; };
+ 2CBB606406CA69F9006AA7C8 /* GSCISPlugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = GSCISPlugin.h; path = src/GSCISPlugin/GSCISPlugin.h; sourceTree = SOURCE_ROOT; };
+ 2CC9AB9A06CC036D0048A811 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+ 2CC9ABC806CC03A10048A811 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+ 4CB55A760592598500B25B27 /* Makefile.installPhase */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = Makefile.installPhase; sourceTree = "<group>"; };
+ 5236DD1C0B9DDBD7007CEF56 /* readerstate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = readerstate.cpp; path = src/PCSC/readerstate.cpp; sourceTree = "<group>"; };
+ 5236DD1D0B9DDBD7007CEF56 /* readerstate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = readerstate.h; path = src/PCSC/readerstate.h; sourceTree = "<group>"; };
+ 527CF60A0AA5192B007589FF /* pcscdmonitor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pcscdmonitor.cpp; path = src/PCSC/pcscdmonitor.cpp; sourceTree = "<group>"; };
+ 527CF60B0AA5192B007589FF /* pcscdmonitor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pcscdmonitor.h; path = src/PCSC/pcscdmonitor.h; sourceTree = "<group>"; };
+ 527CF60C0AA5192B007589FF /* pcscdserver.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = pcscdserver.cpp; path = src/PCSC/pcscdserver.cpp; sourceTree = "<group>"; };
+ 527CF60D0AA5192B007589FF /* pcscdserver.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pcscdserver.h; path = src/PCSC/pcscdserver.h; sourceTree = "<group>"; };
+ 5286293C0A87EA8E004FE8DC /* hotplug_macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = hotplug_macosx.cpp; path = src/PCSC/hotplug_macosx.cpp; sourceTree = "<group>"; };
+ 5286293D0A87EA8E004FE8DC /* PCSCDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PCSCDevice.cpp; path = src/PCSC/PCSCDevice.cpp; sourceTree = "<group>"; };
+ 5286293E0A87EA8E004FE8DC /* PCSCDevice.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCSCDevice.h; path = src/PCSC/PCSCDevice.h; sourceTree = "<group>"; };
+ 5286293F0A87EA8E004FE8DC /* PCSCDriverBundle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PCSCDriverBundle.cpp; path = src/PCSC/PCSCDriverBundle.cpp; sourceTree = "<group>"; };
+ 528629400A87EA8E004FE8DC /* PCSCDriverBundle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCSCDriverBundle.h; path = src/PCSC/PCSCDriverBundle.h; sourceTree = "<group>"; };
+ 528629410A87EA8E004FE8DC /* PCSCDriverBundles.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PCSCDriverBundles.cpp; path = src/PCSC/PCSCDriverBundles.cpp; sourceTree = "<group>"; };
+ 528629420A87EA8E004FE8DC /* PCSCDriverBundles.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PCSCDriverBundles.h; path = src/PCSC/PCSCDriverBundles.h; sourceTree = "<group>"; };
+ 52D00D1A0A9252350093277A /* reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reader.h; path = src/PCSC/reader.h; sourceTree = "<group>"; };
+ 52D00D1B0A9252350093277A /* reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = reader.cpp; path = src/PCSC/reader.cpp; sourceTree = "<group>"; };
+ 52D2492C0BA07E1100F9827A /* winscard_msg_srv.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = winscard_msg_srv.c; path = src/PCSC/winscard_msg_srv.c; sourceTree = "<group>"; };
+ 52D58C080A87FEA000DC3F19 /* security_utilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = security_utilities.framework; path = /usr/local/SecurityPieces/Frameworks/security_utilities.framework; sourceTree = "<absolute>"; };
+ 52DBCAAE0BB851C8007D06A5 /* PCSC.exp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.exports; name = PCSC.exp; path = src/PCSC/PCSC.exp; sourceTree = "<group>"; };
+ 52E0D59D0BA7006D008DFDDF /* winscard.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = winscard.c; path = src/PCSC/winscard.c; sourceTree = "<group>"; };
+ C2F2094A0662B851001DFD06 /* sys_macosx.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = sys_macosx.cpp; path = src/PCSC/sys_macosx.cpp; sourceTree = "<group>"; };
+ F503CACD025425E601B94B21 /* testpcsc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = testpcsc.c; path = src/PCSC/testpcsc.c; sourceTree = "<group>"; };
+ F503CACE025425E601B94B21 /* muscletest.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = muscletest.c; path = src/PCSC/muscletest.c; sourceTree = "<group>"; };
+ F503CADB025428F601B94B21 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+ F503CADC025428F601B94B21 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = "<absolute>"; };
+ F503CADF0254294101B94B21 /* libl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libl.a; path = /usr/lib/libl.a; sourceTree = "<absolute>"; };
+ F51121260272F895017BB957 /* pcsctool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; path = pcsctool; sourceTree = BUILT_PRODUCTS_DIR; };
+ F511212C0272F8D9017BB957 /* bundleTool.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = bundleTool.c; path = src/PCSC/utils/bundleTool.c; sourceTree = "<group>"; };
+ F5294A7E0090C73501CD285A /* pcscd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; path = pcscd; sourceTree = BUILT_PRODUCTS_DIR; };
+ F5294AD30090CAE601CD285A /* pcsctest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; path = pcsctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ F52A93D102541D8C01B94B21 /* PCSC.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = PCSC.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F52A94510254232701B94B21 /* atrhandler.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = atrhandler.c; path = src/PCSC/atrhandler.c; sourceTree = SOURCE_ROOT; };
+ F52A948F0254242101B94B21 /* atrhandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = atrhandler.h; path = src/PCSC/atrhandler.h; sourceTree = SOURCE_ROOT; };
+ F52A94900254242101B94B21 /* configfile.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = configfile.c; path = src/PCSC/configfile.c; sourceTree = SOURCE_ROOT; };
+ F52A94910254242101B94B21 /* configfile.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = configfile.h; path = src/PCSC/configfile.h; sourceTree = SOURCE_ROOT; };
+ F52A94920254242101B94B21 /* debuglog.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = debuglog.c; path = src/PCSC/debuglog.c; sourceTree = SOURCE_ROOT; };
+ F52A94930254242101B94B21 /* debuglog.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = debuglog.h; path = src/PCSC/debuglog.h; sourceTree = SOURCE_ROOT; };
+ F52A94940254242101B94B21 /* dyn_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = dyn_generic.h; path = src/PCSC/dyn_generic.h; sourceTree = SOURCE_ROOT; };
+ F52A94950254242101B94B21 /* dyn_macosx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = dyn_macosx.c; path = src/PCSC/dyn_macosx.c; sourceTree = SOURCE_ROOT; };
+ F52A94960254242101B94B21 /* eventhandler.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = eventhandler.cpp; path = src/PCSC/eventhandler.cpp; sourceTree = "<group>"; };
+ F52A94970254242101B94B21 /* eventhandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = eventhandler.h; path = src/PCSC/eventhandler.h; sourceTree = SOURCE_ROOT; };
+ F52A94990254242101B94B21 /* hotplug.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = hotplug.h; path = src/PCSC/hotplug.h; sourceTree = SOURCE_ROOT; };
+ F52A949A0254242101B94B21 /* ifdhandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ifdhandler.h; path = src/PCSC/ifdhandler.h; sourceTree = SOURCE_ROOT; };
+ F52A949B0254242101B94B21 /* ifdwrapper.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = ifdwrapper.c; path = src/PCSC/ifdwrapper.c; sourceTree = SOURCE_ROOT; };
+ F52A949C0254242101B94B21 /* ifdwrapper.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ifdwrapper.h; path = src/PCSC/ifdwrapper.h; sourceTree = SOURCE_ROOT; };
+ F52A949D0254242101B94B21 /* pcscdaemon.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = pcscdaemon.c; path = src/PCSC/pcscdaemon.c; sourceTree = "<group>"; };
+ F52A949E0254242101B94B21 /* pcsclite.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pcsclite.h; path = src/PCSC/pcsclite.h; sourceTree = SOURCE_ROOT; };
+ F52A949F0254242101B94B21 /* prothandler.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = prothandler.c; path = src/PCSC/prothandler.c; sourceTree = SOURCE_ROOT; };
+ F52A94A00254242101B94B21 /* prothandler.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = prothandler.h; path = src/PCSC/prothandler.h; sourceTree = SOURCE_ROOT; };
+ F52A94A10254242101B94B21 /* readerfactory.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = readerfactory.c; path = src/PCSC/readerfactory.c; sourceTree = "<group>"; };
+ F52A94A20254242101B94B21 /* readerfactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = readerfactory.h; path = src/PCSC/readerfactory.h; sourceTree = "<group>"; };
+ F52A94A30254242101B94B21 /* sys_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = sys_generic.h; path = src/PCSC/sys_generic.h; sourceTree = SOURCE_ROOT; };
+ F52A94A40254242101B94B21 /* sys_unix.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = sys_unix.c; path = src/PCSC/sys_unix.c; sourceTree = SOURCE_ROOT; };
+ F52A94A50254242101B94B21 /* thread_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = thread_generic.h; path = src/PCSC/thread_generic.h; sourceTree = SOURCE_ROOT; };
+ F52A94A60254242101B94B21 /* thread_macosx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = thread_macosx.c; path = src/PCSC/thread_macosx.c; sourceTree = SOURCE_ROOT; };
+ F52A94A70254242101B94B21 /* winscard_msg.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = winscard_msg.cpp; path = src/PCSC/winscard_msg.cpp; sourceTree = "<group>"; };
+ F52A94A80254242101B94B21 /* winscard_msg.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = winscard_msg.h; path = src/PCSC/winscard_msg.h; sourceTree = SOURCE_ROOT; };
+ F52A94A90254242101B94B21 /* winscard_svc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = winscard_svc.c; path = src/PCSC/winscard_svc.c; sourceTree = SOURCE_ROOT; };
+ F52A94AA0254242101B94B21 /* winscard_svc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = winscard_svc.h; path = src/PCSC/winscard_svc.h; sourceTree = SOURCE_ROOT; };
+ F52A94AC0254242101B94B21 /* winscard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = winscard.h; path = src/PCSC/winscard.h; sourceTree = SOURCE_ROOT; };
+ F52A94AD0254242101B94B21 /* wintypes.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = wintypes.h; path = src/PCSC/wintypes.h; sourceTree = SOURCE_ROOT; };
+ F52A94CD025424AC01B94B21 /* mscdefines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = mscdefines.h; path = src/PCSC/mscdefines.h; sourceTree = SOURCE_ROOT; };
+ F52A94CE025424AC01B94B21 /* musclecard.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = musclecard.c; path = src/PCSC/musclecard.c; sourceTree = SOURCE_ROOT; };
+ F52A94CF025424AC01B94B21 /* musclecard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = musclecard.h; path = src/PCSC/musclecard.h; sourceTree = SOURCE_ROOT; };
+ F52A94D0025424AC01B94B21 /* tokenfactory.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = tokenfactory.c; path = src/PCSC/tokenfactory.c; sourceTree = SOURCE_ROOT; };
+ F52A94D1025424AC01B94B21 /* tokenfactory.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = tokenfactory.h; path = src/PCSC/tokenfactory.h; sourceTree = SOURCE_ROOT; };
+ F52A94D2025424AC01B94B21 /* tokenparser.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = tokenparser.c; path = src/PCSC/tokenparser.c; sourceTree = SOURCE_ROOT; };
+ F52A94D4025424AC01B94B21 /* winscard_clnt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = winscard_clnt.c; path = src/PCSC/winscard_clnt.c; sourceTree = SOURCE_ROOT; };
+ F537A7B30379EB7B01B94948 /* config.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = config.h; path = src/PCSC/config.h; sourceTree = SOURCE_ROOT; };
+ F537A7D20379ED7501B94948 /* pkcs11.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = pkcs11.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ F5448E030379EE2A01B94948 /* mscMuscleCard.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = mscMuscleCard.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ F5448E0A0379EE3601B94948 /* commonAccessCard.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = commonAccessCard.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ F5448E110379EE6401B94948 /* slbCryptoflex.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; path = slbCryptoflex.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
+ F5448E120379EEA101B94948 /* musclecardApplet.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = musclecardApplet.c; path = src/MCardPlugin/musclecardApplet.c; sourceTree = SOURCE_ROOT; };
+ F5448E130379EEA101B94948 /* musclecardApplet.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = musclecardApplet.h; path = src/MCardPlugin/musclecardApplet.h; sourceTree = SOURCE_ROOT; };
+ F5448E160379EEC301B94948 /* cryptoflex.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = cryptoflex.c; path = src/CFlexPlugin/cryptoflex.c; sourceTree = SOURCE_ROOT; };
+ F5448E170379EEC301B94948 /* cryptoflex.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cryptoflex.h; path = src/CFlexPlugin/cryptoflex.h; sourceTree = SOURCE_ROOT; };
+ F5448E1A0379EEDD01B94948 /* commonAccessCard.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = commonAccessCard.c; path = src/CACPlugin/commonAccessCard.c; sourceTree = SOURCE_ROOT; };
+ F5448E1B0379EEDD01B94948 /* commonAccessCard.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = commonAccessCard.h; path = src/CACPlugin/commonAccessCard.h; sourceTree = SOURCE_ROOT; };
+ F5448E1E0379EF2501B94948 /* cryptoki_unix.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cryptoki_unix.h; path = src/PKCS11/cryptoki_unix.h; sourceTree = SOURCE_ROOT; };
+ F5448E1F0379EF2501B94948 /* cryptoki.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = cryptoki.h; path = src/PKCS11/cryptoki.h; sourceTree = SOURCE_ROOT; };
+ F5448E200379EF2501B94948 /* p11_crypt.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_crypt.c; path = src/PKCS11/p11_crypt.c; sourceTree = SOURCE_ROOT; };
+ F5448E210379EF2501B94948 /* p11_digest.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_digest.c; path = src/PKCS11/p11_digest.c; sourceTree = SOURCE_ROOT; };
+ F5448E220379EF2501B94948 /* p11_dual.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_dual.c; path = src/PKCS11/p11_dual.c; sourceTree = SOURCE_ROOT; };
+ F5448E230379EF2501B94948 /* p11_ext.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_ext.c; path = src/PKCS11/p11_ext.c; sourceTree = SOURCE_ROOT; };
+ F5448E240379EF2501B94948 /* p11_general.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_general.c; path = src/PKCS11/p11_general.c; sourceTree = SOURCE_ROOT; };
+ F5448E250379EF2501B94948 /* p11_key.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_key.c; path = src/PKCS11/p11_key.c; sourceTree = SOURCE_ROOT; };
+ F5448E260379EF2501B94948 /* p11_object.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_object.c; path = src/PKCS11/p11_object.c; sourceTree = SOURCE_ROOT; };
+ F5448E270379EF2501B94948 /* p11_parallel.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_parallel.c; path = src/PKCS11/p11_parallel.c; sourceTree = SOURCE_ROOT; };
+ F5448E280379EF2501B94948 /* p11_random.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_random.c; path = src/PKCS11/p11_random.c; sourceTree = SOURCE_ROOT; };
+ F5448E290379EF2501B94948 /* p11_session.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_session.c; path = src/PKCS11/p11_session.c; sourceTree = SOURCE_ROOT; };
+ F5448E2A0379EF2501B94948 /* p11_sign.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_sign.c; path = src/PKCS11/p11_sign.c; sourceTree = SOURCE_ROOT; };
+ F5448E2B0379EF2501B94948 /* p11_token.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_token.c; path = src/PKCS11/p11_token.c; sourceTree = SOURCE_ROOT; };
+ F5448E2C0379EF2501B94948 /* p11_verify.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11_verify.c; path = src/PKCS11/p11_verify.c; sourceTree = SOURCE_ROOT; };
+ F5448E2D0379EF2501B94948 /* p11x_async.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_async.c; path = src/PKCS11/p11x_async.c; sourceTree = SOURCE_ROOT; };
+ F5448E2E0379EF2501B94948 /* p11x_bio.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_bio.c; path = src/PKCS11/p11x_bio.c; sourceTree = SOURCE_ROOT; };
+ F5448E2F0379EF2501B94948 /* p11x_error.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_error.c; path = src/PKCS11/p11x_error.c; sourceTree = SOURCE_ROOT; };
+ F5448E300379EF2501B94948 /* p11x_log.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_log.c; path = src/PKCS11/p11x_log.c; sourceTree = SOURCE_ROOT; };
+ F5448E310379EF2501B94948 /* p11x_msc.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_msc.c; path = src/PKCS11/p11x_msc.c; sourceTree = SOURCE_ROOT; };
+ F5448E320379EF2501B94948 /* p11x_msc.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = p11x_msc.h; path = src/PKCS11/p11x_msc.h; sourceTree = SOURCE_ROOT; };
+ F5448E330379EF2501B94948 /* p11x_object.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_object.c; path = src/PKCS11/p11x_object.c; sourceTree = SOURCE_ROOT; };
+ F5448E340379EF2501B94948 /* p11x_prefs.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_prefs.c; path = src/PKCS11/p11x_prefs.c; sourceTree = SOURCE_ROOT; };
+ F5448E350379EF2501B94948 /* p11x_session.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_session.c; path = src/PKCS11/p11x_session.c; sourceTree = SOURCE_ROOT; };
+ F5448E360379EF2501B94948 /* p11x_slot.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_slot.c; path = src/PKCS11/p11x_slot.c; sourceTree = SOURCE_ROOT; };
+ F5448E370379EF2501B94948 /* p11x_state.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_state.c; path = src/PKCS11/p11x_state.c; sourceTree = SOURCE_ROOT; };
+ F5448E380379EF2501B94948 /* p11x_thread.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_thread.c; path = src/PKCS11/p11x_thread.c; sourceTree = SOURCE_ROOT; };
+ F5448E3A0379EF2501B94948 /* p11x_util.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = p11x_util.c; path = src/PKCS11/p11x_util.c; sourceTree = SOURCE_ROOT; };
+ F5448E3B0379EF2501B94948 /* pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pkcs11.h; path = src/PKCS11/pkcs11.h; sourceTree = SOURCE_ROOT; };
+ F5448E3C0379EF2501B94948 /* pkcs11f.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pkcs11f.h; path = src/PKCS11/pkcs11f.h; sourceTree = SOURCE_ROOT; };
+ F5448E3D0379EF2501B94948 /* pkcs11t.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = pkcs11t.h; path = src/PKCS11/pkcs11t.h; sourceTree = SOURCE_ROOT; };
+ F5448E3E0379EF2501B94948 /* thread_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = thread_generic.h; path = src/PKCS11/thread_generic.h; sourceTree = SOURCE_ROOT; };
+ F5448E630379F08001B94948 /* PCSC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PCSC.framework; path = /System/Library/Frameworks/PCSC.framework; sourceTree = "<absolute>"; };
+ F5448E750379F15F01B94948 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.1.1.3.dylib; sourceTree = "<absolute>"; };
+ F555DF350274962801D2E99F /* powermgt_macosx.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = powermgt_macosx.c; path = src/PCSC/powermgt_macosx.c; sourceTree = SOURCE_ROOT; };
+ F555DF370274968F01D2E99F /* powermgt_generic.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = powermgt_generic.h; path = src/PCSC/powermgt_generic.h; sourceTree = SOURCE_ROOT; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworkTarget section */
+ F52A93D402541D8C01B94B21 /* PCSC */ = {
+ isa = PBXFrameworkTarget;
+ buildConfigurationList = C27AD1C10987FCDB001272E0 /* Build configuration list for PBXFrameworkTarget "PCSC" */;
+ buildPhases = (
+ F52A93D502541D8C01B94B21 /* Headers */,
+ F52A93D602541D8C01B94B21 /* Resources */,
+ F52A93D702541D8C01B94B21 /* Sources */,
+ F52A93D802541D8C01B94B21 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = PCSC;
+ productInstallPath = /System/Library/Frameworks;
+ productName = PCSC;
+ productReference = F52A93D102541D8C01B94B21 /* PCSC.framework */;
+ productSettingsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
+<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">
+<plist version=\"1.0\">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>PCSC</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>com.apple.pcsc</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>7.0</string>
+ <key>CFBundleName</key>
+ <string>PCSC</string>
+ <key>CFBundlePackageType</key>
+ <string>FMWK</string>
+ <key>CFBundleShortVersionString</key>
+ <string>6.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>34733</string>
+</dict>
+</plist>
+";
+ };
+/* End PBXFrameworkTarget section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 2CBB605806CA6944006AA7C8 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2CC9AB8406CC02F30048A811 /* PCSC.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F511212A0272F895017BB957 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E6E0379F08001B94948 /* PCSC.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5294A830090C73501CD285A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F503CADD025428F601B94B21 /* CoreFoundation.framework in Frameworks */,
+ F503CADE025428F601B94B21 /* IOKit.framework in Frameworks */,
+ F503CAE00254294101B94B21 /* libl.a in Frameworks */,
+ 52D58C090A87FEA000DC3F19 /* security_utilities.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5294AD70090CAE601CD285A /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E6A0379F08001B94948 /* PCSC.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F52A93D802541D8C01B94B21 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 52C85D900B9FA79F002DA856 /* security_utilities.framework in Frameworks */,
+ F503CAE502542A9201B94B21 /* CoreFoundation.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F537A7CF0379ED7501B94948 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E6D0379F08001B94948 /* PCSC.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E000379EE2A01B94948 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E6C0379F08001B94948 /* PCSC.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E070379EE3601B94948 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E6B0379F08001B94948 /* PCSC.framework in Frameworks */,
+ F5448E760379F15F01B94948 /* libz.dylib in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E0E0379EE6401B94948 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E6F0379F08001B94948 /* PCSC.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 2CBB605406CA680F006AA7C8 /* GSCISPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ 2CBB606306CA69F9006AA7C8 /* GSCISPlugin.c */,
+ 2CBB606406CA69F9006AA7C8 /* GSCISPlugin.h */,
+ );
+ name = GSCISPlugin;
+ sourceTree = "<group>";
+ };
+ 527CF6040AA51879007589FF /* pcscd */ = {
+ isa = PBXGroup;
+ children = (
+ 5236DD1C0B9DDBD7007CEF56 /* readerstate.cpp */,
+ 5236DD1D0B9DDBD7007CEF56 /* readerstate.h */,
+ F52A949D0254242101B94B21 /* pcscdaemon.c */,
+ 527CF60A0AA5192B007589FF /* pcscdmonitor.cpp */,
+ 527CF60B0AA5192B007589FF /* pcscdmonitor.h */,
+ 527CF60C0AA5192B007589FF /* pcscdserver.cpp */,
+ 527CF60D0AA5192B007589FF /* pcscdserver.h */,
+ 5286293C0A87EA8E004FE8DC /* hotplug_macosx.cpp */,
+ 5286293D0A87EA8E004FE8DC /* PCSCDevice.cpp */,
+ 5286293E0A87EA8E004FE8DC /* PCSCDevice.h */,
+ 5286293F0A87EA8E004FE8DC /* PCSCDriverBundle.cpp */,
+ 528629400A87EA8E004FE8DC /* PCSCDriverBundle.h */,
+ 528629410A87EA8E004FE8DC /* PCSCDriverBundles.cpp */,
+ 528629420A87EA8E004FE8DC /* PCSCDriverBundles.h */,
+ F52A94A10254242101B94B21 /* readerfactory.c */,
+ F52A94A20254242101B94B21 /* readerfactory.h */,
+ 52D00D1A0A9252350093277A /* reader.h */,
+ 52D00D1B0A9252350093277A /* reader.cpp */,
+ );
+ name = pcscd;
+ sourceTree = "<group>";
+ };
+ 527CF6070AA51881007589FF /* framework */ = {
+ isa = PBXGroup;
+ children = (
+ 52DBCAAE0BB851C8007D06A5 /* PCSC.exp */,
+ );
+ name = framework;
+ sourceTree = "<group>";
+ };
+ 527CF6240AA51B07007589FF /* tools */ = {
+ isa = PBXGroup;
+ children = (
+ F503CACD025425E601B94B21 /* testpcsc.c */,
+ F503CACE025425E601B94B21 /* muscletest.c */,
+ F511212C0272F8D9017BB957 /* bundleTool.c */,
+ );
+ name = tools;
+ sourceTree = "<group>";
+ };
+ F5294A500090C4CA01CD285A = {
+ isa = PBXGroup;
+ children = (
+ 52D58C080A87FEA000DC3F19 /* security_utilities.framework */,
+ F538896A0397E93B012F6BBF /* InstallPhase */,
+ F537A7CB0379ECEB01B94948 /* MCardPlugin */,
+ 2CBB605406CA680F006AA7C8 /* GSCISPlugin */,
+ F537A7CA0379ECE301B94948 /* CFlexPlugin */,
+ F537A7C90379ECDC01B94948 /* CACPlugin */,
+ F537A7C80379ECD501B94948 /* PKCS11 */,
+ F537A7B50379EB8B01B94948 /* PCSC */,
+ F5294A520090C5DF01CD285A /* Products */,
+ F5448E630379F08001B94948 /* PCSC.framework */,
+ 2CC9AB9A06CC036D0048A811 /* CoreFoundation.framework */,
+ 2CC9ABC806CC03A10048A811 /* IOKit.framework */,
+ );
+ sourceTree = "<group>";
+ };
+ F5294A520090C5DF01CD285A /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ F5294A7E0090C73501CD285A /* pcscd */,
+ F5294AD30090CAE601CD285A /* pcsctest */,
+ F52A93D102541D8C01B94B21 /* PCSC.framework */,
+ F51121260272F895017BB957 /* pcsctool */,
+ F537A7D20379ED7501B94948 /* pkcs11.bundle */,
+ F5448E030379EE2A01B94948 /* mscMuscleCard.bundle */,
+ F5448E0A0379EE3601B94948 /* commonAccessCard.bundle */,
+ F5448E110379EE6401B94948 /* slbCryptoflex.bundle */,
+ 2CBB605B06CA6944006AA7C8 /* GSCISPlugin.bundle */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ F537A7B50379EB8B01B94948 /* PCSC */ = {
+ isa = PBXGroup;
+ children = (
+ 527CF6240AA51B07007589FF /* tools */,
+ 527CF6070AA51881007589FF /* framework */,
+ 527CF6040AA51879007589FF /* pcscd */,
+ F52A94510254232701B94B21 /* atrhandler.c */,
+ F52A948F0254242101B94B21 /* atrhandler.h */,
+ F52A94900254242101B94B21 /* configfile.c */,
+ F52A94910254242101B94B21 /* configfile.h */,
+ F52A94920254242101B94B21 /* debuglog.c */,
+ F52A94930254242101B94B21 /* debuglog.h */,
+ F52A94940254242101B94B21 /* dyn_generic.h */,
+ F52A94950254242101B94B21 /* dyn_macosx.c */,
+ F52A94960254242101B94B21 /* eventhandler.cpp */,
+ F52A94970254242101B94B21 /* eventhandler.h */,
+ F52A94990254242101B94B21 /* hotplug.h */,
+ F52A949A0254242101B94B21 /* ifdhandler.h */,
+ F52A949B0254242101B94B21 /* ifdwrapper.c */,
+ F52A949C0254242101B94B21 /* ifdwrapper.h */,
+ F52A949E0254242101B94B21 /* pcsclite.h */,
+ F52A949F0254242101B94B21 /* prothandler.c */,
+ F52A94A00254242101B94B21 /* prothandler.h */,
+ F52A94A30254242101B94B21 /* sys_generic.h */,
+ F52A94A40254242101B94B21 /* sys_unix.c */,
+ C2F2094A0662B851001DFD06 /* sys_macosx.cpp */,
+ F52A94A50254242101B94B21 /* thread_generic.h */,
+ F52A94A60254242101B94B21 /* thread_macosx.c */,
+ 52E0D59D0BA7006D008DFDDF /* winscard.c */,
+ F52A94A70254242101B94B21 /* winscard_msg.cpp */,
+ F52A94A80254242101B94B21 /* winscard_msg.h */,
+ F52A94A90254242101B94B21 /* winscard_svc.c */,
+ 52D2492C0BA07E1100F9827A /* winscard_msg_srv.c */,
+ F52A94AA0254242101B94B21 /* winscard_svc.h */,
+ F52A94CD025424AC01B94B21 /* mscdefines.h */,
+ F52A94AC0254242101B94B21 /* winscard.h */,
+ F52A94CF025424AC01B94B21 /* musclecard.h */,
+ F52A94AD0254242101B94B21 /* wintypes.h */,
+ F52A94CE025424AC01B94B21 /* musclecard.c */,
+ F555DF370274968F01D2E99F /* powermgt_generic.h */,
+ F555DF350274962801D2E99F /* powermgt_macosx.c */,
+ F52A94D0025424AC01B94B21 /* tokenfactory.c */,
+ F52A94D1025424AC01B94B21 /* tokenfactory.h */,
+ F52A94D2025424AC01B94B21 /* tokenparser.c */,
+ F52A94D4025424AC01B94B21 /* winscard_clnt.c */,
+ F537A7B30379EB7B01B94948 /* config.h */,
+ F503CADF0254294101B94B21 /* libl.a */,
+ F503CADC025428F601B94B21 /* IOKit.framework */,
+ F503CADB025428F601B94B21 /* CoreFoundation.framework */,
+ );
+ name = PCSC;
+ sourceTree = "<group>";
+ };
+ F537A7C80379ECD501B94948 /* PKCS11 */ = {
+ isa = PBXGroup;
+ children = (
+ F5448E1E0379EF2501B94948 /* cryptoki_unix.h */,
+ F5448E1F0379EF2501B94948 /* cryptoki.h */,
+ F5448E200379EF2501B94948 /* p11_crypt.c */,
+ F5448E210379EF2501B94948 /* p11_digest.c */,
+ F5448E220379EF2501B94948 /* p11_dual.c */,
+ F5448E230379EF2501B94948 /* p11_ext.c */,
+ F5448E240379EF2501B94948 /* p11_general.c */,
+ F5448E250379EF2501B94948 /* p11_key.c */,
+ F5448E260379EF2501B94948 /* p11_object.c */,
+ F5448E270379EF2501B94948 /* p11_parallel.c */,
+ F5448E280379EF2501B94948 /* p11_random.c */,
+ F5448E290379EF2501B94948 /* p11_session.c */,
+ F5448E2A0379EF2501B94948 /* p11_sign.c */,
+ F5448E2B0379EF2501B94948 /* p11_token.c */,
+ F5448E2C0379EF2501B94948 /* p11_verify.c */,
+ F5448E2D0379EF2501B94948 /* p11x_async.c */,
+ F5448E2E0379EF2501B94948 /* p11x_bio.c */,
+ F5448E2F0379EF2501B94948 /* p11x_error.c */,
+ F5448E300379EF2501B94948 /* p11x_log.c */,
+ F5448E310379EF2501B94948 /* p11x_msc.c */,
+ F5448E320379EF2501B94948 /* p11x_msc.h */,
+ F5448E330379EF2501B94948 /* p11x_object.c */,
+ F5448E340379EF2501B94948 /* p11x_prefs.c */,
+ F5448E350379EF2501B94948 /* p11x_session.c */,
+ F5448E360379EF2501B94948 /* p11x_slot.c */,
+ F5448E370379EF2501B94948 /* p11x_state.c */,
+ F5448E380379EF2501B94948 /* p11x_thread.c */,
+ F5448E3A0379EF2501B94948 /* p11x_util.c */,
+ F5448E3B0379EF2501B94948 /* pkcs11.h */,
+ F5448E3C0379EF2501B94948 /* pkcs11f.h */,
+ F5448E3D0379EF2501B94948 /* pkcs11t.h */,
+ F5448E3E0379EF2501B94948 /* thread_generic.h */,
+ );
+ name = PKCS11;
+ sourceTree = "<group>";
+ };
+ F537A7C90379ECDC01B94948 /* CACPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ F5448E1A0379EEDD01B94948 /* commonAccessCard.c */,
+ F5448E1B0379EEDD01B94948 /* commonAccessCard.h */,
+ F5448E750379F15F01B94948 /* libz.dylib */,
+ );
+ name = CACPlugin;
+ sourceTree = "<group>";
+ };
+ F537A7CA0379ECE301B94948 /* CFlexPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ F5448E160379EEC301B94948 /* cryptoflex.c */,
+ F5448E170379EEC301B94948 /* cryptoflex.h */,
+ );
+ name = CFlexPlugin;
+ sourceTree = "<group>";
+ };
+ F537A7CB0379ECEB01B94948 /* MCardPlugin */ = {
+ isa = PBXGroup;
+ children = (
+ F5448E120379EEA101B94948 /* musclecardApplet.c */,
+ F5448E130379EEA101B94948 /* musclecardApplet.h */,
+ );
+ name = MCardPlugin;
+ sourceTree = "<group>";
+ };
+ F538896A0397E93B012F6BBF /* InstallPhase */ = {
+ isa = PBXGroup;
+ children = (
+ 4CB55A760592598500B25B27 /* Makefile.installPhase */,
+ );
+ name = InstallPhase;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXHeadersBuildPhase section */
+ 2CBB605506CA6944006AA7C8 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2CBB606606CA69F9006AA7C8 /* GSCISPlugin.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F51121280272F895017BB957 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5294A810090C73501CD285A /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F52A94AE0254242101B94B21 /* atrhandler.h in Headers */,
+ F52A94AF0254242101B94B21 /* configfile.h in Headers */,
+ F52A94B00254242101B94B21 /* debuglog.h in Headers */,
+ F52A94B10254242101B94B21 /* dyn_generic.h in Headers */,
+ F52A94B20254242101B94B21 /* eventhandler.h in Headers */,
+ F52A94B30254242101B94B21 /* hotplug.h in Headers */,
+ F52A94B40254242101B94B21 /* ifdhandler.h in Headers */,
+ F52A94B50254242101B94B21 /* ifdwrapper.h in Headers */,
+ F52A94B60254242101B94B21 /* pcsclite.h in Headers */,
+ F52A94B70254242101B94B21 /* prothandler.h in Headers */,
+ F52A94B80254242101B94B21 /* readerfactory.h in Headers */,
+ F52A94B90254242101B94B21 /* sys_generic.h in Headers */,
+ F52A94BA0254242101B94B21 /* thread_generic.h in Headers */,
+ F52A94BB0254242101B94B21 /* winscard_msg.h in Headers */,
+ F52A94BC0254242101B94B21 /* winscard_svc.h in Headers */,
+ F52A94BD0254242101B94B21 /* winscard.h in Headers */,
+ F52A94BE0254242101B94B21 /* wintypes.h in Headers */,
+ F555DF380274968F01D2E99F /* powermgt_generic.h in Headers */,
+ 5286294B0A87EA8E004FE8DC /* PCSCDevice.h in Headers */,
+ 5286294D0A87EA8E004FE8DC /* PCSCDriverBundle.h in Headers */,
+ 5286294F0A87EA8E004FE8DC /* PCSCDriverBundles.h in Headers */,
+ 52D00D1C0A9252350093277A /* reader.h in Headers */,
+ 527CF60F0AA5192B007589FF /* pcscdmonitor.h in Headers */,
+ 527CF6110AA5192B007589FF /* pcscdserver.h in Headers */,
+ 5236DD1F0B9DDBD7007CEF56 /* readerstate.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5294AD50090CAE601CD285A /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F52A93D502541D8C01B94B21 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F52A94D5025424AC01B94B21 /* thread_generic.h in Headers */,
+ F52A94D6025424AC01B94B21 /* pcsclite.h in Headers */,
+ F52A94D7025424AC01B94B21 /* mscdefines.h in Headers */,
+ F52A94D8025424AC01B94B21 /* musclecard.h in Headers */,
+ F52A94D9025424AC01B94B21 /* winscard_msg.h in Headers */,
+ F52A94DA025424AC01B94B21 /* tokenfactory.h in Headers */,
+ F52A94DB025424AC01B94B21 /* winscard.h in Headers */,
+ F52A94DC025424AC01B94B21 /* dyn_generic.h in Headers */,
+ F503CAE402542A9201B94B21 /* wintypes.h in Headers */,
+ F52A94DD025424AC01B94B21 /* debuglog.h in Headers */,
+ F537A7B40379EB7B01B94948 /* config.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F537A7CC0379ED7501B94948 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E3F0379EF2501B94948 /* cryptoki_unix.h in Headers */,
+ F5448E400379EF2501B94948 /* cryptoki.h in Headers */,
+ F5448E530379EF2501B94948 /* p11x_msc.h in Headers */,
+ F5448E5C0379EF2501B94948 /* pkcs11.h in Headers */,
+ F5448E5D0379EF2501B94948 /* pkcs11f.h in Headers */,
+ F5448E5E0379EF2501B94948 /* pkcs11t.h in Headers */,
+ F5448E5F0379EF2501B94948 /* thread_generic.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448DFD0379EE2A01B94948 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E150379EEA101B94948 /* musclecardApplet.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E040379EE3601B94948 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E1D0379EEDD01B94948 /* commonAccessCard.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E0B0379EE6401B94948 /* Headers */ = {
+ isa = PBXHeadersBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E190379EEC301B94948 /* cryptoflex.h in Headers */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXHeadersBuildPhase section */
+
+/* Begin PBXLegacyTarget section */
+ F538896903953B79012F6BBF /* InstallPhase */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "-f Makefile.installPhase $ALL_SETTINGS $ACTION";
+ buildConfigurationList = C27AD1EE0987FCDC001272E0 /* Build configuration list for PBXLegacyTarget "InstallPhase" */;
+ buildPhases = (
+ );
+ buildToolPath = /usr/bin/gnumake;
+ buildWorkingDirectory = "";
+ dependencies = (
+ );
+ name = InstallPhase;
+ passBuildSettingsInEnvironment = 1;
+ productName = InstallPhase;
+ };
+/* End PBXLegacyTarget section */
+
+/* Begin PBXProject section */
+ F5294A4F0090C4CA01CD285A /* Project object */ = {
+ isa = PBXProject;
+ buildConfigurationList = C27AD1FD0987FCDC001272E0 /* Build configuration list for PBXProject "SmartCardServices" */;
+ compatibilityVersion = "Xcode 2.4";
+ hasScannedForEncodings = 1;
+ mainGroup = F5294A500090C4CA01CD285A;
+ productRefGroup = F5294A520090C5DF01CD285A /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ F5294A510090C54E01CD285A /* World */,
+ F5294A800090C73501CD285A /* pcscd */,
+ F52A93D402541D8C01B94B21 /* PCSC */,
+ F5294AD40090CAE601CD285A /* pcsctest */,
+ F51121270272F895017BB957 /* pcsctool */,
+ F537A7D10379ED7501B94948 /* PKCS11 */,
+ F5448E020379EE2A01B94948 /* MCardPlugin */,
+ F5448E090379EE3601B94948 /* CACPlugin */,
+ F5448E100379EE6401B94948 /* CFlexPlugin */,
+ F538896903953B79012F6BBF /* InstallPhase */,
+ 2CBB605A06CA6944006AA7C8 /* GSCISPlugin */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 2CBB605606CA6944006AA7C8 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F52A93D602541D8C01B94B21 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F537A7CD0379ED7501B94948 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448DFE0379EE2A01B94948 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E050379EE3601B94948 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E0C0379EE6401B94948 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 2CBB605706CA6944006AA7C8 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2CBB606506CA69F9006AA7C8 /* GSCISPlugin.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F51121290272F895017BB957 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F511212D0272F8D9017BB957 /* bundleTool.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5294A820090C73501CD285A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F52A94520254232701B94B21 /* atrhandler.c in Sources */,
+ 52C3C14D0BA5D54100436862 /* readerstate.cpp in Sources */,
+ F52A94BF0254242101B94B21 /* configfile.c in Sources */,
+ F52A94C00254242101B94B21 /* debuglog.c in Sources */,
+ F52A94C10254242101B94B21 /* dyn_macosx.c in Sources */,
+ F52A94C20254242101B94B21 /* eventhandler.cpp in Sources */,
+ F52A94C40254242101B94B21 /* ifdwrapper.c in Sources */,
+ F52A94C50254242101B94B21 /* pcscdaemon.c in Sources */,
+ F52A94C60254242101B94B21 /* prothandler.c in Sources */,
+ F52A94C70254242101B94B21 /* readerfactory.c in Sources */,
+ F52A94C90254242101B94B21 /* thread_macosx.c in Sources */,
+ F52A94CA0254242101B94B21 /* winscard_msg.cpp in Sources */,
+ F52A94CB0254242101B94B21 /* winscard_svc.c in Sources */,
+ F555DF360274962801D2E99F /* powermgt_macosx.c in Sources */,
+ C2F2094B0662B851001DFD06 /* sys_macosx.cpp in Sources */,
+ 528629490A87EA8E004FE8DC /* hotplug_macosx.cpp in Sources */,
+ 5286294A0A87EA8E004FE8DC /* PCSCDevice.cpp in Sources */,
+ 5286294C0A87EA8E004FE8DC /* PCSCDriverBundle.cpp in Sources */,
+ 5286294E0A87EA8E004FE8DC /* PCSCDriverBundles.cpp in Sources */,
+ 52D00D1D0A9252350093277A /* reader.cpp in Sources */,
+ 527CF60E0AA5192B007589FF /* pcscdmonitor.cpp in Sources */,
+ 527CF6100AA5192B007589FF /* pcscdserver.cpp in Sources */,
+ 52D2492D0BA07E1100F9827A /* winscard_msg_srv.c in Sources */,
+ 52E0D59E0BA7006D008DFDDF /* winscard.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5294AD60090CAE601CD285A /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F503CACF025425E601B94B21 /* testpcsc.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F52A93D702541D8C01B94B21 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 52C3C1480BA5D46900436862 /* readerstate.cpp in Sources */,
+ 52D58C560A8803A800DC3F19 /* thread_macosx.c in Sources */,
+ F52A94DE025424AC01B94B21 /* musclecard.c in Sources */,
+ F52A94DF025424AC01B94B21 /* dyn_macosx.c in Sources */,
+ F52A94E5025424F101B94B21 /* winscard_msg.cpp in Sources */,
+ F52A94E0025424AC01B94B21 /* tokenfactory.c in Sources */,
+ F52A94E7025424F101B94B21 /* sys_unix.c in Sources */,
+ F52A94E1025424AC01B94B21 /* tokenparser.c in Sources */,
+ F52A94E3025424AC01B94B21 /* debuglog.c in Sources */,
+ F52A94E4025424AC01B94B21 /* winscard_clnt.c in Sources */,
+ 52DBCAAF0BB851C8007D06A5 /* PCSC.exp in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F537A7CE0379ED7501B94948 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E410379EF2501B94948 /* p11_crypt.c in Sources */,
+ F5448E420379EF2501B94948 /* p11_digest.c in Sources */,
+ F5448E430379EF2501B94948 /* p11_dual.c in Sources */,
+ F5448E440379EF2501B94948 /* p11_ext.c in Sources */,
+ F5448E450379EF2501B94948 /* p11_general.c in Sources */,
+ F5448E460379EF2501B94948 /* p11_key.c in Sources */,
+ F5448E470379EF2501B94948 /* p11_object.c in Sources */,
+ F5448E480379EF2501B94948 /* p11_parallel.c in Sources */,
+ F5448E490379EF2501B94948 /* p11_random.c in Sources */,
+ F5448E4A0379EF2501B94948 /* p11_session.c in Sources */,
+ F5448E4B0379EF2501B94948 /* p11_sign.c in Sources */,
+ F5448E4C0379EF2501B94948 /* p11_token.c in Sources */,
+ F5448E4D0379EF2501B94948 /* p11_verify.c in Sources */,
+ F5448E4E0379EF2501B94948 /* p11x_async.c in Sources */,
+ F5448E4F0379EF2501B94948 /* p11x_bio.c in Sources */,
+ F5448E500379EF2501B94948 /* p11x_error.c in Sources */,
+ F5448E510379EF2501B94948 /* p11x_log.c in Sources */,
+ F5448E520379EF2501B94948 /* p11x_msc.c in Sources */,
+ F5448E540379EF2501B94948 /* p11x_object.c in Sources */,
+ F5448E550379EF2501B94948 /* p11x_prefs.c in Sources */,
+ F5448E560379EF2501B94948 /* p11x_session.c in Sources */,
+ F5448E570379EF2501B94948 /* p11x_slot.c in Sources */,
+ F5448E580379EF2501B94948 /* p11x_state.c in Sources */,
+ F5448E590379EF2501B94948 /* p11x_thread.c in Sources */,
+ F5448E5B0379EF2501B94948 /* p11x_util.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448DFF0379EE2A01B94948 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E140379EEA101B94948 /* musclecardApplet.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E060379EE3601B94948 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E1C0379EEDD01B94948 /* commonAccessCard.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ F5448E0D0379EE6401B94948 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ F5448E180379EEC301B94948 /* cryptoflex.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 2CBB607506CA6DDE006AA7C8 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 2CBB605A06CA6944006AA7C8 /* GSCISPlugin */;
+ targetProxy = 2CBB607406CA6DDE006AA7C8 /* PBXContainerItemProxy */;
+ };
+ F511213B0272FA1C017BB957 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F51121270272F895017BB957 /* pcsctool */;
+ targetProxy = 4CFE9C0C059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F520A5F60257B49C01D97E8A /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F52A93D402541D8C01B94B21 /* PCSC */;
+ targetProxy = 4CFE9C0E059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F520E3A001F6204201B94B28 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F5294A800090C73501CD285A /* pcscd */;
+ targetProxy = 4CFE9C06059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F520E3A301F6204201B94B28 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F5294AD40090CAE601CD285A /* pcsctest */;
+ targetProxy = 4CFE9C0D059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F5448E810379FE0101B94948 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F537A7D10379ED7501B94948 /* PKCS11 */;
+ targetProxy = 4CFE9C0B059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F5448E820379FE0501B94948 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F5448E020379EE2A01B94948 /* MCardPlugin */;
+ targetProxy = 4CFE9C05059254C8007119DE /* PBXContainerItemProxy */;
+ };
+ F5448E830379FE0801B94948 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F5448E090379EE3601B94948 /* CACPlugin */;
+ targetProxy = 4CFE9C0A059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F5448E840379FE0C01B94948 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F5448E100379EE6401B94948 /* CFlexPlugin */;
+ targetProxy = 4CFE9C07059254C9007119DE /* PBXContainerItemProxy */;
+ };
+ F54DC28B0397F35F01115D8D /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = F538896903953B79012F6BBF /* InstallPhase */;
+ targetProxy = 4CFE9C09059254C9007119DE /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXToolTarget section */
+ F51121270272F895017BB957 /* pcsctool */ = {
+ isa = PBXToolTarget;
+ buildConfigurationList = C27AD1D00987FCDC001272E0 /* Build configuration list for PBXToolTarget "pcsctool" */;
+ buildPhases = (
+ F51121280272F895017BB957 /* Headers */,
+ F51121290272F895017BB957 /* Sources */,
+ F511212A0272F895017BB957 /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = pcsctool;
+ productInstallPath = /usr/bin/;
+ productName = pcsctool;
+ productReference = F51121260272F895017BB957 /* pcsctool */;
+ };
+ F5294A800090C73501CD285A /* pcscd */ = {
+ isa = PBXToolTarget;
+ buildConfigurationList = C27AD1C60987FCDB001272E0 /* Build configuration list for PBXToolTarget "pcscd" */;
+ buildPhases = (
+ F5294A810090C73501CD285A /* Headers */,
+ F5294A820090C73501CD285A /* Sources */,
+ F5294A830090C73501CD285A /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = pcscd;
+ productInstallPath = /usr/sbin;
+ productName = pcscd;
+ productReference = F5294A7E0090C73501CD285A /* pcscd */;
+ };
+ F5294AD40090CAE601CD285A /* pcsctest */ = {
+ isa = PBXToolTarget;
+ buildConfigurationList = C27AD1CB0987FCDB001272E0 /* Build configuration list for PBXToolTarget "pcsctest" */;
+ buildPhases = (
+ F5294AD50090CAE601CD285A /* Headers */,
+ F5294AD60090CAE601CD285A /* Sources */,
+ F5294AD70090CAE601CD285A /* Frameworks */,
+ );
+ dependencies = (
+ );
+ name = pcsctest;
+ productInstallPath = /usr/bin;
+ productName = testpcsc;
+ productReference = F5294AD30090CAE601CD285A /* pcsctest */;
+ };
+/* End PBXToolTarget section */
+
+/* Begin XCBuildConfiguration section */
+ C27AD1C20987FCDB001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 34733;
+ EXPORTED_SYMBOLS_FILE = "\"$(SRCROOT)/src/PCSC/PCSC.exp\"";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ FRAMEWORK_VERSION = A;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+ OPTIMIZATION_CFLAGS = "-O0";
+ OPT_CFLAGS = "-DNDEBUG -Os $(OPT_INLINEFLAGS)";
+ OPT_CPPFLAGS = "$(OPT_CFLAGS)";
+ OPT_INLINEFLAGS = "-finline-functions";
+ OPT_LDFLAGS = "-dead_strip";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OPT_CFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CFLAGS_profile = "$(OPT_CFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_normal = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS) -pg";
+ PRODUCT_NAME = PCSC;
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = framework;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1C30987FCDB001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = (
+ normal,
+ debug,
+ );
+ CURRENT_PROJECT_VERSION = 34733;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 34733;
+ EXPORTED_SYMBOLS_FILE = "\"$(SRCROOT)/src/PCSC/PCSC.exp\"";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ FRAMEWORK_VERSION = A;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+ OPT_CFLAGS = "-DNDEBUG -Os $(OPT_INLINEFLAGS)";
+ OPT_CPPFLAGS = "$(OPT_CFLAGS)";
+ OPT_INLINEFLAGS = "-finline-functions";
+ OPT_LDFLAGS = "-dead_strip";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OPT_CFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CFLAGS_profile = "$(OPT_CFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_normal = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS) -pg";
+ PRODUCT_NAME = PCSC;
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = framework;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1C40987FCDB001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 34733;
+ EXPORTED_SYMBOLS_FILE = "\"$(SRCROOT)/src/PCSC/PCSC.exp\"";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ FRAMEWORK_VERSION = A;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+ OPT_CFLAGS = "-DNDEBUG -Os $(OPT_INLINEFLAGS)";
+ OPT_CPPFLAGS = "$(OPT_CFLAGS)";
+ OPT_INLINEFLAGS = "-finline-functions";
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CFLAGS_profile = "$(OPT_CFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_normal = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS) -pg";
+ PREBINDING = NO;
+ PRODUCT_NAME = PCSC;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = framework;
+ };
+ name = "normal with debug";
+ };
+ C27AD1C50987FCDB001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = (
+ normal,
+ debug,
+ );
+ CURRENT_PROJECT_VERSION = 34733;
+ DYLIB_COMPATIBILITY_VERSION = 1;
+ DYLIB_CURRENT_VERSION = 34733;
+ EXPORTED_SYMBOLS_FILE = "\"$(SRCROOT)/src/PCSC/PCSC.exp\"";
+ FRAMEWORK_SEARCH_PATHS = (
+ "$(inherited)",
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ FRAMEWORK_VERSION = A;
+ INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Frameworks";
+ OPT_CFLAGS = "-DNDEBUG -Os $(OPT_INLINEFLAGS)";
+ OPT_CPPFLAGS = "$(OPT_CFLAGS)";
+ OPT_INLINEFLAGS = "-finline-functions";
+ OPT_LDFLAGS = "-dead_strip";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OPT_CFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CFLAGS_profile = "$(OPT_CFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_normal = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS) -pg";
+ PRODUCT_NAME = PCSC;
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = framework;
+ };
+ name = Default;
+ };
+ C27AD1C70987FCDB001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = (
+ "${BUILT_PRODUCTS_DIR}",
+ /usr/local/SecurityPieces/Components/Security,
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/CoreFoundation.framework/Headers,
+ /System/Library/Frameworks/IOKit.framework/Headers/usb,
+ /System/Library/Frameworks/IOKit.framework/Headers,
+ );
+ INSTALL_PATH = /usr/sbin;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+ OPT_CXFLAGS = "-DNDEBUG -Os $(OPT_INLINEXFLAGS)";
+ OPT_INLINEXFLAGS = "-finline-functions";
+ OPT_LDXFLAGS = "-dead_strip";
+ OPT_LDXNOPIC = ",_nopic";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS) -framework Security,_debug -framework securityd_client,_debug -framework security_cdsa_client,_debug -framework security_cdsa_utilities,_debug -framework security_utilities,_debug";
+ OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -framework Security -framework securityd_client$(OPT_LDXNOPIC) -framework security_cdsa_client$(OPT_LDXNOPIC) -framework security_cdsa_utilities$(OPT_LDXNOPIC) -framework security_utilities$(OPT_LDXNOPIC)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg -framework Security,_profile -framework securityd_client,_profile -framework security_cdsa_client,_profile -framework security_cdsa_utilities,_profile -framework security_utilities,_profile";
+ PRODUCT_NAME = pcscd;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1C80987FCDB001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = (
+ normal,
+ debug,
+ );
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = (
+ "${BUILT_PRODUCTS_DIR}",
+ /usr/local/SecurityPieces/Components/Security,
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/CoreFoundation.framework/Headers,
+ /System/Library/Frameworks/IOKit.framework/Headers/usb,
+ /System/Library/Frameworks/IOKit.framework/Headers,
+ );
+ INSTALL_PATH = /usr/sbin;
+ OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+ OPT_CXFLAGS = "-DNDEBUG -Os $(OPT_INLINEXFLAGS)";
+ OPT_INLINEXFLAGS = "-finline-functions";
+ OPT_LDXFLAGS = "-dead_strip";
+ OPT_LDXNOPIC = ",_nopic";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS) -framework Security,_debug -framework securityd_client,_debug -framework security_cdsa_client,_debug -framework security_cdsa_utilities,_debug -framework security_utilities,_debug";
+ OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -framework Security -framework securityd_client$(OPT_LDXNOPIC) -framework security_cdsa_client$(OPT_LDXNOPIC) -framework security_cdsa_utilities$(OPT_LDXNOPIC) -framework security_utilities$(OPT_LDXNOPIC)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg -framework Security,_profile -framework securityd_client,_profile -framework security_cdsa_client,_profile -framework security_cdsa_utilities,_profile -framework security_utilities,_profile";
+ PRODUCT_NAME = pcscd;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1C90987FCDB001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = (
+ "${BUILT_PRODUCTS_DIR}",
+ /usr/local/SecurityPieces/Components/Security,
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/CoreFoundation.framework/Headers,
+ /System/Library/Frameworks/IOKit.framework/Headers/usb,
+ /System/Library/Frameworks/IOKit.framework/Headers,
+ );
+ INSTALL_PATH = /usr/sbin;
+ OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+ OPT_CXFLAGS = "-DNDEBUG -Os $(OPT_INLINEXFLAGS)";
+ OPT_INLINEXFLAGS = "-finline-functions";
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS) -framework Security,_debug -framework securityd_client,_debug -framework security_cdsa_client,_debug -framework security_cdsa_utilities,_debug -framework security_utilities,_debug";
+ OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -framework Security -framework securityd_client$(OPT_LDXNOPIC) -framework security_cdsa_client$(OPT_LDXNOPIC) -framework security_cdsa_utilities$(OPT_LDXNOPIC) -framework security_utilities$(OPT_LDXNOPIC)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg -framework Security,_profile -framework securityd_client,_profile -framework security_cdsa_client,_profile -framework security_cdsa_utilities,_profile -framework security_utilities,_profile";
+ PREBINDING = NO;
+ PRODUCT_NAME = pcscd;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = "normal with debug";
+ };
+ C27AD1CA0987FCDB001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = (
+ normal,
+ debug,
+ );
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = (
+ "${BUILT_PRODUCTS_DIR}",
+ /usr/local/SecurityPieces/Components/Security,
+ /usr/local/SecurityPieces/Frameworks,
+ );
+ HEADER_SEARCH_PATHS = (
+ /System/Library/Frameworks/CoreFoundation.framework/Headers,
+ /System/Library/Frameworks/IOKit.framework/Headers/usb,
+ /System/Library/Frameworks/IOKit.framework/Headers,
+ );
+ INSTALL_PATH = /usr/sbin;
+ OPT_CPPXFLAGS = "$(OPT_CXFLAGS)";
+ OPT_CXFLAGS = "-DNDEBUG -Os $(OPT_INLINEXFLAGS)";
+ OPT_INLINEXFLAGS = "-finline-functions";
+ OPT_LDXFLAGS = "-dead_strip";
+ OPT_LDXNOPIC = ",_nopic";
+ OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_normal = "-DNDEBUG $(OTHER_CFLAGS)";
+ OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
+ OTHER_CFLAGS = (
+ "-DPCSC_DEBUG=1",
+ "-DUSE_SYSLOG=1",
+ "-DUSE_DAEMON=1",
+ );
+ OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
+ OTHER_CFLAGS_normal = "$(OPT_CXFLAGS) $(OTHER_CFLAGS)";
+ OTHER_CFLAGS_profile = "$(OPT_CXFLAGS) $(OTHER_CFLAGS) -pg";
+ OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CPLUSPLUSFLAGS) -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS)";
+ OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPXFLAGS) $(OTHER_CPLUSPLUSFLAGS) -pg";
+ OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS) -framework Security,_debug -framework securityd_client,_debug -framework security_cdsa_client,_debug -framework security_cdsa_utilities,_debug -framework security_utilities,_debug";
+ OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -framework Security -framework securityd_client$(OPT_LDXNOPIC) -framework security_cdsa_client$(OPT_LDXNOPIC) -framework security_cdsa_utilities$(OPT_LDXNOPIC) -framework security_utilities$(OPT_LDXNOPIC)";
+ OTHER_LDFLAGS_profile = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -pg -framework Security,_profile -framework securityd_client,_profile -framework security_cdsa_client,_profile -framework security_cdsa_utilities,_profile -framework security_utilities,_profile";
+ PRODUCT_NAME = pcscd;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Default;
+ };
+ C27AD1CC0987FCDB001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/bin;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pcsctest;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1CD0987FCDB001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/bin;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pcsctest;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1CE0987FCDB001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ INSTALL_PATH = /usr/bin;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = pcsctest;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = "normal with debug";
+ };
+ C27AD1CF0987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ INSTALL_PATH = /usr/bin;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pcsctest;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Default;
+ };
+ C27AD1D10987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/bin;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pcsctool;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1D20987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/bin;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pcsctool;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1D30987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ INSTALL_PATH = /usr/bin;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = pcsctool;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = "normal with debug";
+ };
+ C27AD1D40987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ FRAMEWORK_SEARCH_PATHS = "";
+ INSTALL_PATH = /usr/bin;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pcsctool;
+ REZ_EXECUTABLE = YES;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Default;
+ };
+ C27AD1D60987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/pkcs11;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "-lcrypto";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pkcs11;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1D70987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/pkcs11;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "-lcrypto";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pkcs11;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1D80987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/pkcs11;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "-lcrypto";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = pkcs11;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = "normal with debug";
+ };
+ C27AD1D90987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/pkcs11;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "-lcrypto";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = pkcs11;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Default;
+ };
+ C27AD1DB0987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = mscMuscleCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1DC0987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = mscMuscleCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1DD0987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = mscMuscleCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = "normal with debug";
+ };
+ C27AD1DE0987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = mscMuscleCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Default;
+ };
+ C27AD1E00987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ PRODUCT_NAME = GSCISPlugin;
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1E10987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ PRODUCT_NAME = GSCISPlugin;
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1E20987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ PREBINDING = NO;
+ PRODUCT_NAME = GSCISPlugin;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = "normal with debug";
+ };
+ C27AD1E30987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ PRODUCT_NAME = GSCISPlugin;
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Default;
+ };
+ C27AD1E50987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = commonAccessCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1E60987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = commonAccessCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1E70987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = commonAccessCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = "normal with debug";
+ };
+ C27AD1E80987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = commonAccessCard;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Default;
+ };
+ C27AD1EA0987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = slbCryptoflex;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1EB0987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = slbCryptoflex;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1EC0987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = slbCryptoflex;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = "normal with debug";
+ };
+ C27AD1ED0987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CURRENT_PROJECT_VERSION = 34733;
+ INSTALL_PATH = /usr/libexec/SmartCardServices/services;
+ OTHER_CFLAGS = "-DMSC_TARGET_OSX=1";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = slbCryptoflex;
+ SECTORDER_FLAGS = "";
+ VERSIONING_SYSTEM = "apple-generic";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ WRAPPER_EXTENSION = bundle;
+ };
+ name = Default;
+ };
+ C27AD1EF0987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ OPTIMIZATION_CFLAGS = "-O0";
+ PRODUCT_NAME = InstallPhase;
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1F00987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ PRODUCT_NAME = InstallPhase;
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1F10987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ PREBINDING = NO;
+ PRODUCT_NAME = InstallPhase;
+ SECTORDER_FLAGS = "";
+ };
+ name = "normal with debug";
+ };
+ C27AD1F20987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = InstallPhase;
+ };
+ name = Default;
+ };
+ C27AD1F90987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = debug;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_ENABLE_FIX_AND_CONTINUE = YES;
+ GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ OPTIMIZATION_CFLAGS = "-O0";
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = World;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = YES;
+ };
+ name = Development;
+ };
+ C27AD1FA0987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ GCC_ENABLE_FIX_AND_CONTINUE = NO;
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = World;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ ZERO_LINK = NO;
+ };
+ name = Deployment;
+ };
+ C27AD1FB0987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ BUILD_VARIANTS = normal;
+ OPT_LDFLAGS = "";
+ OPT_LDXFLAGS = "";
+ OPT_LDXNOPIC = "";
+ OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG";
+ OTHER_CFLAGS = "";
+ OTHER_CFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_CPLUSPLUSFLAGS_normal = "$(OTHER_CFLAGS) -UNDEBUG -O0 -fno-inline";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PREBINDING = NO;
+ PRODUCT_NAME = World;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = "normal with debug";
+ };
+ C27AD1FC0987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ OTHER_CFLAGS = "";
+ OTHER_LDFLAGS = "";
+ OTHER_REZFLAGS = "";
+ PRODUCT_NAME = World;
+ SECTORDER_FLAGS = "";
+ WARNING_CFLAGS = (
+ "-Wmost",
+ "-Wno-four-char-constants",
+ "-Wno-unknown-pragmas",
+ );
+ };
+ name = Default;
+ };
+ C27AD1FE0987FCDC001272E0 /* Development */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+ CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+ };
+ name = Development;
+ };
+ C27AD1FF0987FCDC001272E0 /* Deployment */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+ CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+ };
+ name = Deployment;
+ };
+ C27AD2000987FCDC001272E0 /* normal with debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+ CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+ };
+ name = "normal with debug";
+ };
+ C27AD2010987FCDC001272E0 /* Default */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+ CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
+ };
+ name = Default;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ C27AD1C10987FCDB001272E0 /* Build configuration list for PBXFrameworkTarget "PCSC" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1C20987FCDB001272E0 /* Development */,
+ C27AD1C30987FCDB001272E0 /* Deployment */,
+ C27AD1C40987FCDB001272E0 /* normal with debug */,
+ C27AD1C50987FCDB001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1C60987FCDB001272E0 /* Build configuration list for PBXToolTarget "pcscd" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1C70987FCDB001272E0 /* Development */,
+ C27AD1C80987FCDB001272E0 /* Deployment */,
+ C27AD1C90987FCDB001272E0 /* normal with debug */,
+ C27AD1CA0987FCDB001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1CB0987FCDB001272E0 /* Build configuration list for PBXToolTarget "pcsctest" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1CC0987FCDB001272E0 /* Development */,
+ C27AD1CD0987FCDB001272E0 /* Deployment */,
+ C27AD1CE0987FCDB001272E0 /* normal with debug */,
+ C27AD1CF0987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1D00987FCDC001272E0 /* Build configuration list for PBXToolTarget "pcsctool" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1D10987FCDC001272E0 /* Development */,
+ C27AD1D20987FCDC001272E0 /* Deployment */,
+ C27AD1D30987FCDC001272E0 /* normal with debug */,
+ C27AD1D40987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1D50987FCDC001272E0 /* Build configuration list for PBXBundleTarget "PKCS11" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1D60987FCDC001272E0 /* Development */,
+ C27AD1D70987FCDC001272E0 /* Deployment */,
+ C27AD1D80987FCDC001272E0 /* normal with debug */,
+ C27AD1D90987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1DA0987FCDC001272E0 /* Build configuration list for PBXBundleTarget "MCardPlugin" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1DB0987FCDC001272E0 /* Development */,
+ C27AD1DC0987FCDC001272E0 /* Deployment */,
+ C27AD1DD0987FCDC001272E0 /* normal with debug */,
+ C27AD1DE0987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1DF0987FCDC001272E0 /* Build configuration list for PBXBundleTarget "GSCISPlugin" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1E00987FCDC001272E0 /* Development */,
+ C27AD1E10987FCDC001272E0 /* Deployment */,
+ C27AD1E20987FCDC001272E0 /* normal with debug */,
+ C27AD1E30987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1E40987FCDC001272E0 /* Build configuration list for PBXBundleTarget "CACPlugin" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1E50987FCDC001272E0 /* Development */,
+ C27AD1E60987FCDC001272E0 /* Deployment */,
+ C27AD1E70987FCDC001272E0 /* normal with debug */,
+ C27AD1E80987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1E90987FCDC001272E0 /* Build configuration list for PBXBundleTarget "CFlexPlugin" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1EA0987FCDC001272E0 /* Development */,
+ C27AD1EB0987FCDC001272E0 /* Deployment */,
+ C27AD1EC0987FCDC001272E0 /* normal with debug */,
+ C27AD1ED0987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1EE0987FCDC001272E0 /* Build configuration list for PBXLegacyTarget "InstallPhase" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1EF0987FCDC001272E0 /* Development */,
+ C27AD1F00987FCDC001272E0 /* Deployment */,
+ C27AD1F10987FCDC001272E0 /* normal with debug */,
+ C27AD1F20987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1F80987FCDC001272E0 /* Build configuration list for PBXAggregateTarget "World" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1F90987FCDC001272E0 /* Development */,
+ C27AD1FA0987FCDC001272E0 /* Deployment */,
+ C27AD1FB0987FCDC001272E0 /* normal with debug */,
+ C27AD1FC0987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+ C27AD1FD0987FCDC001272E0 /* Build configuration list for PBXProject "SmartCardServices" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C27AD1FE0987FCDC001272E0 /* Development */,
+ C27AD1FF0987FCDC001272E0 /* Deployment */,
+ C27AD2000987FCDC001272E0 /* normal with debug */,
+ C27AD2010987FCDC001272E0 /* Default */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Default;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = F5294A4F0090C4CA01CD285A /* Project object */;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>CM4040</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.omnikey.cm4040.driver</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>cm4040</string>
+ <key>CFBundlePackageType</key>
+ <string>KEXT</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.2</string>
+ <key>IOKitPersonalities</key>
+ <dict>
+ <key>OKCM4040UC</key>
+ <dict>
+ <key>CFBundleIdentifier</key>
+ <string>com.omnikey.cm4040.driver</string>
+ <key>IOClass</key>
+ <string>com_omnikey_cm4040_driver</string>
+ <key>IOProviderClass</key>
+ <string>IOPCCard16Device</string>
+ <key>IOResourceMatch</key>
+ <string>IOKit</string>
+ <key>IOUserClientClass</key>
+ <string>com_omnikey_cm4040_UserClient</string>
+ <key>VersionOneInfo</key>
+ <array>
+ <string>OMNIKEY</string>
+ <string>CardMan 4040</string>
+ </array>
+ </dict>
+ </dict>
+ <key>OSBundleLibraries</key>
+ <dict>
+ <key>com.apple.iokit.IOPCCardFamily</key>
+ <string>1.1.0</string>
+ <key>com.apple.kernel.iokit</key>
+ <string>1.1</string>
+ <key>com.apple.kernel.libkern</key>
+ <string>1.1</string>
+ <key>com.apple.kernel.mach</key>
+ <string>1.1</string>
+ </dict>
+</dict>
+</plist>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/MacOS/CM4040
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CM4040.kext/Contents/MacOS/CM4040
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>CRYPTOCardPCCard</string>
+ <key>CFBundleGetInfoString</key>
+ <string>PC Card Smart Card Reader Driver</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.CRYPTOCard.iokit.SmartCardReader</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>CRYPTOCardPCCard</string>
+ <key>CFBundlePackageType</key>
+ <string>KEXT</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0.1</string>
+ <key>CFBundleSignature</key>
+ <string>CCrd</string>
+ <key>CFBundleVersion</key>
+ <string>1.0.0d2</string>
+ <key>IOKitPersonalities</key>
+ <dict>
+ <key>CRYPTOCardPCCard</key>
+ <dict>
+ <key>CFBundleIdentifier</key>
+ <string>com.CRYPTOCard.iokit.SmartCardReader</string>
+ <key>IOClass</key>
+ <string>com_CRYPTOCard_iokit_SmartCardReader</string>
+ <key>IOKitDebug</key>
+ <integer>65535</integer>
+ <key>IONameMatch</key>
+ <string>pccard2bd,1003</string>
+ <key>IOProbeScore</key>
+ <integer>10000</integer>
+ <key>IOProviderClass</key>
+ <string>IOPCCard16Device</string>
+ <key>IOUserClientClass</key>
+ <string>com_CRYPTOCard_iokit_UserClient</string>
+ <key>VersionOneInfo</key>
+ <array>
+ <string>CRYPTOCard</string>
+ <string>Smart Card Reader Model P1</string>
+ </array>
+ </dict>
+ </dict>
+ <key>OSBundleLibraries</key>
+ <dict>
+ <key>com.apple.iokit.IOPCCardFamily</key>
+ <string>1.1.0</string>
+ </dict>
+</dict>
+</plist>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/MacOS/CRYPTOCardPCCard
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/MacOS/CRYPTOCardPCCard
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Resources/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/CRYPTOCardPCCard.kext/Contents/Resources/English.lproj/InfoPlist.strings
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>SCR24X_Apple_Driver</string>
+ <key>CFBundleGetInfoString</key>
+ <string>2.1.0</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.scm.driver.scr24x</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>SCR24X PCMCIA Smart Card Reader</string>
+ <key>CFBundlePackageType</key>
+ <string>KEXT</string>
+ <key>CFBundleShortVersionString</key>
+ <string>2.1.0</string>
+ <key>CFBundleVersion</key>
+ <string>2.1.0</string>
+ <key>IOKitPersonalities</key>
+ <dict>
+ <key>HP</key>
+ <dict>
+ <key>CFBundleIdentifier</key>
+ <string>com.scm.driver.scr24x</string>
+ <key>IOClass</key>
+ <string>com_scm_driver_scr24x</string>
+ <key>IOKitDebug</key>
+ <integer>65535</integer>
+ <key>IOProbeScore</key>
+ <integer>10000</integer>
+ <key>IOProviderClass</key>
+ <string>IOPCCard16Device</string>
+ <key>IOUserClientClass</key>
+ <string>com_scm_driver_scr24xUserClient</string>
+ <key>VersionOneInfo</key>
+ <array>
+ <string>HP</string>
+ <string>PC Card Smart Card Reader</string>
+ </array>
+ </dict>
+ <key>SCR241</key>
+ <dict>
+ <key>CFBundleIdentifier</key>
+ <string>com.scm.driver.scr24x</string>
+ <key>IOClass</key>
+ <string>com_scm_driver_scr24x</string>
+ <key>IOKitDebug</key>
+ <integer>65535</integer>
+ <key>IOProbeScore</key>
+ <integer>10000</integer>
+ <key>IOProviderClass</key>
+ <string>IOPCCard16Device</string>
+ <key>IOUserClientClass</key>
+ <string>com_scm_driver_scr24xUserClient</string>
+ <key>VersionOneInfo</key>
+ <array>
+ <string>SCR241 PCMCIA</string>
+ <string>Smart Card Reader</string>
+ </array>
+ </dict>
+ <key>SCR243</key>
+ <dict>
+ <key>CFBundleIdentifier</key>
+ <string>com.scm.driver.scr24x</string>
+ <key>IOClass</key>
+ <string>com_scm_driver_scr24x</string>
+ <key>IOKitDebug</key>
+ <integer>65535</integer>
+ <key>IOProbeScore</key>
+ <integer>10000</integer>
+ <key>IOProviderClass</key>
+ <string>IOPCCard16Device</string>
+ <key>IOUserClientClass</key>
+ <string>com_scm_driver_scr24xUserClient</string>
+ <key>VersionOneInfo</key>
+ <array>
+ <string>SCR243 PCMCIA</string>
+ <string>Smart Card Reader</string>
+ </array>
+ </dict>
+ <key>SCR24x</key>
+ <dict>
+ <key>CFBundleIdentifier</key>
+ <string>com.scm.driver.scr24x</string>
+ <key>IOClass</key>
+ <string>com_scm_driver_scr24x</string>
+ <key>IOKitDebug</key>
+ <integer>65535</integer>
+ <key>IOProbeScore</key>
+ <integer>10000</integer>
+ <key>IOProviderClass</key>
+ <string>IOPCCard16Device</string>
+ <key>IOUserClientClass</key>
+ <string>com_scm_driver_scr24xUserClient</string>
+ <key>VersionOneInfo</key>
+ <array>
+ <string>SCR24x PCMCIA</string>
+ <string>Smart Card Reader</string>
+ </array>
+ </dict>
+ </dict>
+ <key>Java</key>
+ <dict>
+ <key>Properties</key>
+ <dict/>
+ </dict>
+ <key>OSBundleLibraries</key>
+ <dict>
+ <key>com.apple.iokit.IOPCCardFamily</key>
+ <string>1.1.0</string>
+ </dict>
+</dict>
+</plist>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/MacOS/SCR24X_Apple_Driver
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/MacOS/SCR24X_Apple_Driver
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Resources/English.lproj/InfoPlist.strings
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/Extensions/SCR24X_Apple_Driver.kext/Contents/Resources/English.lproj/InfoPlist.strings
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/PKCS11/pkcs11.shlb
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/PKCS11/pkcs11.shlb
___________________________________________________________________
Added: svn:executable
+
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>CC-PC-Card</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>0.0.1d1</string>
+ <key>ifdFriendlyName</key>
+ <string>CRYPTOCard</string>
+ <key>ifdProductID</key>
+ <string>1003</string>
+ <key>ifdVendorID</key>
+ <string>2BD</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.CRYPTOCard.SmartcardReader</string>
+ <key>CFBundleName</key>
+ <string>CRYPTOCardSmartcardDriver</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0.1</string>
+</dict>
+</plist>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/MacOS/CC-PC-Card
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/CC-PC-Card.bundle/Contents/MacOS/CC-PC-Card
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>SCR24XHndlr</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.scm.bundle.scr24xhndlr</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>0.9.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>0.9.0</string>
+ <key>ifdFriendlyName</key>
+ <string>SCR24X</string>
+ <key>ifdProductID</key>
+ <string>0xffff</string>
+ <key>ifdVendorID</key>
+ <string>0x04e6</string>
+</dict>
+</plist>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/MacOS/SCR24XHndlr
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/SCR24XHndlr.bundle/Contents/MacOS/SCR24XHndlr
___________________________________________________________________
Added: svn:executable
+
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>ifd-ASEIIIeUSB</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.athena.AseIIIeUSB</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>CFPlugInFactories</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <string>MyFactoryFunction</string>
+ </dict>
+ <key>CFPlugInTypes</key>
+ <dict>
+ <key>00000000-0000-0000-0000-000000000000</key>
+ <array>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </array>
+ </dict>
+ <key>CFPlugInUnloadFunction</key>
+ <string></string>
+ <key>NSPrincipalClass</key>
+ <string>0x60000</string>
+ <key>ifdCapabilities</key>
+ <string>0x00000000</string>
+ <key>ifdFriendlyName</key>
+ <string>AseIIIeUSB</string>
+ <key>ifdManufacturerString</key>
+ <string>Athena</string>
+ <key>ifdManufacturerURL</key>
+ <string>http://www.athena-scs.com/</string>
+ <key>ifdMaxSpeed</key>
+ <string>153600</string>
+ <key>ifdProductID</key>
+ <string>0x0802</string>
+ <key>ifdProductString</key>
+ <string>AseIIIeUSB</string>
+ <key>ifdProtocolSupport</key>
+ <string>0x00000001</string>
+ <key>ifdReadTimeOut</key>
+ <string>60000</string>
+ <key>ifdVendorID</key>
+ <string>0x0DC3</string>
+ <key>ifdVersionNumber</key>
+ <string>0x00000001</string>
+</dict>
+</plist>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/MacOS/ifd-ASEIIIeUSB
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifd-ASEIIIeUSB.bundle/Contents/MacOS/ifd-ASEIIIeUSB
___________________________________________________________________
Added: svn:executable
+
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/Info.plist
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/Info.plist (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/Info.plist 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>ifdok_cm4040_macos-2.0.0.dylib</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>BNDL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0.0d2</string>
+ <key>CSResourcesFileMapped</key>
+ <true/>
+ <key>ManufacturerString</key>
+ <string>Omnikey AG</string>
+ <key>ManufacturerURL</key>
+ <string>http://www.omnikey.com/</string>
+ <key>ifdCapabilities</key>
+ <string>0x00000000</string>
+ <key>ifdFriendlyName</key>
+ <string>OMNIKEY CardMan 4040</string>
+ <key>ifdMaxSpeed</key>
+ <string>115200</string>
+ <key>ifdProductID</key>
+ <string>0x0200</string>
+ <key>ifdProductString</key>
+ <string>OMNIKEY CardMan 4040</string>
+ <key>ifdProtocolSupport</key>
+ <string>0x00000011</string>
+ <key>ifdVendorID</key>
+ <string>0x0223</string>
+</dict>
+</plist>
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/Info.plist
___________________________________________________________________
Added: svn:executable
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/MacOS/ifdok_cm4040_macos-2.0.0.dylib
===================================================================
(Binary files differ)
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/drivers/ifdok_cm4040_macos-2.0.0.bundle/Contents/MacOS/ifdok_cm4040_macos-2.0.0.dylib
___________________________________________________________________
Added: svn:executable
+
Added: svn:mime-type
+ application/octet-stream
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcscd.8
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcscd.8 (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcscd.8 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,149 @@
+.\" Process this file with
+.\" groff -man -Tascii pcscd.txt
+.\"
+.TH PCSCD 8 "March 2002" Linux "User Manual"
+.SH NAME
+pcscd \- PC/SC Smartcard Daemon
+.SH SYNOPSIS
+.BI "pcscd [" options "]"
+.SH OPTIONS
+.TP
+\fB\-a\fR, \fB\-\-apdu\fR
+log APDUs and SW using the debug method (see \fB\-d\fR)
+.TP
+\fB\-c\fR, \fB\-\-config\fR \fIfile\fR
+Specifies the file \fIfile\fR as an alternate location for
+\fIreader.conf\fR
+.TP
+\fB\-d\fR, \fB\-\-debug\fR \fIOUTPUT\fR
+display debug messages.
+
+\fIOUTPUT\fR may be:
+ \fBstdout\fR (imply \fB\-f\fR),
+ \fBstderr\fR (imply \fB\-f\fR),
+ or \fBsyslog\fR
+.TP
+\fB\-f\fR, \fB\-\-foreground\fR
+Runs pcscd in the foreground (no daemon)
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Displays information about the pcscd command line
+.TP
+\fB\-v\fR, \fB\-\-version\fR
+Displays the program version number
+.SH DESCRIPTION
+pcscd is the daemon program for pcsc-lite and musclecard framework. It is
+a resource manager that coordinates communications with smart-card readers
+and smart cards and cryptographic tokens that are connected to the system.
+
+pcscd is normally started at boot time from
+.IR /System/Library/StartupItems/SmartCardServices .
+It allows applications to access smart cards and readers without knowing
+details of the card or reader.
+
+pcscd coordinates the loading of drivers for card readers and plug-ins
+for different card types.
+
+The purpose of pcsc-lite is to provide both a cross compatible API for
+migrating Windows based PCSC applications to Unix and to provide a
+pluggable architecture for supporting smartcards and cryptographic tokens
+through high level API's.
+
+At startup, pcscd loads the smart card reader drivers specified in the
+.I /etc/reader.conf
+file (or specified using \fB-c\fR \fIfile\fR).
+
+When a smart card is inserted into a reader, pcscd uses the ATR string from
+the card to identify this card. The
+.I /usr/libexec/SmartCardServices/services
+directory contains plug-ins for the card. These plug-ins are searched. If
+the ATR string matches, the client library loads that plug-in for that
+token.
+
+.SH "USB SMART CARD READER DRIVERS"
+USB Smart card reader drivers are placed in the
+.I /usr/libexec/SmartCardServices/drivers
+directory. Each driver is simply a
+bundle. The bundle contains an XML file Info.plist
+which is parsed by pcscd. This file contains the vendor
+and product id of the device. This information allows
+pcscd to automatically determine when a reader is inserted
+or removed.
+
+.SH "SERIAL SMART CARD READER DRIVERS"
+Serial Smart card reader drivers are placed in the
+.I /usr/libexec/SmartCardServices/drivers
+directory. Each driver is simply a
+.I shared object
+file. The pcscd locates serial drivers with the
+.I /etc/reader.conf
+file. The file has the following format:
+
+ # comment
+ FRIENDLYNAME <Descriptive name>
+ DEVICENAME <Short name>
+ LIBPATH <Location of the driver library>
+ CHANNELID <Hexadecimal channel identificator>
+
+.IP FRIENDLYNAME
+is a user-friendly name of the reader that is served by this driver.
+This name is displayed to the user when necessary.
+
+.IP DEVICENAME
+is a driver specific value. If you do not know this value,
+GEN_SMART_RDR is a good choice.
+
+.IP LIBPATH
+is the full path to the shared library.
+
+.IP CHANNELID
+is the channel ID for serial-port, smart-card readers. This could vary
+depending on the driver in which you are using - check the driver README
+for more information. Some use the following:
+
+ \fI/dev/ttyS0\fR (COM1) -> 0x0103F8 or 1
+ \fI/dev/ttyS1\fR (COM2) -> 0x0102F8 or 2
+ \fI/dev/ttyS2\fR (COM3) -> 0x0103E8 or 3
+ \fI/dev/ttyS3\fR (COM4) -> 0x0102E8 or 4
+.PP
+Example:
+
+ # Configuration file for pcsc-lite
+
+ FRIENDLYNAME "My Smartcard Reader"
+ DEVICENAME GEN_SMART_RDR
+ LIBPATH /usr/libexec/SmartCardServices/drivers/my_reader.so
+ CHANNELID 0x0103F8
+
+ # End of file
+
+Multiple drivers can be listed in
+.I /etc/reader.conf.
+
+Drivers are available at \fIhttp://www.musclecard.com/drivers.html\fR.
+.SH "SMART CARD PLUG-INS"
+pcsc-lite uses plug-ins to handle different types of smart cards. There is
+a plug-in for each smart-card type. Plug-ins are installed in the
+.I /usr/libexec/SmartCardServices/services
+directory. Plug-ins for cards/tokens are available from the MUSCLE
+web site \fIhttp://www.musclecard.com\fR.
+.SH FILES
+.I /etc/reader.conf
+: Reader configuration file
+.br
+.I /System/Library/StartupItems/SmartCardServices
+: pcscd startup script
+.br
+.I /var/run/pcscd.pid
+: process id of the running pcscd
+.br
+.I /usr/libexec/SmartCardServices/drivers/
+: directory containing bundles for USB
+drivers"
+.SH BUGS
+None known.
+.SH "SEE ALSO"
+.BR pcsctool (1),
+.SH AUTHORS
+David Corcoran <corcoran at identityalliance.com> and Ludovic Rousseau
+<ludovic.rousseau at free.fr>
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctest.8
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctest.8 (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctest.8 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,57 @@
+.\" Process this file with
+.\" groff -man -Tascii pcsctool.8
+.\"
+.TH PCSCTEST 8 "March 2003" MacOSX "User Manual"
+.SH NAME
+pcsctest
+.SH SYNOPSIS
+.B pcsctest
+.SH DESCRPTION
+pcsctest runs a test on pcscd, lists the readers currently connected, and
+displays card information if a card is inserted.
+.SH OPTIONS
+None
+.SH USAGE
+pcsctest lists the currently connected readers and asks the user
+to choose one. After choosing the reader, pcsctest will ask the
+user to insert a card into the card reader. If this happens pcsctest
+will display the cards's ATR and other information.
+
+Example:
+
+The following will occur if no reader is inserted and recognized:
+
+MUSCLE PC/SC Lite Test Program
+
+ Testing SCardEstablishContext : Command successful.
+ Testing SCardGetStatusChange
+
+Once a reader is inserted and recognized the following will occur:
+
+ MUSCLE PC/SC Lite Test Program
+
+ Testing SCardEstablishContext : Command successful.
+ Testing SCardGetStatusChange
+ Please insert a working reader : Command successful.
+ Testing SCardListReaders : Command successful.
+ Reader 01: SCM SCR-331 CCID 0 0
+ Enter the reader number : 1
+
+ Waiting for card insertion
+ : Command successful.
+ Testing SCardConnect : Command successful.
+ Testing SCardStatus : Command successful.
+ Current Reader Name : CCID USB Reader 0 0
+ Current Reader State : 34
+ Current Reader Protocol : 0
+ Current Reader ATR Size : 9
+ Current Reader ATR Value : 3B E2 00 00 04 03 00
+ Testing SCardDisconnect : Command successful.
+ Testing SCardReleaseContext : Command successful.
+
+ PC/SC Test Completed Successfully !
+
+
+.SH SEE ALSO
+.BR pcscd (8)
+.SH BUGS
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctool.8
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctool.8 (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/pcsctool.8 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,37 @@
+.\" Process this file with
+.\" groff -man -Tascii pcsctool.8
+.\"
+.TH PCSCTOOL 8 "March 2002" Linux "User Manual"
+.SH NAME
+pcsctool
+.SH SYNOPSIS
+.B pcsctool
+.SH DESCRPTION
+pcsctool introduces new smart cards to pcsc-lite and assigns a
+plugin to service the card.
+.SH OPTIONS
+None
+.SH USAGE
+pcsctool lists the currently installed bundles and asks you to
+select one. You select the plugin bundle that services your
+smartcard. pcsctool will then ask you to insert the new card. The
+application exits and pcsc is now configured to use your card.
+
+Example:
+
+ [root at osx]# pcsctool
+ Select the approprate token driver:
+ -----------------------------------
+ 1. mscMuscleCard.bundle
+ -----------------------------------
+ Enter the number: 1
+
+ Insert your token in: My Friendly Reader 0 0
+
+ Token support updated successfully !
+ [root at osx]#
+.SH SEE ALSO
+.BR pcscd (8)
+.SH BUGS
+Plugins MUST reside in
+.I /usr/libexec/SmartCardServices/services
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/sc_auth.8
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/sc_auth.8 (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/man/sc_auth.8 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,91 @@
+.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples.
+.\"See Also:
+.\"man mdoc.samples for a complete listing of options
+.\"man mdoc for the short list of editing options
+.\"/usr/share/misc/mdoc.template
+.Dd December 11, 2006 \" DATE
+.Dt sc_auth 8 \" Program name and manual section number
+.Os MacOSX
+.Sh NAME \" Section Header - required - don't modify
+.Nm sc_auth
+.\" The following lines are read in generating the apropos(man -k) database. Use only key
+.\" words here as the database is built based on the words here and in the .ND line.
+.\" Use .Nm macro to designate other names for the documented program.
+.Nd smart card authorization setup script
+.Sh SYNOPSIS \" Section Header - required - don't modify
+.Nm
+.Ar accept
+.Op Fl v
+.Op Fl u Ar user
+.Op Fl d Ar domain
+.Op Fl k Ar keyname
+.Nm
+.Ar accept
+.Op Fl v
+.Op Fl u Ar user
+.Op Fl d Ar domain
+.Fl h Ar hash
+.Nm
+.Ar remove
+.Op Fl v
+.Op Fl u Ar user
+.Op Fl d Ar domain
+.Nm
+.Ar hash " "
+.Op Fl k Ar keyname
+.Nm
+.Ar list " "
+.Op Fl v
+.Op Fl u Ar user
+.Op Fl d Ar domain
+.Sh DESCRIPTION \" Section Header - required - don't modify
+.Nm
+configures a local user account to permit authentication using a supported
+smart card. Authentication is via asymmetric key (also known as
+public-key) encryption.
+.Nm
+works with signing keys, but not encryption keys.
+.Pp
+.Nm
+can perform the following actions:
+.Bl -tag -width -indent \" Begins a tagged list
+.It Ar accept
+Associate a user with a public key on a card. The key to use can be
+specified either by its name or its hash.
+.It Ar remove
+Remove all public keys associated with a user.
+.It Ar hash
+Print the hashes for all keys on all inserted cards.
+.It Ar list
+List all public keys associated with a user.
+.El \" Ends the list
+.Pp
+.Sh OPTIONS
+.Bl -tag -width -indent \" Differs from above in tag removed
+.It Fl u Ar user
+Specifies the user whose account is to be modified
+.It Fl d Ar domain
+Specifies the directory domain containing the user account
+.It Fl k Ar keyname
+Specifies a public key by its name
+.It Fl h Ar hash
+Specifies a public key by its hash
+.It Fl v
+Verbose mode
+.El \" Ends the list
+.Sh NOTES
+.Nm
+is a shell script. It is intended to be modified by administrators to
+suit their local environments.
+.Pp
+.Nm
+is only known to work with a local directory. Consult the script's source
+for some limited guidance to using remote directories.
+.Sh BUGS
+.Nm
+.Ar hash
+might display the hashes of encryption keys as well as signing keys, even
+though
+.Nm
+.Ar accept
+does not work with encryption keys.
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/scripts/sc_auth
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/scripts/sc_auth (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/scripts/sc_auth 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,148 @@
+#!/bin/bash
+#
+# sc_auth - smart card authorization setup script
+#
+# You can log in with a smart card if the authentication_authority field
+# of your user record contains an entry of the form
+# ;pubkeyhash;THEHASH
+# where THEHASH is the hex encoding of the SHA1 of the public key to be used.
+# (In keychains, this is the value in the Label attribute of keys, and of
+# the PublicKeyHash # attribute of certificate records.)
+#
+# This script allows you to get the hash from a smartcard, and to create
+# the appropriate authority entry in a user account. It also lets you list
+# and delete them. It works as is for (local) NetInfo directories. If you
+# use LDAP or more exotic directory sources, you'll have to find your own
+# way to store the authentication_authority information, but the workflow
+# is the same. Feel free to hack.
+#
+# This script assumes the Tiger version of the /usr/bin/security command.
+# It will probably not work (without modification) with future versions.
+#
+# This script has been updated to use the dscl command in place of the
+# deprecated nicl command. To use the standard name in the header file:
+# /System/Library/Frameworks/DirectoryService.framework/Headers/DirServicesConst.h
+# we have replaced "authentication_authority" with "AuthenticationAuthority"
+
+#set -x
+
+# general functions
+die() { echo "$*" 1>&2; exit 1; }
+note() { [ $verbose = yes ] && echo "$*" 1>&2; }
+
+usage() {
+cat <<EOU
+Usage: $(basename $0) accept [-v] [-u user] [-d domain] [-k keyname] # by key on inserted card(s)
+ $(basename $0) accept [-v] [-u user] [-d domain] -h hash # by known pubkey hash
+ $(basename $0) remove [-v] [-u user] [-d domain] # remove all public keys for this user
+ $(basename $0) hash [-k keyname] # print hashes for keys on inserted card(s)
+ $(basename $0) list [-v] [-u user] [-d domain] # list pubkey hashes that can authenticate this user
+EOU
+exit 2
+}
+
+# first argument is a command word
+[ -n "$1" ] || usage
+command=$1; shift
+
+# parse options
+user=${USER:-$(logname)}
+keyname=
+hash=
+verbose=no
+domain="."
+while getopts d:h:k:u:v arg; do
+ case $arg in
+ d) domain="$OPTARG";;
+ h) hash="$OPTARG";;
+ k) keyname="$OPTARG";;
+ u) user="$OPTARG";;
+ v) verbose=yes;;
+ esac
+done
+shift $(($OPTIND - 1))
+
+
+#
+# Using "security dump-keychain", extract the public key hash for a key
+# on a smartcard and print it to stdout.
+# The optional argument is a regular expression to match against the
+# print name of the key.
+# Prints all matching keys; aborts if none are found.
+#
+hash_for_key() {
+ # hash_for_key [string in name]
+ string=${1:-'.*'}
+ HOME=/no/where /usr/bin/security dump-keychain |
+ awk -v RE="$string" '
+ /^ 0x00000001/ {
+ if (matched = ($2 ~ RE)) { name=$0; sub("^.*<blob>=\"", "", name); sub("\"$", "", name); count++; }}
+ /^ 0x00000006/ {
+ if (matched) { hash=$2; sub("<blob>=0x", "", hash); print hash, name; }}
+ '
+ HOME=/no/where /usr/bin/security dump-keychain |
+ awk -v RE="$string" '
+ /^ 0x01000000/ {
+ if (matched = ($2 ~ RE)) { name=$0; sub("^.*<blob>=\"", "", name); sub("\"$", "", name); count++; }}
+ /^ 0x06000000/ {
+ if (matched) { hash=$2; sub("<blob>=0x", "", hash); print hash, name; }}
+ '
+}
+
+
+get_hash() {
+ if [ -n "$hash" ]; then # passed in
+ echo "$hash"
+ else # find it
+ hash_for_key "$keyname" |
+ (
+ read hash rest
+ [ -n "$hash" ] || die "No matching keys found"
+ [ $verbose = yes ] && note "Using key \"$rest\""
+ echo $hash
+ )
+ fi
+}
+
+
+accept_user() {
+ local hash="$1"
+ [ -n "$hash" ] || die "No hash specified"
+ dscl "$domain" -append "/Users/$user" AuthenticationAuthority ";pubkeyhash;$hash"
+}
+
+remove_user() {
+ set -- $(dscl "$domain" -read "/Users/$user" AuthenticationAuthority)
+ shift # skip authentication_authority: header
+ while [ -n "$1" ]; do
+ case "$1" in
+ \;pubkeyhash\;*)
+ dscl "$domain" -delete "/Users/$user" AuthenticationAuthority "$1"
+ [ $verbose = yes ] && note "Removed $1"
+ ;;
+ esac
+ shift
+ done
+}
+
+list_hashes() {
+ set -- $(dscl "$domain" -read "/Users/$user" AuthenticationAuthority)
+ shift # skip authentication_authority: header
+ while [ -n "$1" ]; do
+ case "$1" in
+ \;pubkeyhash\;*)
+ echo $1 | sed -e 's/;pubkeyhash;//'
+ ;;
+ esac
+ shift
+ done
+}
+
+
+case "$command" in
+ hash) hash_for_key "$keyname";;
+ accept) accept_user $(get_hash);;
+ remove) remove_user;;
+ list) list_hashes;;
+ *) usage;;
+esac
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/installPhase/scripts/sc_auth
___________________________________________________________________
Added: svn:executable
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/pbx/config.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/pbx/config.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/pbx/config.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,36 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if you have the daemon function. */
+#define HAVE_DAEMON 1
+
+/* Name of package */
+#define PACKAGE "PCSC Framework"
+
+/* Version number of package */
+#define VERSION "1.1.1"
+
+/* OSX */
+#define PCSC_TARGET_OSX 1
+#define MSC_TARGET_OSX 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* enable full PCSC debug messaging. */
+ #define PCSC_DEBUG 1
+
+/* enable full musclecard debug messaging. */
+ #define MSC_DEBUG 1
+
+/* display ATR parsing debug messages. */
+/* #define ATR_DEBUG */
+
+/* send messages to syslog instead of stdout */
+/* #define USE_SYSLOG */
+
+/* pcsc runs as a daemon in the background. */
+#define USE_DAEMON 1
+
+/* enable client side thread safety. */
+#define USE_THREAD_SAFETY 1
+
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/pbx/config.h
___________________________________________________________________
Added: svn:executable
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,2057 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ Title : commonAccessCard.c
+ Package: CAC Plugin
+ Author : David Corcoran
+ Date : 02/06/02
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+
+ Purpose: This abstracts the CAC APDU's
+ into client side function calls.
+
+********************************************************************/
+
+#ifdef WIN32
+#include "../win32/CACPlugin.h"
+#endif
+
+#ifndef __APPLE__
+#include <musclecard.h>
+#else
+#include <PCSC/musclecard.h>
+#endif
+#include "commonAccessCard.h"
+#include <zlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/* Define to turn on APDU debugging */
+/* #define MSC_DEBUG 1 */
+
+static int suppressResponse = 0;
+static int tlvsCached = 0;
+
+static MSCUShort16 pntbSize = 0;
+static MSCUShort16 pnvbSize = 0;
+static MSCUShort16 pltbSize = 0;
+static MSCUShort16 plvbSize = 0;
+static MSCUShort16 bstbSize = 0;
+static MSCUShort16 bsvbSize = 0;
+static MSCUShort16 obtbSize = 0;
+static MSCUShort16 obvbSize = 0;
+
+typedef struct {
+ MSCUChar8 pBuffer[MAX_BUFFER_SIZE];
+ MSCULong32 bufferSize;
+ MSCUChar8 apduResponse[MAX_BUFFER_SIZE];
+ MSCULong32 apduResponseSize;
+ LPSCARD_IO_REQUEST ioType;
+} MSCTransmitBuffer, *MSCLPTransmitBuffer;
+
+MSC_RV convertPCSC( MSCLong32 );
+MSCUShort16 convertSW( MSCPUChar8 );
+void MemCopy16( MSCPUChar8, MSCPUShort16 );
+void MemCopy32( MSCPUChar8, MSCPULong32 );
+void MemCopyTo16( MSCPUShort16, MSCPUChar8 );
+void MemCopyTo32( MSCPULong32, MSCPUChar8 );
+MSCUShort16 getUShort16( MSCPUChar8 );
+void setUShort16( MSCPUChar8, MSCUShort16 );
+
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection pConnection,
+ MSCLPTransmitBuffer transmitBuffer );
+
+#define CAC_IDCERT_OBJID "C7"
+#define CAC_ECRYCERT_OBJID "C3"
+#define CAC_ESIGCERT_OBJID "C5"
+#define CAC_IDCERTATT_OBJID "c7"
+#define CAC_ECRYCERTATT_OBJID "c3"
+#define CAC_ESIGCERTATT_OBJID "c5"
+#define CAC_IDKEYATT_OBJID "k7"
+#define CAC_ECRYKEYATT_OBJID "k3"
+#define CAC_ESIGKEYATT_OBJID "k5"
+
+#define CAC_PNTB_OBJID "PNTB"
+#define CAC_PNVB_OBJID "PNVB"
+
+#define CAC_PLTB_OBJID "PLTB"
+#define CAC_PLVB_OBJID "PLVB"
+
+#define CAC_BSTB_OBJID "BSTB"
+#define CAC_BSVB_OBJID "BSVB"
+
+#define CAC_OBTB_OBJID "OBTB"
+#define CAC_OBVB_OBJID "OBVB"
+
+#define CAC_LABEL_ID "Identification"
+#define CAC_LABEL_ESIG "Email Certificate"
+#define CAC_LABEL_ECRY "Email Certificate"
+#define CAC_MAXSIZE_CERT 4000
+#define CAC_MAXSIZE_SIGNDATA 0x80
+#define CAC_KEYNUM_ID 7
+#define CAC_KEYNUM_ESIG 5
+#define CAC_KEYNUM_ECRY 3
+
+
+/* ID Applet */
+MSCUChar8 CAC_APPLET_ID_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00};
+/* PKI ID Instance */
+MSCUChar8 CAC_APPLET_PKI_ID_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00};
+/* PKI Email Signature Instance */
+MSCUChar8 CAC_APPLET_PKI_ESIG_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x01};
+/* PKI Email Encryption Instance */
+MSCUChar8 CAC_APPLET_PKI_ECRY_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x02};
+MSCUChar8 CAC_APPLET_CONT_PN_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00};
+MSCUChar8 CAC_APPLET_CONT_PL_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x01};
+MSCUChar8 CAC_APPLET_CONT_BS_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x02};
+MSCUChar8 CAC_APPLET_CONT_OB_AID[7] =
+{0xA0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x03};
+
+static MSCULong32 cacIDCertAttrSize = 48;
+static MSCULong32 cacECryptCertAttrSize = 45;
+static MSCULong32 cacESignCertAttrSize = 45;
+static MSCULong32 cacIDKeyAttrSize = 245;
+static MSCULong32 cacECryptKeyAttrSize = 245;
+static MSCULong32 cacESignKeyAttrSize = 245;
+
+static MSCUChar8 cacIDCertAttr[48] = {
+ 0x00, 0x63, 0x37, 0x00, 0x00, 0x00, 0x29,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x08,
+ 'I', 'd', 'e', 'n', 't', 'i', 't', 'y',
+ 0x00, 0x00, 0x01, 0x02, 0x00, 0x01,
+ CAC_KEYNUM_ID
+};
+
+static MSCUChar8 cacESignCertAttr[45] = {
+ 0x00, 0x63, 0x35, 0x00, 0x00, 0x00, 0x26,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x05,
+ 'E', 'm', 'a', 'i', 'l',
+ 0x00, 0x00, 0x01, 0x02, 0x00, 0x01,
+ CAC_KEYNUM_ESIG
+};
+
+static MSCUChar8 cacECryptCertAttr[45] = {
+ 0x00, 0x63, 0x33, 0x00, 0x00, 0x00, 0x26,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
+ 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x05,
+ 'E', 'm', 'a', 'i', 'l',
+ 0x00, 0x00, 0x01, 0x02, 0x00, 0x01,
+ CAC_KEYNUM_ECRY
+};
+
+
+static MSCUChar8 cacIDKeyAttr[245] = {
+ 0x00, /* Object type */
+ 0x6B, 0x37, /* Object id */
+ 0x00, 0x00, /* Next id */
+ 0x00, 0xEE, /* Data len */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* CKA_CLASS */
+ 0x03, 0x00, 0x00, 0x00, /* Value */
+
+ 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, /* CKA_ID */
+ CAC_KEYNUM_ID, /* Value */
+
+ 0x00, 0x00, 0x01, 0x62, 0x00, 0x01, /* CKA_EXTRACTABLE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x09, 0x00, 0x01, /* CKA_SIGN_RECOVER */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x0C, 0x00, 0x01, /* CKA_DERIVE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x70, 0x00, 0x01, /* CKA_MODIFIABLE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x07, 0x00, 0x01, /* CKA_UNWRAP */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x05, 0x00, 0x01, /* CKA_DECRYPT */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, /* CKA_PRIVATE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x08, 0x00, 0x01, /* CKA_SIGN */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x64, 0x00, 0x01, /* CKA_NEVER_EXTRACTABLE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x65, 0x00, 0x01, /* CKA_ALWAYS_SENSITIVE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x03, 0x00, 0x01, /* CKA_SENSITIVE */
+ 0x01,
+
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, /* CKA_KEY_TYPE */
+ 0x00, 0x00, 0x00, 0x00, /* Value */
+
+ 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, /* CKA_MODULUS */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+
+};
+
+static MSCUChar8 cacECryptKeyAttr[245] = {
+ 0x00, /* Object type */
+ 0x6B, 0x33, /* Object id */
+ 0x00, 0x00, /* Next id */
+ 0x00, 0xEE, /* Data len */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* CKA_CLASS */
+ 0x03, 0x00, 0x00, 0x00, /* Value */
+
+ 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, /* CKA_ID */
+ CAC_KEYNUM_ECRY, /* Value */
+
+ 0x00, 0x00, 0x01, 0x62, 0x00, 0x01, /* CKA_EXTRACTABLE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x09, 0x00, 0x01, /* CKA_SIGN_RECOVER */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x0C, 0x00, 0x01, /* CKA_DERIVE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x70, 0x00, 0x01, /* CKA_MODIFIABLE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x07, 0x00, 0x01, /* CKA_UNWRAP */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x05, 0x00, 0x01, /* CKA_DECRYPT */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, /* CKA_PRIVATE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x08, 0x00, 0x01, /* CKA_SIGN */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x64, 0x00, 0x01, /* CKA_NEVER_EXTRACTABLE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x65, 0x00, 0x01, /* CKA_ALWAYS_SENSITIVE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x03, 0x00, 0x01, /* CKA_SENSITIVE */
+ 0x01,
+
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, /* CKA_KEY_TYPE */
+ 0x00, 0x00, 0x00, 0x00, /* Value */
+
+ 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, /* CKA_MODULUS */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static MSCUChar8 cacESignKeyAttr[245] = {
+ 0x00, /* Object type */
+ 0x6B, 0x35, /* Object id */
+ 0x00, 0x00, /* Next id */
+ 0x00, 0xEE, /* Data len */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* CKA_CLASS */
+ 0x03, 0x00, 0x00, 0x00, /* Value */
+
+ 0x00, 0x00, 0x01, 0x02, 0x00, 0x01, /* CKA_ID */
+ CAC_KEYNUM_ESIG, /* Value */
+
+ 0x00, 0x00, 0x01, 0x62, 0x00, 0x01, /* CKA_EXTRACTABLE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x09, 0x00, 0x01, /* CKA_SIGN_RECOVER */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x0C, 0x00, 0x01, /* CKA_DERIVE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x70, 0x00, 0x01, /* CKA_MODIFIABLE */
+ 0x00, /* Value */
+ 0x00, 0x00, 0x01, 0x07, 0x00, 0x01, /* CKA_UNWRAP */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x05, 0x00, 0x01, /* CKA_DECRYPT */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, /* CKA_PRIVATE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x08, 0x00, 0x01, /* CKA_SIGN */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x64, 0x00, 0x01, /* CKA_NEVER_EXTRACTABLE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x65, 0x00, 0x01, /* CKA_ALWAYS_SENSITIVE */
+ 0x01, /* Value */
+ 0x00, 0x00, 0x01, 0x03, 0x00, 0x01, /* CKA_SENSITIVE */
+ 0x01,
+
+ 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, /* CKA_KEY_TYPE */
+ 0x00, 0x00, 0x00, 0x00, /* Value */
+
+ 0x00, 0x00, 0x01, 0x20, 0x00, 0x80, /* CKA_MODULUS */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+static MSCUChar8 cacIDCert[CAC_MAXSIZE_CERT];
+static MSCUChar8 cacESignCert[CAC_MAXSIZE_CERT];
+static MSCUChar8 cacECryptCert[CAC_MAXSIZE_CERT];
+static MSCUChar8 cacCompBuffer[CAC_MAXSIZE_CERT];
+static MSCUShort16 cacIDCertSize = 0;
+static MSCUShort16 cacESignCertSize = 0;
+static MSCUShort16 cacECryptCertSize = 0;
+static MSCUChar8 dataIsCached = 0;
+
+
+MSC_RV CACLoadAndCacheData(MSCLPTokenConnection pConnection);
+
+MSC_RV CACLoadTLVSize(MSCLPTokenConnection pConnection,
+ MSCPUChar8 demoPointer,
+ MSCULong32 demoSize,
+ MSCPUShort16 tlvSize,
+ MSCUChar8 tlvType);
+
+MSC_RV CACLoadCertificate(MSCLPTokenConnection pConnection, MSCPUChar8 cert,
+ MSCPUShort16 certSize);
+
+MSC_RV CACSelectInstance(MSCLPTokenConnection pConnection, MSCPUChar8 aid,
+ MSCULong32 aidLength);
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteFramework( MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCGetStatus( MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo ) {
+
+ pStatusInfo->appVersion = 0xFF;
+ pStatusInfo->swVersion = 0xFF;
+ pStatusInfo->freeMemory = 0x00;
+ pStatusInfo->totalMemory = 0x00;
+ pStatusInfo->usedPINs = 1;
+ pStatusInfo->usedKeys = 3;
+ pStatusInfo->loggedID = pConnection->loggedIDs;;
+
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCGetCapabilities( MSCLPTokenConnection pConnection, MSCULong32 Tag,
+ MSCPUChar8 Value, MSCPULong32 Length ) {
+
+ MSCULong32 ulValue;
+ MSCUShort16 usValue;
+ MSCUChar8 ucValue;
+ MSCUChar8 tagType;
+
+ /* 4 - MSCULong32, 2 - MSCUShort16, 1 - MSCUChar8 */
+
+ ulValue = 0; usValue = 0; ucValue = 0; tagType = 0;
+
+ switch(Tag) {
+
+ case MSC_TAG_SUPPORT_FUNCTIONS:
+ ulValue = MSC_SUPPORT_COMPUTECRYPT | MSC_SUPPORT_LISTKEYS |
+ MSC_SUPPORT_VERIFYPIN | MSC_SUPPORT_LISTPINS | MSC_SUPPORT_READOBJECT |
+ MSC_SUPPORT_LISTOBJECTS | MSC_SUPPORT_GETCHALLENGE |
+ MSC_SUPPORT_CHANGEPIN;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_SUPPORT_CRYPTOALG:
+ ulValue = MSC_SUPPORT_RSA;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_RSA:
+ ulValue = MSC_CAPABLE_RSA_1024 | MSC_CAPABLE_RSA_NOPAD;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_ATTR:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_IDSIZE:
+ ucValue = 16;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_AUTH:
+ usValue = MSC_AUT_NONE;
+ tagType = 2;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_MAXNUM:
+ ulValue = 17;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_ATTR:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MAXNUM:
+ ucValue = 1;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MINSIZE:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MAXSIZE:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_CHARSET:
+ ulValue = MSC_CAPABLE_PIN_A_Z | MSC_CAPABLE_PIN_a_z |
+ MSC_CAPABLE_PIN_0_9 | MSC_CAPABLE_PIN_CALC | MSC_CAPABLE_PIN_NONALPHA;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_POLICY:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_ID_STATE:
+ ucValue = 0;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_RANDOM_MAX:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_RANDOM_MIN:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_KEY_AUTH:
+ usValue = MSC_AUT_NONE;
+ tagType = 2;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_AUTH:
+ usValue = MSC_AUT_NONE;
+ tagType = 2;
+ break;
+
+ default:
+ return MSC_INVALID_PARAMETER;
+ }
+
+ switch(tagType) {
+ case 1:
+ memcpy(Value, &ucValue, 1);
+ break;
+ case 2:
+ memcpy(Value, &usValue, 2);
+ break;
+ case 4:
+ memcpy(Value, &ulValue, 4);
+ break;
+ }
+
+ *Length = tagType;
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCExtendedFeature( MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature,
+ MSCPUChar8 outData, MSCULong32 outLength,
+ MSCPUChar8 inData, MSCPULong32 inLength ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCGenerateKeys( MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum, MSCUChar8 pubKeyNum,
+ MSCLPGenKeyParams pParams ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCImportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL, MSCPUChar8 pKeyBlob,
+ MSCULong32 keyBlobSize, MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCExportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCComputeCrypt( MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize ) {
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCPUChar8 pkiPointer;
+ MSCULong32 pkiSize;
+ MSCTransmitBuffer tBuffer;
+
+ rv = CACLoadAndCacheData(pConnection);
+ if (rv != MSC_SUCCESS) return rv;
+
+ if ( inputDataSize != CAC_MAXSIZE_SIGNDATA ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( cryptInit->cipherMode != MSC_MODE_RSA_NOPAD ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( cryptInit->cipherDirection != MSC_DIR_SIGN &&
+ cryptInit->cipherDirection != MSC_DIR_ENCRYPT &&
+ cryptInit->cipherDirection != MSC_DIR_DECRYPT) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ if ( cryptInit->keyNum == CAC_KEYNUM_ID ) {
+ if ( cacIDCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pkiPointer = CAC_APPLET_PKI_ID_AID;
+ pkiSize = sizeof(CAC_APPLET_PKI_ID_AID);
+
+ } else if ( cryptInit->keyNum == CAC_KEYNUM_ESIG ) {
+ if ( cacESignCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pkiPointer = CAC_APPLET_PKI_ESIG_AID;
+ pkiSize = sizeof(CAC_APPLET_PKI_ESIG_AID);
+
+ } else if ( cryptInit->keyNum == CAC_KEYNUM_ECRY ) {
+ if ( cacECryptCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pkiPointer = CAC_APPLET_PKI_ECRY_AID;
+ pkiSize = sizeof(CAC_APPLET_PKI_ECRY_AID);
+
+ } else {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ /* Select the instance associated with this key */
+ rv = CACSelectInstance( pConnection, pkiPointer, pkiSize );
+ if ( rv != MSC_SUCCESS )
+ return rv;
+
+ tBuffer.bufferSize = inputDataSize + 5;
+
+ /* Select AID */
+ txBuffer[0] = 0x80; txBuffer[1] = 0x42; txBuffer[2] = 0x00;
+ txBuffer[3] = 0x00; txBuffer[4] = inputDataSize;
+
+ memcpy(&txBuffer[5], pInputData, inputDataSize);
+
+ tBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( tBuffer.apduResponseSize != inputDataSize + 2 ) {
+ return MSC_UNSPECIFIED_ERROR;
+ } else if ( rxBuffer[tBuffer.apduResponseSize-2] != 0x90 ) {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+ memcpy(pOutputData, rxBuffer, inputDataSize);
+ *outputDataSize = inputDataSize;
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCExtAuthenticate( MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum, MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData, MSCULong32 dataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCListKeys( MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption, MSCLPKeyInfo pKeyInfo ) {
+
+ MSC_RV rv;
+ static int seq = 0;
+
+ rv = CACLoadAndCacheData(pConnection);
+ if (rv != MSC_SUCCESS) return rv;
+
+ if (seqOption == MSC_SEQUENCE_RESET) {
+ seq = 0;
+ }
+
+ switch(seq) {
+
+ case 0:
+ if ( cacECryptCertSize != 0 ) {
+ pKeyInfo->keySize = 1024;
+ pKeyInfo->keyNum = CAC_KEYNUM_ECRY;
+ pKeyInfo->keyType = MSC_KEY_RSA_PRIVATE;
+ break;
+ } else {
+ seq += 1;
+ }
+ case 1:
+ if ( cacESignCertSize != 0 ) {
+ pKeyInfo->keySize = 1024;
+ pKeyInfo->keyNum = CAC_KEYNUM_ESIG;
+ pKeyInfo->keyType = MSC_KEY_RSA_PRIVATE;
+ break;
+ } else {
+ seq += 1;
+ }
+ case 2:
+ if ( cacIDCertSize != 0 ) {
+ pKeyInfo->keySize = 1024;
+ pKeyInfo->keyNum = CAC_KEYNUM_ID;
+ pKeyInfo->keyType = MSC_KEY_RSA_PRIVATE;
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 3:
+ return MSC_SEQUENCE_END;
+
+ }
+
+ /* For keys, use only - pin verification needed, no write */
+ pKeyInfo->keyACL.readPermission = MSC_AUT_NONE;
+ pKeyInfo->keyACL.writePermission = MSC_AUT_NONE;
+ pKeyInfo->keyACL.usePermission = MSC_AUT_PIN_1;
+ pKeyInfo->keyPolicy.cipherMode = MSC_KEYPOLICY_MODE_RSA_NOPAD;
+ pKeyInfo->keyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_SIGN | MSC_KEYPOLICY_DIR_VERIFY |
+ MSC_KEYPOLICY_DIR_ENCRYPT | MSC_KEYPOLICY_DIR_DECRYPT;
+
+ seq += 1;
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCCreatePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts, MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCVerifyPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode, MSCULong32 pinCodeSize ) {
+
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCUChar8 pinPad[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ MSCTransmitBuffer tBuffer;
+
+ rv = CACLoadAndCacheData(pConnection);
+ if (rv != MSC_SUCCESS) return rv;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ txBuffer[OFFSET_CLA] = 0x80;
+ txBuffer[OFFSET_INS] = 0x20;
+ txBuffer[OFFSET_P1] = 0x00;
+ txBuffer[OFFSET_P2] = 0x00;
+ txBuffer[OFFSET_P3] = 0x08;
+
+ if ( pinNum != 1 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( pinCodeSize > 8 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ memcpy(pinPad, pPinCode, pinCodeSize);
+
+#ifdef CAC_PROTECTED_MODE
+ printf("Protected Mode: Injecting default pin\n");
+ memcpy(&txBuffer[OFFSET_DATA], "77777777", 8);
+ tBuffer.bufferSize = 8 + 5;
+#else
+ memcpy(&txBuffer[OFFSET_DATA], pinPad, 8);
+ tBuffer.bufferSize = 8 + 5;
+#endif
+
+ tBuffer.apduResponseSize = MAX_BUFFER_SIZE;
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if(tBuffer.apduResponseSize == 2) {
+ if (rxBuffer[0] == 0x90 && rxBuffer[1] == 0x00 ) {
+ pConnection->loggedIDs |= MSC_AUT_PIN_1;
+ return MSC_SUCCESS;
+ } else if ( rxBuffer[0] == 0x63 ) {
+ pConnection->loggedIDs = 0;
+ return MSC_AUTH_FAILED;
+ } else {
+ pConnection->loggedIDs = 0;
+ return convertSW(rxBuffer);
+ }
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCChangePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize ) {
+
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCUChar8 pinPad[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ MSCUChar8 newPinPad[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ MSCTransmitBuffer tBuffer;
+
+ /* Select the instance associated with this key */
+ rv = CACSelectInstance( pConnection, CAC_APPLET_ID_AID, 7 );
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ txBuffer[OFFSET_CLA] = 0x80;
+ txBuffer[OFFSET_INS] = 0x24;
+ txBuffer[OFFSET_P1] = 0x01;
+ txBuffer[OFFSET_P2] = 0x00;
+ txBuffer[OFFSET_P3] = 0x10;
+
+ if ( pinNum != 1 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( oldPinCodeSize > 8 || newPinCodeSize > 8 ||
+ oldPinCodeSize < 4 || newPinCodeSize < 4 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ memcpy(pinPad, pOldPinCode, oldPinCodeSize);
+ memcpy(newPinPad, pNewPinCode, newPinCodeSize);
+
+ memcpy(&txBuffer[OFFSET_DATA], pinPad, 8);
+ memcpy(&txBuffer[OFFSET_DATA+8], newPinPad, 8);
+
+ tBuffer.bufferSize = 16 + 5;
+ tBuffer.apduResponseSize = MAX_BUFFER_SIZE;
+
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if(tBuffer.apduResponseSize == 2) {
+ if (rxBuffer[0] == 0x90 && rxBuffer[1] == 0x00 ) {
+ return MSC_SUCCESS;
+ } else if ( rxBuffer[0] == 0x63 ) {
+ return MSC_AUTH_FAILED;
+ } else {
+ return convertSW(rxBuffer);
+ }
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCUnblockPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode,
+ MSCULong32 unblockCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCListPINs( MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask ) {
+
+
+ *pPinBitMask = 2; /* Just one pin on CAC */
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCCreateObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 objectSize,
+ MSCLPObjectACL pObjectACL ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCDeleteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCUChar8 zeroFlag ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offset,
+ MSCPUChar8 pInputData, MSCUChar8 dataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCReadObject( MSCLPTokenConnection pConnection, MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pOutputData,
+ MSCUChar8 dataSize ) {
+
+ MSCLong32 rv;
+ MSCPUChar8 demoPointer;
+ MSCULong32 demoSize;
+ MSCPUChar8 itemValue;
+ MSCULong32 itemSize;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCTransmitBuffer tBuffer;
+ MSCUChar8 readLocation;
+
+ demoSize = 0; demoPointer = 0;
+ itemValue = 0; itemSize = 0;
+ readLocation = 0;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ rv = CACLoadAndCacheData(pConnection);
+ if (rv != MSC_SUCCESS) return rv;
+
+ if ( strcmp(objectID, CAC_IDCERT_OBJID) == 0 ) {
+ if ( cacIDCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacIDCert;
+ itemSize = cacIDCertSize;
+
+ } else if ( strcmp(objectID, CAC_ECRYCERT_OBJID) == 0 ) {
+ if ( cacECryptCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacECryptCert;
+ itemSize = cacECryptCertSize;
+
+ } else if ( strcmp(objectID, CAC_ESIGCERT_OBJID) == 0 ) {
+ if ( cacESignCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacESignCert;
+ itemSize = cacESignCertSize;
+
+ } else if ( strcmp(objectID, CAC_IDCERTATT_OBJID) == 0 ) {
+ if ( cacIDCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacIDCertAttr;
+ itemSize = cacIDCertAttrSize;
+
+ } else if ( strcmp(objectID, CAC_ECRYCERTATT_OBJID) == 0 ) {
+ if ( cacECryptCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacECryptCertAttr;
+ itemSize = cacECryptCertAttrSize;
+
+ } else if ( strcmp(objectID, CAC_ESIGCERTATT_OBJID) == 0 ) {
+ if ( cacESignCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacESignCertAttr;
+ itemSize = cacESignCertAttrSize;
+
+ } else if ( strcmp(objectID, CAC_IDKEYATT_OBJID) == 0 ) {
+ if ( cacIDCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacIDKeyAttr;
+ itemSize = cacIDKeyAttrSize;
+
+ } else if ( strcmp(objectID, CAC_ECRYKEYATT_OBJID) == 0 ) {
+ if ( cacECryptCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacECryptKeyAttr;
+ itemSize = cacECryptKeyAttrSize;
+
+ } else if ( strcmp(objectID, CAC_ESIGKEYATT_OBJID) == 0 ) {
+ if ( cacESignCertSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ itemValue = cacESignKeyAttr;
+ itemSize = cacESignKeyAttrSize;
+
+ /* For the tags */
+ } else if ( strcmp(objectID, CAC_PNTB_OBJID) == 0 ) {
+ itemSize = pntbSize;
+ demoPointer = CAC_APPLET_CONT_PN_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PN_AID);
+ readLocation = 1; /* T-Buffer */
+ } else if ( strcmp(objectID, CAC_PLTB_OBJID) == 0 ) {
+ itemSize = pltbSize;
+ demoPointer = CAC_APPLET_CONT_PL_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PL_AID);
+ readLocation = 1; /* T-Buffer */
+ } else if ( strcmp(objectID, CAC_BSTB_OBJID) == 0 ) {
+ itemSize = bstbSize;
+ demoPointer = CAC_APPLET_CONT_BS_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_BS_AID);
+ readLocation = 1; /* T-Buffer */
+ } else if ( strcmp(objectID, CAC_OBTB_OBJID) == 0 ) {
+ itemSize = obtbSize;
+ demoPointer = CAC_APPLET_CONT_OB_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_OB_AID);
+ readLocation = 1; /* T-Buffer */
+
+ /* For the values */
+ } else if ( strcmp(objectID, CAC_PNVB_OBJID) == 0 ) {
+ itemSize = pnvbSize;
+ demoPointer = CAC_APPLET_CONT_PN_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PN_AID);
+ readLocation = 2; /* V-Buffer */
+ } else if ( strcmp(objectID, CAC_PLVB_OBJID) == 0 ) {
+ itemSize = plvbSize;
+ demoPointer = CAC_APPLET_CONT_PL_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PL_AID);
+ readLocation = 2; /* V-Buffer */
+ } else if ( strcmp(objectID, CAC_BSVB_OBJID) == 0 ) {
+ itemSize = bsvbSize;
+ demoPointer = CAC_APPLET_CONT_BS_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_BS_AID);
+ readLocation = 2; /* V-Buffer */
+ } else if ( strcmp(objectID, CAC_OBVB_OBJID) == 0 ) {
+ itemSize = obvbSize;
+ demoPointer = CAC_APPLET_CONT_OB_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_OB_AID);
+ readLocation = 2; /* V-Buffer */
+
+ } else {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ if (itemSize == 0) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( (dataSize + offset) > itemSize ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ /* Must be V-Data - this is not cached */
+ if ( readLocation == 1 || readLocation == 2 ) {
+ /* Select the correct applet */
+ rv = CACSelectInstance( pConnection, demoPointer, demoSize );
+ if ( rv != MSC_SUCCESS )
+ return rv;
+
+ txBuffer[OFFSET_CLA] = 0x80;
+ txBuffer[OFFSET_INS] = 0x52;
+ txBuffer[OFFSET_P1] = (offset/256);
+ txBuffer[OFFSET_P2] = (offset%256);
+ txBuffer[OFFSET_P3] = 0x02;
+ txBuffer[OFFSET_DATA] = readLocation;
+ txBuffer[OFFSET_DATA+1] = dataSize;
+
+ tBuffer.bufferSize = 7;
+ tBuffer.apduResponseSize = MAX_BUFFER_SIZE;
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if (tBuffer.apduResponseSize != (dataSize + 2)) {
+ return convertSW(rxBuffer);
+ } else {
+ itemValue = rxBuffer;
+ }
+ }
+
+ memcpy(pOutputData, &itemValue[offset], dataSize);
+ return MSC_SUCCESS;
+
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCListObjects( MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo ) {
+
+ static int seq = 0;
+ MSCULong32 rv;
+ MSCULong32 itemSize;
+
+ rv = CACLoadAndCacheData(pConnection);
+ if (rv != MSC_SUCCESS) {
+ return rv;
+ }
+
+ if ( seqOption == MSC_SEQUENCE_RESET ) {
+ seq = 0;
+ }
+
+ switch(seq) {
+
+ case 0:
+ /* Email Encryption Certificate */
+ itemSize = cacECryptCertSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_ECRYCERT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+ case 1:
+ /* Email Signature Certificate */
+ itemSize = cacESignCertSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_ESIGCERT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 2:
+ /* ID Certificate */
+ itemSize = cacIDCertSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_IDCERT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 3:
+ /* ID Certificate attributes */
+ itemSize = cacIDCertAttrSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_IDCERTATT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 4:
+ /* Email Encryption Certificate attributes */
+ itemSize = cacECryptCertAttrSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_ECRYCERTATT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 5:
+ /* Email Signature Certificate attributes */
+ itemSize = cacESignCertAttrSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_ESIGCERTATT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 6:
+ /* ID Key attributes */
+ itemSize = cacIDKeyAttrSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_IDKEYATT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 7:
+ /* Email Encryption Key attributes */
+ itemSize = cacECryptKeyAttrSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_ECRYKEYATT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 8:
+ /* Email Signature Key attributes */
+ itemSize = cacESignKeyAttrSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_ESIGKEYATT_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 9:
+ itemSize = pntbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_PNTB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 10:
+ itemSize = pnvbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_PNVB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 11:
+ itemSize = pltbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_PLTB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 12:
+ itemSize = plvbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_PLVB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 13:
+ itemSize = bstbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_BSTB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 14:
+ itemSize = bsvbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_BSVB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 15:
+ itemSize = obtbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_OBTB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ case 16:
+ itemSize = obvbSize;
+ if (itemSize != 0) {
+ strncpy(pObjectInfo->objectID, CAC_OBVB_OBJID, MSC_MAXSIZE_OBJID);
+ break;
+ } else {
+ seq += 1;
+ }
+
+ default:
+ return MSC_SEQUENCE_END;
+ }
+
+ /* Set the ACL */
+
+ switch(seq) {
+
+ case 0:
+ case 1:
+ case 2:
+ /* For all certificates */
+ pObjectInfo->objectACL.readPermission = MSC_AUT_ALL;
+ pObjectInfo->objectACL.writePermission = MSC_AUT_NONE;
+ pObjectInfo->objectACL.deletePermission = MSC_AUT_NONE;
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ /* For all certificate attributes */
+ pObjectInfo->objectACL.readPermission = MSC_AUT_ALL;
+ pObjectInfo->objectACL.writePermission = MSC_AUT_NONE;
+ pObjectInfo->objectACL.deletePermission = MSC_AUT_NONE;
+ break;
+
+ case 6:
+ case 7:
+ case 8:
+ /* For all key attributes */
+ pObjectInfo->objectACL.readPermission = MSC_AUT_ALL;
+ pObjectInfo->objectACL.writePermission = MSC_AUT_NONE;
+ pObjectInfo->objectACL.deletePermission = MSC_AUT_NONE;
+ break;
+
+ case 9:
+ case 11:
+ case 13:
+ case 15:
+ /* For all tag buffers */
+ pObjectInfo->objectACL.readPermission = MSC_AUT_ALL;
+ pObjectInfo->objectACL.writePermission = MSC_AUT_NONE;
+ pObjectInfo->objectACL.deletePermission = MSC_AUT_NONE;
+ break;
+
+ case 10:
+ case 12:
+ case 14:
+ case 16:
+ /* For all value buffers */
+ pObjectInfo->objectACL.readPermission = MSC_AUT_PIN_1;
+ pObjectInfo->objectACL.writePermission = MSC_AUT_NONE;
+ pObjectInfo->objectACL.deletePermission = MSC_AUT_NONE;
+ break;
+ }
+
+ pObjectInfo->objectSize = itemSize;
+
+ seq += 1;
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCLogoutAll( MSCLPTokenConnection pConnection ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCGetChallenge( MSCLPTokenConnection pConnection, MSCPUChar8 pSeed,
+ MSCUShort16 seedSize, MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize ) {
+
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCTransmitBuffer tBuffer;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ txBuffer[OFFSET_CLA] = 0x80;
+ txBuffer[OFFSET_INS] = 0x84;
+ txBuffer[OFFSET_P1] = 0x00;
+ txBuffer[OFFSET_P2] = 0x00;
+ txBuffer[OFFSET_P3] = 0x08;
+
+ if ( randomDataSize != 8 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ tBuffer.apduResponseSize = MAX_BUFFER_SIZE;
+ tBuffer.bufferSize = 5;
+
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if(tBuffer.apduResponseSize == 2) {
+ return convertSW(rxBuffer);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCIdentifyToken( MSCLPTokenConnection pConnection ) {
+
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCTransmitBuffer tBuffer;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ /* Select AID */
+ txBuffer[0] = 0x00; txBuffer[1] = 0xA4; txBuffer[2] = 0x04;
+ txBuffer[3] = 0x00; txBuffer[4] = sizeof(CAC_APPLET_PKI_ESIG_AID);
+
+ /* Copy PKI Applet */
+ memcpy(&txBuffer[5], CAC_APPLET_PKI_ESIG_AID,
+ sizeof(CAC_APPLET_PKI_ESIG_AID));
+
+ tBuffer.bufferSize = 5 + sizeof(CAC_APPLET_PKI_ESIG_AID);
+ tBuffer.apduResponseSize = sizeof(CAC_APPLET_PKI_ESIG_AID) + 5;
+
+ suppressResponse = 1;
+ rv = SCardExchangeAPDU( pConnection, &tBuffer );
+ suppressResponse = 0;
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( rxBuffer[0] != 0x61 ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCInitializePlugin( MSCLPTokenConnection pConnection ) {
+
+ /* Clean up and make sure all is shut down. */
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CACPLUGIN_API
+#endif
+MSC_RV PL_MSCFinalizePlugin( MSCLPTokenConnection pConnection ) {
+
+ /* Clean up and make sure all is shut down. */
+
+ tlvsCached = 0;
+ pntbSize = 0;
+ pnvbSize = 0;
+ pltbSize = 0;
+ plvbSize = 0;
+ bstbSize = 0;
+ bsvbSize = 0;
+ obtbSize = 0;
+ obvbSize = 0;
+ cacIDCertSize = 0;
+ cacESignCertSize = 0;
+ cacECryptCertSize = 0;
+ dataIsCached = 0;
+ pConnection->loggedIDs = 0;
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV CACLoadTLVSize(MSCLPTokenConnection pConnection,
+ MSCPUChar8 demoPointer,
+ MSCULong32 demoSize,
+ MSCPUShort16 tlvSize,
+ MSCUChar8 tlvType) {
+
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCTransmitBuffer tBuffer;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ if ( *tlvSize != 0 ) {
+ /* Data already cached */
+ return MSC_SUCCESS;
+ }
+
+ rv = CACSelectInstance( pConnection, demoPointer, demoSize );
+
+ if ( rv != MSC_SUCCESS )
+ return rv;
+
+ txBuffer[OFFSET_CLA] = 0x80;
+ txBuffer[OFFSET_INS] = 0x56;
+ txBuffer[OFFSET_P1] = 0x00;
+ txBuffer[OFFSET_P2] = 0x00;
+ txBuffer[OFFSET_P3] = 0x2E;
+
+ tBuffer.bufferSize = 5;
+ tBuffer.apduResponseSize = MAX_BUFFER_SIZE;
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if ( tBuffer.apduResponseSize == 2 ) {
+ if (rxBuffer[0] == 0x6C) {
+ /* We requested the wrong length, try again */
+
+ txBuffer[OFFSET_P3] = rxBuffer[1];
+ tBuffer.apduResponseSize = MAX_BUFFER_SIZE;
+ rv = SCardExchangeAPDU(pConnection, &tBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ } else {
+ /* Another status return */
+ return convertSW(rxBuffer);
+ }
+
+ } else if (tBuffer.apduResponseSize != (txBuffer[OFFSET_P3] + 2)) {
+ return MSC_INTERNAL_ERROR;
+ }
+
+ if ( tlvType == 0 ) {
+ /* Get the Tag */
+ *tlvSize = rxBuffer[28] + rxBuffer[29]*0x100;
+ } else {
+ /* Get the Value */
+ *tlvSize = rxBuffer[30] + rxBuffer[31]*0x100;
+ }
+
+ return MSC_SUCCESS;
+
+}
+
+MSC_RV CACLoadCertificate(MSCLPTokenConnection pConnection, MSCPUChar8 cert,
+ MSCPUShort16 certSize) {
+
+ MSCLong32 rv;
+ MSCULong32 dataPosition;
+ MSCULong32 defLength;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCTransmitBuffer tBuffer;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ defLength = 0; dataPosition = 0;
+
+ /* Getting certificate */
+
+ txBuffer[0] = 0x80; txBuffer[1] = 0x36; txBuffer[2] = 0x00;
+ txBuffer[3] = 0x00; txBuffer[4] = 0x64;
+
+ /* Reading the certificate */
+
+ do {
+ /* Read data in 0x64 byte chunks */
+ tBuffer.bufferSize = 0x05;
+ tBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &tBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) { return convertPCSC(rv); }
+
+ if ( tBuffer.apduResponseSize == 2 ) {
+ if (( rxBuffer[0] == 0x69 ) && ( rxBuffer[1] == 0x81 )) {
+ *certSize = 0;
+ return MSC_OBJECT_NOT_FOUND;
+ } else if (( rxBuffer[0] == 0x69 ) && ( rxBuffer[1] == 0x82 )) {
+ *certSize = 0;
+ return MSC_UNAUTHORIZED;
+
+ }
+ } else if ( tBuffer.apduResponseSize != txBuffer[4] + 2 ) {
+ /* Card was removed during a transaction */
+ return MSC_INTERNAL_ERROR;
+ } else {
+ memcpy(&cacCompBuffer[dataPosition], rxBuffer,
+ tBuffer.apduResponseSize - 2);
+ dataPosition += tBuffer.apduResponseSize - 2;
+ txBuffer[4] = rxBuffer[tBuffer.apduResponseSize-1];
+ }
+ } while ( rxBuffer[tBuffer.apduResponseSize-2] == 0x63 );
+
+ /* Done reading certificate */
+
+ if (cacCompBuffer[0] == 0x01) { /* this is compressed */
+ defLength = CAC_MAXSIZE_CERT;
+ rv = uncompress(cert, (uLongf *)&defLength, &cacCompBuffer[1],
+ dataPosition - 1);
+ if ( rv != 0 ) {
+ return MSC_INTERNAL_ERROR;
+ }
+
+ *certSize = defLength;
+
+ } else {
+ memcpy(cert, &cacCompBuffer[1], dataPosition - 1);
+ *certSize = dataPosition - 1;
+ }
+
+ return MSC_SUCCESS;
+
+}
+
+MSC_RV CACSelectInstance(MSCLPTokenConnection pConnection, MSCPUChar8 aid,
+ MSCULong32 aidLength) {
+
+ MSCLong32 rv;
+ MSCPUChar8 txBuffer;
+ MSCPUChar8 rxBuffer;
+ MSCTransmitBuffer tBuffer;
+
+ txBuffer = tBuffer.pBuffer;
+ rxBuffer = tBuffer.apduResponse;
+
+ /* Now we must select the PKI instance, read the
+ certificate and cache it, updating it's size */
+
+ tBuffer.bufferSize = aidLength + 5;
+ tBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+
+ /* Select AID */
+ txBuffer[0] = 0x00; txBuffer[1] = 0xA4; txBuffer[2] = 0x04;
+ txBuffer[3] = 0x00; txBuffer[4] = aidLength;
+
+ memcpy(&txBuffer[5], aid, aidLength);
+
+ suppressResponse = 1;
+ rv = SCardExchangeAPDU( pConnection, &tBuffer );
+ suppressResponse = 0;
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( rxBuffer[0] != 0x61 ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV CACLoadAndCacheData(MSCLPTokenConnection pConnection) {
+
+ MSCLong32 rv;
+ MSCPUChar8 certPointer;
+ MSCPUChar8 pkiPointer;
+ MSCULong32 pkiSize;
+ MSCPUChar8 demoPointer;
+ MSCULong32 demoSize;
+ MSCPUShort16 itemCache;
+ unsigned short *certSizePointer;
+
+ if ( dataIsCached == 1 ) {
+ return MSC_SUCCESS;
+ }
+
+ pkiPointer = CAC_APPLET_PKI_ID_AID;
+ pkiSize = sizeof(CAC_APPLET_PKI_ID_AID);
+ certPointer = cacIDCert;
+ certSizePointer = &cacIDCertSize;
+
+ if ( *certSizePointer == 0 ) {
+ rv = CACSelectInstance( pConnection, pkiPointer, pkiSize );
+ if ( rv == MSC_SUCCESS )
+ rv = CACLoadCertificate(pConnection, certPointer, certSizePointer);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+
+ if (*certSizePointer == 0) {
+ cacIDCertAttrSize = 0;
+ cacIDKeyAttrSize = 0;
+ }
+ }
+
+ pkiPointer = CAC_APPLET_PKI_ECRY_AID;
+ pkiSize = sizeof(CAC_APPLET_PKI_ECRY_AID);
+ certPointer = cacECryptCert;
+ certSizePointer = &cacECryptCertSize;
+ if ( *certSizePointer == 0 ) {
+ rv = CACSelectInstance( pConnection, pkiPointer, pkiSize );
+ if ( rv == MSC_SUCCESS )
+ CACLoadCertificate(pConnection, certPointer, certSizePointer);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+
+ if (*certSizePointer == 0) {
+ cacECryptCertAttrSize = 0;
+ cacECryptKeyAttrSize = 0;
+ }
+ }
+
+ pkiPointer = CAC_APPLET_PKI_ESIG_AID;
+ pkiSize = sizeof(CAC_APPLET_PKI_ESIG_AID);
+ certPointer = cacESignCert;
+ certSizePointer = &cacESignCertSize;
+ if ( *certSizePointer == 0 ) {
+ rv = CACSelectInstance( pConnection, pkiPointer, pkiSize );
+ if ( rv == MSC_SUCCESS )
+ CACLoadCertificate(pConnection, certPointer, certSizePointer);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+
+ if (*certSizePointer == 0) {
+ cacESignCertAttrSize = 0;
+ cacESignKeyAttrSize = 0;
+ }
+
+
+ }
+
+ itemCache = &pntbSize;
+ demoPointer = CAC_APPLET_CONT_PN_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PN_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 0);
+ }
+
+ itemCache = &pnvbSize;
+ demoPointer = CAC_APPLET_CONT_PN_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PN_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 1);
+ }
+
+ itemCache = &pltbSize;
+ demoPointer = CAC_APPLET_CONT_PL_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PL_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 0);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+ }
+
+ itemCache = &plvbSize;
+ demoPointer = CAC_APPLET_CONT_PL_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_PL_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 1);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+ }
+
+ itemCache = &bstbSize;
+ demoPointer = CAC_APPLET_CONT_BS_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_BS_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 0);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+ }
+
+ itemCache = &bsvbSize;
+ demoPointer = CAC_APPLET_CONT_BS_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_BS_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 1);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+ }
+
+ itemCache = &obtbSize;
+ demoPointer = CAC_APPLET_CONT_OB_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_OB_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 0);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+ }
+
+ itemCache = &obvbSize;
+ demoPointer = CAC_APPLET_CONT_OB_AID;
+ demoSize = sizeof(CAC_APPLET_CONT_OB_AID);
+ if ( *itemCache == 0 ) {
+ rv = CACLoadTLVSize(pConnection, demoPointer, demoSize, itemCache, 1);
+ if ( rv == MSC_INTERNAL_ERROR ) { return rv; }
+ }
+
+ dataIsCached = 1;
+ return MSC_SUCCESS;
+
+}
+
+
+MSCUShort16 convertSW(MSCPUChar8 pBuffer) {
+ MSCUShort16 retValue;
+ MSCUShort16 newValue;
+
+ retValue = pBuffer[0] * 0x100;
+ retValue += pBuffer[1];
+
+ switch(retValue) {
+ case CACMSC_SUCCESS:
+ newValue = MSC_SUCCESS;
+ break;
+ case CACMSC_NO_MEMORY_LEFT:
+ newValue = MSC_NO_MEMORY_LEFT;
+ break;
+ case CACMSC_AUTH_FAILED:
+ newValue = MSC_AUTH_FAILED;
+ break;
+ case CACMSC_UNSUPPORTED_FEATURE:
+ newValue = MSC_UNSUPPORTED_FEATURE;
+ break;
+ case CACMSC_UNAUTHORIZED:
+ newValue = MSC_UNAUTHORIZED;
+ break;
+ case CACMSC_OBJECT_NOT_FOUND:
+ newValue = MSC_OBJECT_NOT_FOUND;
+ break;
+ case CACMSC_OBJECT_EXISTS:
+ newValue = MSC_OBJECT_EXISTS;
+ break;
+ case CACMSC_INCORRECT_ALG:
+ newValue = MSC_INCORRECT_ALG;
+ break;
+ case CACMSC_IDENTITY_BLOCKED:
+ newValue = MSC_IDENTITY_BLOCKED;
+ break;
+ case CACMSC_UNSPECIFIED_ERROR:
+ newValue = MSC_UNSPECIFIED_ERROR;
+ break;
+ case CACMSC_INVALID_PARAMETER:
+ newValue = MSC_INVALID_PARAMETER;
+ break;
+ case CACMSC_INTERNAL_ERROR:
+ newValue = MSC_INTERNAL_ERROR;
+ break;
+ default:
+ newValue = retValue;
+ break;
+ }
+
+ return newValue;
+}
+
+void MemCopy16(MSCPUChar8 destValue, MSCPUShort16 srcValue) {
+ destValue[0] = (*srcValue & 0xFF00) >> 8;
+ destValue[1] = (*srcValue & 0x00FF);
+}
+
+void MemCopy32(MSCPUChar8 destValue, MSCPULong32 srcValue) {
+ destValue[0] = (*srcValue >> 24);
+ destValue[1] = (*srcValue & 0x00FF0000) >> 16;
+ destValue[2] = (*srcValue & 0x0000FF00) >> 8;
+ destValue[3] = (*srcValue & 0x000000FF);
+}
+
+void MemCopyTo16(MSCPUShort16 destValue, MSCPUChar8 srcValue) {
+
+ *destValue = srcValue[0] * 0x100;
+ *destValue += srcValue[1];
+
+}
+
+void MemCopyTo32(MSCPULong32 destValue, MSCPUChar8 srcValue) {
+
+ *destValue = srcValue[0] * 0x1000000;
+ *destValue += srcValue[1] * 0x10000;
+ *destValue += srcValue[2] * 0x100;
+ *destValue += srcValue[3];
+
+}
+
+MSCUShort16 getUShort16(MSCPUChar8 srcValue) {
+ return ( (((MSCUShort16)srcValue[0]) << 8) || srcValue[1] );
+}
+
+void setUShort16(MSCPUChar8 dstValue, MSCUShort16 srcValue) {
+ MemCopyTo16(&srcValue, dstValue);
+}
+
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection pConnection,
+ MSCLPTransmitBuffer transmitBuffer ) {
+
+ MSCLong32 rv, ret;
+ MSCULong32 originalLength;
+ MSCUChar8 getResponse[5] = {0x00, 0xC0, 0x00, 0x00, 0x00};
+ MSCULong32 dwActiveProtocol;
+
+#ifdef MSC_DEBUG
+ int i;
+#endif
+
+ originalLength = transmitBuffer->apduResponseSize;
+
+ while (1) {
+
+#ifdef MSC_DEBUG
+ printf("[%02d]->: ", transmitBuffer->bufferSize);
+
+ for (i=0; i < transmitBuffer->bufferSize; i++) {
+ printf("%02x ", transmitBuffer->pBuffer[i]);
+ } printf("\n");
+#endif
+
+ while(1) {
+ transmitBuffer->apduResponseSize = originalLength;
+
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ transmitBuffer->pBuffer,
+ transmitBuffer->bufferSize, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+ break;
+
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+ /* Must be a BIG, BAD, ERROR */
+#ifdef MSC_DEBUG
+ printf("Transmit error: %s\n", pcsc_stringify_error(rv));
+#endif
+ return rv;
+ }
+ }
+
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+
+ if ( suppressResponse == 1 ) {
+ /* Do not do the Get Response */
+ break;
+ }
+
+ if ( transmitBuffer->apduResponseSize == 2 &&
+ transmitBuffer->apduResponse[0] == 0x61 ) {
+#ifdef MSC_DEBUG
+ printf("->: 0x00 0xC0 0x00 0x00 %02x\n",
+ transmitBuffer->apduResponse[1]);
+#endif
+ getResponse[4] = transmitBuffer->apduResponse[1];
+ transmitBuffer->apduResponseSize = originalLength;
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ getResponse, 5, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+ break;
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+#ifdef MSC_DEBUG
+ printf("Transmit error: %s\n", pcsc_stringify_error(rv));
+#endif
+ return rv;
+ }
+ }
+
+ break;
+ } /* End of while */
+
+
+ return rv;
+}
+
+
+MSC_RV convertPCSC( MSCLong32 pcscCode ) {
+
+ switch(pcscCode) {
+ case SCARD_S_SUCCESS:
+ return MSC_SUCCESS;
+ case SCARD_E_INVALID_HANDLE:
+ return MSC_INVALID_HANDLE;
+ case SCARD_E_SHARING_VIOLATION:
+ return MSC_SHARING_VIOLATION;
+ case SCARD_W_REMOVED_CARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_E_NO_SMARTCARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_W_RESET_CARD:
+ return MSC_TOKEN_RESET;
+ case SCARD_W_INSERTED_CARD:
+ return MSC_TOKEN_INSERTED;
+ case SCARD_E_NO_SERVICE:
+ return MSC_SERVICE_UNRESPONSIVE;
+ case SCARD_E_UNKNOWN_CARD:
+ case SCARD_W_UNSUPPORTED_CARD:
+ case SCARD_E_CARD_UNSUPPORTED:
+ return MSC_UNRECOGNIZED_TOKEN;
+ case SCARD_E_INVALID_PARAMETER:
+ case SCARD_E_INVALID_VALUE:
+ case SCARD_E_UNKNOWN_READER:
+ case SCARD_E_PROTO_MISMATCH:
+ case SCARD_E_READER_UNAVAILABLE:
+ return MSC_INVALID_PARAMETER;
+ case SCARD_E_CANCELLED:
+ return MSC_CANCELLED;
+ case SCARD_E_TIMEOUT:
+ return MSC_TIMEOUT_OCCURRED;
+
+ default:
+ return MSC_INTERNAL_ERROR;
+ }
+}
+
+
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.c
___________________________________________________________________
Added: svn:executable
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : commonAccessCard.h
+ Package: CACPlugin
+ Author : David Corcoran
+ Date : 02/06/02
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts the CAC Interface
+
+
+********************************************************************/
+
+#ifndef __commonAccessCard_h__
+#define __commonAccessCard_h__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Some useful offsets in the buffer */
+#define OFFSET_CLA 0x00
+#define OFFSET_INS 0x01
+#define OFFSET_P1 0x02
+#define OFFSET_P2 0x03
+#define OFFSET_P3 0x04
+#define OFFSET_DATA 0x05
+
+
+#define CAC_GID_CERTNAME "C3"
+#define CAC_MID_CERTNAME "C5"
+#define CAC_ENC_CERTNAME "C7"
+
+#define MC_1024P_FULLSIZE 140
+#define MC_SIZEOF_COMPSIZE 2
+#define MC_1024_OFFSET_P 4
+#define MC_1024_OFFSET_Q 70
+#define MC_1024_OFFSET_PQ 136
+#define MC_1024_OFFSET_DP1 202
+#define MC_1024_OFFSET_DQ1 268
+
+#define MC_1024P_MOD 4
+#define MC_1024P_EXP 134
+
+#define MC_DES_OFFSET_KEY 4
+
+ /* Sizes of particular objects */
+#define MSC_SIZEOF_OBJECTID 4
+#define MSC_SIZEOF_OBJECTSIZE 4
+#define MSC_SIZEOF_KEYINFO 11
+#define MSC_SIZEOF_STATUS 16
+#define MSC_SIZEOF_VERSION 2
+#define MSC_SIZEOF_FREEMEM 4
+#define MSC_SIZEOF_LOGIDS 2
+#define MSC_SIZEOF_ADDINFO 8
+#define MSC_SIZEOF_OPTLEN 2
+#define MSC_SIZEOF_GENOPTIONS 1
+#define MSC_SIZEOF_KEYSIZE 2
+#define MSC_SIZEOF_KEYNUMBER 1
+#define MSC_SIZEOF_KEYTYPE 1
+#define MSC_SIZEOF_KEYPARTNER 1
+#define MSC_SIZEOF_CIPHERMODE 1
+#define MSC_SIZEOF_CIPHERDIR 1
+#define MSC_SIZEOF_CRYPTLEN 2
+#define MSC_SIZEOF_ALGOTYPE 1
+#define MSC_SIZEOF_IDUSED 1
+#define MSC_SIZEOF_OFFSET 4
+#define MSC_SIZEOF_ACLSTRUCT 6
+#define MSC_SIZEOF_RWDATA 1
+#define MSC_SIZEOF_PINSIZE 1
+#define MSC_SIZEOF_CIPHERMODE 1
+#define MSC_SIZEOF_CIPHERDIR 1
+#define MSC_SIZEOF_DATALOCATION 1
+#define MSC_SIZEOF_ACLVALUE 2
+#define MSC_SIZEOF_SEEDLENGTH 2
+#define MSC_SIZEOF_RANDOMSIZE 2
+
+ /** success */
+#define CACMSC_SUCCESS 0x9000
+
+ /** There have been memory problems on the card */
+#define CACMSC_NO_MEMORY_LEFT 0x6A84
+ /** Entered PIN is not correct */
+#define CACMSC_AUTH_FAILED 0x6300
+ /** Required feature is not (yet) supported */
+#define CACMSC_UNSUPPORTED_FEATURE 0x6D00
+ /** Required operation was not authorized because lack of privileges */
+#define CACMSC_UNAUTHORIZED 0x6982
+ /** Required object is missing */
+#define CACMSC_OBJECT_NOT_FOUND 0x6A82
+ /** New object ID already in use */
+#define CACMSC_OBJECT_EXISTS 0x6A80
+ /** Algorithm specified is not correct */
+#define CACMSC_INCORRECT_ALG 0x6981
+
+ /** Operation has been blocked for security reason */
+#define CACMSC_IDENTITY_BLOCKED 0x6983
+ /** Unspecified error */
+#define CACMSC_UNSPECIFIED_ERROR 0x6F00
+ /** PCSC and driver transport errors */
+#define CACMSC_INVALID_PARAMETER 0x6B00
+ /** Incorrect P1 parameter */
+#define CACMSC_INCORRECT_P1 0x6B00
+ /** Incorrect P2 parameter */
+#define CACMSC_INCORRECT_P2 0x6B00
+ /** For debugging purposes */
+#define CACMSC_INTERNAL_ERROR 0x6581
+
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __commonAccessCard_h__ */
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CACPlugin/commonAccessCard.h
___________________________________________________________________
Added: svn:executable
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1065 @@
+/*
+ * usbserial.h
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ * Initial implementation from David Corcoran (corcoran at linuxnet.com)
+ *
+ */
+
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <mach/mach.h>
+#include <mach/mach_error.h>
+
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFURL.h>
+#include <CoreFoundation/CFPlugIn.h>
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/usb/IOUSBLib.h>
+
+
+#include <IOKit/IOCFPlugIn.h>
+
+#include <assert.h>
+#include "global.h"
+#include <wintypes.h>
+#include "pcscdefines.h"
+#include "usbserial.h"
+#include "Transport.h"
+
+#include "usbserial_mosx.h"
+#include "tools.h"
+
+#define USBMAX_READERS (PCSCLITE_MAX_CHANNELS)
+//+++ Should be included from a pcscd header file
+#define PCSCLITE_HP_BASE_PORT 0x200000
+#define PCSCLITE_HP_IFACECLASSKEY_NAME "ifdInterfaceClass"
+#define PCSCLITE_HP_IFACESUBCLASSKEY_NAME "ifdInterfaceSubClass"
+#define PCSCLITE_HP_IFACEPROTOCOLKEY_NAME "ifdInterfaceProtocol"
+
+
+// Used to read the manufacturer USB strings
+#define LANGUAGE_ID 0x0409
+#define STRING_REQUEST 0x03
+
+
+// Read time out in milliseconds (default value)
+unsigned long ReadTimeOut = 60000;
+
+
+static int iInitialized = FALSE;
+
+
+static intrFace intFace[USBMAX_READERS];
+
+
+// Local helper function
+void ReadUSBString(IOUSBDeviceInterface245 **dev, UInt8 bIndex,
+ const char* pcHeader);
+
+
+TrRv OpenUSB( DWORD lun, DWORD Channel)
+{
+ kern_return_t kr;
+ IOReturn ior;
+ CFMutableDictionaryRef USBMatch = 0;
+ io_iterator_t iter = 0;
+ io_service_t USBDevice = 0;
+ io_service_t USBInterface = 0;
+ IOCFPlugInInterface **ioPlugin=NULL;
+ HRESULT res;
+ SInt32 score;
+ DWORD rdrLun;
+ UInt8 class, subClass, protocol;
+ CFNumberRef CFclass = 0;
+ CFNumberRef CFsubClass = 0;
+ CFNumberRef CFprotocol = 0;
+//+ CFNumberRef CFUsbAddress = 0;
+ UInt32 usbAddr, targetusbAddress;
+ short iFound;
+ mach_port_t masterPort;
+ UInt8 sleepCount;
+ const char* cStringValue;
+ UInt16 i=0;
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Entering OpenUSB");
+
+
+ rdrLun = lun >> 16;
+
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+
+ // Parse the bundle for various information
+ cStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, PCSCLITE_HP_IFACECLASSKEY_NAME);
+ if ( cStringValue == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "OpenUSB error: ifdInterfaceClass not found");
+ return TrRv_ERR;
+ }
+ class = (UInt8) strtoul(cStringValue, 0, 16);
+
+ cStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, PCSCLITE_HP_IFACESUBCLASSKEY_NAME);
+ if ( cStringValue == NULL )
+ {
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "OpenUSB warning: ifdInterfaceSubClass not found");
+ return TrRv_ERR;
+ }
+ subClass = (UInt8) strtoul(cStringValue, 0, 16);
+
+
+ cStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, PCSCLITE_HP_IFACEPROTOCOLKEY_NAME);
+ if ( cStringValue == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "OpenUSB warning: ifdInterfaceProtocol not found");
+ return TrRv_ERR;
+ }
+ protocol = (UInt8) strtoul(cStringValue, 0, 16);
+
+ cStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, "ifdReadTimeOut");
+ if ( cStringValue == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "OpenUSB warning: ifdReadTimeOut not found, use default: %ld ms",
+ ReadTimeOut);
+ }
+ else
+ {
+ ReadTimeOut = strtoul(cStringValue, 0, 10);
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "Driver configured to detect Interface class=%02X, subClass=%02X, protocol=%02X",
+ class, subClass, protocol);
+
+ iFound = FALSE;
+
+ if ( iInitialized == FALSE ) {
+
+ for (i=0; i < USBMAX_READERS; i++) {
+ (intFace[i]).usbAddr = 0;
+ (intFace[i]).dev = NULL;
+ (intFace[i]).iface = NULL;
+ (intFace[i]).inPipeRef = 0;
+ (intFace[i]).outPipeRef = 0;
+ (intFace[i]).used = 0;
+ (intFace[i]).ready = 0;
+ (intFace[i]).class = 0;
+ (intFace[i]).subClass = 0;
+ }
+
+ iInitialized = TRUE;
+
+ }
+
+ kr = IOMasterPort(MACH_PORT_NULL, &masterPort);
+ if (kr || !masterPort)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Couldn't create a master IOKit Port (0x%08X)", kr);
+ return TrRv_ERR;
+ }
+
+
+
+ USBMatch = IOServiceMatching(kIOUSBInterfaceClassName);
+ if (!USBMatch)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Can't create a USB matching dictionary");
+ mach_port_deallocate(mach_task_self(), masterPort);
+ return TrRv_ERR;
+ }
+ // Compute target usb Address from Channel ID
+
+ targetusbAddress = Channel - PCSCLITE_HP_BASE_PORT;
+/*+
+ // Locate device according to USB address
+ CFUsbAddress = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberSInt64Type,
+ &targetusbAddress);
+ if (!CFUsbAddress)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Can't create a CFNumber for usb Address");
+ mach_port_deallocate(mach_task_self(), masterPort);
+ return TrRv_ERR;
+ }
+ CFDictionarySetValue(USBMatch,
+ CFSTR(kUSBDevicePropertyAddress),
+ CFUsbAddress);
+ CFRelease(CFUsbAddress);
+*/
+
+ // Prepare CFNumbers for the dictionary
+ CFclass = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberCharType,
+ &class);
+ if (!CFclass)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Can't create a CFNumber for interface class byte");
+ mach_port_deallocate(mach_task_self(), masterPort);
+ return TrRv_ERR;
+ }
+ CFDictionarySetValue(USBMatch,
+ CFSTR(kUSBInterfaceClass),
+ CFclass);
+ CFRelease(CFclass);
+
+
+
+ CFsubClass = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberCharType,
+ &subClass);
+ if (!CFsubClass)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Can't create a CFNumber for interface subclass byte");
+ mach_port_deallocate(mach_task_self(), masterPort);
+ return TrRv_ERR;
+ }
+ CFDictionarySetValue(USBMatch,
+ CFSTR(kUSBInterfaceSubClass),
+ CFsubClass);
+ CFRelease(CFsubClass);
+
+
+
+ CFprotocol = CFNumberCreate(kCFAllocatorDefault,
+ kCFNumberCharType,
+ &protocol);
+ if (!CFprotocol)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Can't create a CFNumber for interface protocol byte");
+ mach_port_deallocate(mach_task_self(), masterPort);
+ return TrRv_ERR;
+ }
+ CFDictionarySetValue(USBMatch,
+ CFSTR(kUSBInterfaceProtocol),
+ CFprotocol);
+ CFRelease(CFprotocol);
+
+ /* Get an iterator over all matching IOService nubs */
+ kr = IOServiceGetMatchingServices(masterPort, USBMatch, &iter);
+ USBMatch = 0; // This was consumed by abbove call (according to USBSimple, main.c)
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Can't create a USB Service iterator (0x%08X)", kr);
+ mach_port_deallocate(mach_task_self(), masterPort);
+ return TrRv_ERR;
+ }
+
+ // masterPort not used any more
+ mach_port_deallocate(mach_task_self(), masterPort);
+
+
+ // We loop on all interfaces matching the triplet (class, subclass, protocol)
+ // and identify the right one using the device usb address (or Location ID)
+ // This would not work with USB devices exposing 2 or more CCID interfaces
+ while ( (USBInterface = IOIteratorNext(iter)) )
+ {
+ // Get the IOServices plug-in for the interface
+ kr = IOCreatePlugInInterfaceForService(USBInterface,
+ kIOUSBInterfaceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &ioPlugin, &score);
+ IOObjectRelease(USBInterface); /* done with the interface object now */
+ if (kr || !ioPlugin)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to create a plugin (0x%08X)", kr);
+ continue;
+ }
+
+ /* Get the interface */
+ res = (*ioPlugin)->QueryInterface(ioPlugin,
+ CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID245),
+ (LPVOID)&(intFace[rdrLun]).iface);
+ IODestroyPlugInInterface(ioPlugin);
+ if (res || !(intFace[rdrLun]).iface)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Couldn't create a device interface (0x%08X)", res);
+ continue;
+ }
+
+ // Get the USB address of the discovered matching interface
+ ior = (*(intFace[rdrLun]).iface)->GetLocationID(((intFace[rdrLun]).iface), &usbAddr);
+ if (ior)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Couldn't get the interface location ID (0x%08X)", ior);
+ continue;
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose,
+ "Found Interface at usb address 0x%08X (target=0x%08X)",
+ usbAddr, targetusbAddress);
+
+ // Check if this interface is on the device given as channel ID
+ if (usbAddr == targetusbAddress)
+ {
+ iFound = TRUE;
+ break;
+ }
+ }
+
+
+
+ // iterator not needed anymore.
+ IOObjectRelease(iter);
+
+ if (!iFound)
+ {
+ /* Device not found */
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Unable to locate interface");
+ return TrRv_ERR;
+ }
+
+ // Device discovered, memorize its properties
+ (intFace[rdrLun]).class = class;
+ (intFace[rdrLun]).subClass = subClass;
+ (intFace[rdrLun]).protocol = protocol;
+
+ // Get the USB device the intereface is part of
+ ior = (*(intFace[rdrLun]).iface)->GetDevice((intFace[rdrLun]).iface,
+ &USBDevice);
+ if (ior)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Couldn't get the parent device (0x%08X)", ior);
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ return TrRv_ERR;
+ }
+
+ // Get the plug-in for the device
+
+ kr = IOCreatePlugInInterfaceForService(USBDevice, kIOUSBDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &ioPlugin, &score);
+ IOObjectRelease(USBDevice); /* done with the device object now */
+ if (kr || !ioPlugin)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to create a plugin for device (0x%08X)", kr);
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ return TrRv_ERR;
+ }
+
+ // Get the device
+ res = (*ioPlugin)->QueryInterface(ioPlugin,
+ CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245),
+ (LPVOID)&(intFace[rdrLun]).dev);
+ IODestroyPlugInInterface(ioPlugin);
+ if (res || !(intFace[rdrLun]).dev)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Couldn't create a device (0x%08X)", res);
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ return TrRv_ERR;
+ }
+
+
+ // Open the device using Apple's KB example to resolve arbitration
+ // issues with Classic
+ for (sleepCount = 5; sleepCount > 0; sleepCount--)
+ {
+ kr = (*(intFace[rdrLun]).dev)->USBDeviceOpen(((intFace[rdrLun]).dev));
+ if (kr == kIOReturnExclusiveAccess)
+ {
+ sleep(1);
+ }
+ else
+ {
+ if ( kr != kIOReturnSuccess)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to open device, not kIOReturnExclusiveAccess: 0x%08X", kr);
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ (*(intFace[rdrLun]).dev)->Release(((intFace[rdrLun]).dev));
+ return TrRv_ERR;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ if ( kr != kIOReturnSuccess)
+ {
+ // Some process is still using the device
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to open device, device busy");
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ (*(intFace[rdrLun]).dev)->Release(((intFace[rdrLun]).dev));
+ return TrRv_ERR;
+ }
+
+ (intFace[rdrLun]).usbAddr = usbAddr;
+ // Now the device is used but not set-up yet (pipes,...)
+ (intFace[rdrLun]).used = 1;
+
+
+
+ // Get and store the device VendorID/ProductID
+ (intFace[rdrLun]).vendorID = 0;
+ ior = (*(intFace[rdrLun]).iface)->GetDeviceVendor(((intFace[rdrLun]).iface),
+ (&((intFace[rdrLun]).vendorID)));
+ if (ior)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "unable to get device vendor Id");
+ }
+
+ (intFace[rdrLun]).productID = 0;
+ ior = (*(intFace[rdrLun]).iface)->GetDeviceProduct(((intFace[rdrLun]).iface),
+ (&((intFace[rdrLun]).productID)));
+ if (ior)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "unable to get device product Id");
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "Driver captured device with vendor Id %04X\n",
+ (intFace[rdrLun]).vendorID);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "Driver captured device with product Id %04X\n",
+ (intFace[rdrLun]).productID);
+
+ // Read the USB strings to identify in the logs which reader
+ // was captured
+
+ // Index of the manufacturer, product and serial number strings
+ UInt8 manIdx, prodIdx, snIdx;
+ kr = (*(intFace[rdrLun]).dev)->USBGetManufacturerStringIndex((intFace[rdrLun]).dev,
+ &manIdx);
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "Could not get Manufacturer string");
+ }
+ else
+ {
+ ReadUSBString((intFace[rdrLun]).dev, manIdx, "manufacturer");
+ }
+ kr = (*(intFace[rdrLun]).dev)->USBGetProductStringIndex((intFace[rdrLun]).dev,
+ &prodIdx);
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "Could not get Product string");
+ }
+ else
+ {
+ ReadUSBString((intFace[rdrLun]).dev, prodIdx, "product name");
+ }
+
+ kr = (*(intFace[rdrLun]).dev)->USBGetSerialNumberStringIndex((intFace[rdrLun]).dev,
+ &snIdx);
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose,
+ "Could not get Serial Number string");
+ }
+ else
+ {
+ ReadUSBString((intFace[rdrLun]).dev, snIdx, "serial number");
+ }
+
+
+
+
+ // Now release the interface as the call to SetConfiguration on
+ // the device in SetupConnectionsUSB() will break it
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ (intFace[rdrLun]).iface = 0;
+
+ return TrRv_OK;
+}
+
+
+TrRv GetConfigDescNumberUSB( DWORD lun, BYTE* pcconfigDescNb )
+{
+ DWORD rdrLun;
+ IOUSBDeviceInterface245 **dev;
+ IOReturn err;
+
+ rdrLun = lun >> 16;
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+
+ // Check if a USB connection is set-up for this lun
+ if ( ! (intFace[rdrLun]).used )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get class desc: usb not opened for lun %d", lun);
+ return TrRv_ERR;
+ }
+ dev = (intFace[rdrLun]).dev;
+ err = (*dev)->GetNumberOfConfigurations(dev, (UInt8 *) pcconfigDescNb);
+ if (err || !(*pcconfigDescNb))
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to obtain the number of configurations. ret = %08x\n",
+ err);
+ return TrRv_ERR;
+ }
+ return TrRv_OK;
+}
+
+TrRv GetVendorAndProductIDUSB( DWORD lun, DWORD *vendorID, DWORD *productID )
+{
+ DWORD rdrLun;
+
+ rdrLun = lun >> 16;
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+
+ // Check if a USB connection is set-up for this lun
+ if ( ! (intFace[rdrLun]).used )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get vendor or product ID: usb not opened for lun %d", lun);
+ return TrRv_ERR;
+ }
+ *vendorID = (intFace[rdrLun]).vendorID;
+ *productID = (intFace[rdrLun]).productID;
+ return TrRv_OK;
+}
+
+
+TrRv GetClassDescUSB( DWORD lun, BYTE configDescNb, BYTE bdescType,
+ BYTE *pcdesc, BYTE *pcdescLength)
+{
+ IOUSBDeviceInterface245 **dev;
+ IOReturn err;
+ DWORD rdrLun;
+ IOUSBConfigurationDescriptorPtr confDesc;
+
+ rdrLun = lun >> 16;
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+
+ // Check if a USB connection is set-up for this lun
+ if ( ! (intFace[rdrLun]).used )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get class desc: usb not opened for lun %d", lun);
+ return TrRv_ERR;
+ }
+ dev = (intFace[rdrLun]).dev;
+ UInt8 numConf;
+ err = (*dev)->GetNumberOfConfigurations(dev, &numConf);
+ if (err || !numConf)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to obtain the number of configurations. ret = %08x\n", err);
+ return TrRv_ERR;
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose,
+ "found %d configurations\n", numConf);
+ if ( configDescNb >= numConf )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Requested configuration nb too large: %d\n", configDescNb);
+ return TrRv_ERR;
+ }
+
+ err = (*dev)->GetConfigurationDescriptorPtr(dev, configDescNb, &confDesc);
+ if (err)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get config descriptor for index %d\n", configDescNb);
+ return TrRv_ERR;
+ }
+ char *ptr;
+ ptr = (char*) confDesc;
+ //+++ NEED TO DO THIS IN A NICER WAY (MIGHT BE FIXED IN LATER MOSX)
+ //+ This is currently done to fix the endianness of the length
+ //+ as the API returns the length in USB endianness
+ unsigned char lsb, msb;
+ lsb = *((char*)&(confDesc->wTotalLength));
+ msb = *((char*)&(confDesc->wTotalLength)+1);
+ UInt16 size, offset, offset_target_desc = 0;
+ UInt8 found_target_desc = 0;
+
+ size = (msb << 8) +lsb;
+ // Move to beginning of descriptors
+
+ //+ For some reason, sizeof(IOUSBConfigurationDescriptor)
+ //+ Does not have the right length. It is probably
+ //+ not "packed" properly in the declaration.
+ offset = 9; //sizeof(IOUSBConfigurationDescriptor);
+ ptr += 9; //sizeof(IOUSBConfigurationDescriptor);
+
+ // Scan all descriptors
+ while ( offset < size )
+ {
+ //-LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Found new descriptor,");
+ //-LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Length = %02Xh,", *(ptr));
+ //-LogMessage( __FILE__, __LINE__, LogLevelVerbose, " Type= %02X\n", *(ptr+1));
+ if ( *(ptr+1) == bdescType )
+ {
+ offset_target_desc = offset;
+ found_target_desc = 1;
+ }
+ offset += *ptr;
+ ptr += *ptr;
+ }
+ if (!found_target_desc)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, " unable to find target conf desc %02X\n", bdescType);
+ return TrRv_ERR;
+ }
+ // Reset ptr to start of config desc
+ ptr = (char*) confDesc;
+ UInt8 targetDescLength = *(ptr+offset_target_desc);
+ // Check if called to find out length or to return value
+ if ( pcdesc == NULL )
+ {
+ *pcdescLength = targetDescLength;
+ return TrRv_OK;
+ }
+ // Set length to minimal of buffer or real value
+ if ( *pcdescLength > targetDescLength )
+ {
+ *pcdescLength = targetDescLength;
+ }
+ bcopy(ptr+offset_target_desc, pcdesc, *pcdescLength);
+ return TrRv_OK;
+}
+
+//+++ NEED TO ADD and interruptPipe management
+TrRv SetupConnectionsUSB( DWORD lun, BYTE ConfigDescNb, BYTE interruptPipe)
+{
+ kern_return_t kr;
+ int i = 0;
+ IOUSBConfigurationDescriptorPtr confDesc;
+ UInt8 intfNumEndpoints;
+ UInt8 direction, number, transferType, interval;
+ UInt16 maxPacketSize;
+ io_service_t USBIface = 0;
+ io_iterator_t iter = 0;
+ IOUSBFindInterfaceRequest findInterface;
+ IOCFPlugInInterface **iodevB = 0;
+ HRESULT res;
+ SInt32 score;
+ DWORD rdrLun;
+ // Check if a USB connection is set-up for this lun
+ rdrLun = lun >> 16;
+
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+ if ( ! (intFace[rdrLun]).used )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get set-up connections: usb not opened for lun %d", lun);
+ return TrRv_ERR;
+ }
+
+
+ kr = (*(intFace[rdrLun]).dev)->GetConfigurationDescriptorPtr(((intFace[rdrLun]).dev),
+ ConfigDescNb, &confDesc);
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "ERR: unable to get the configuration: 0x%08X\n", kr);
+ return TrRv_ERR;
+ }
+
+ (*(intFace[rdrLun]).dev)->ResetDevice(((intFace[rdrLun]).dev));
+
+
+ // This call invalidates any interface currently opened on the device.
+ // Hence the re-opening of the USB interface below (even though it was
+ // already opened in OpenUSB()
+ kr = (*(intFace[rdrLun]).dev)->SetConfiguration(((intFace[rdrLun]).dev),
+ confDesc->bConfigurationValue);
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "ERR: unable to set the configuration: 0x%08X\n", kr);
+ return TrRv_ERR;
+ }
+
+
+
+ // Time to find the first CCID interface
+
+ findInterface.bInterfaceClass = (intFace[rdrLun]).class;
+ findInterface.bInterfaceSubClass = (intFace[rdrLun]).subClass;
+ findInterface.bInterfaceProtocol = (intFace[rdrLun]).protocol;
+ findInterface.bAlternateSetting = kIOUSBFindInterfaceDontCare;
+
+ kr = (*(intFace[rdrLun]).dev)->CreateInterfaceIterator(((intFace[rdrLun]).dev),
+ &findInterface, &iter);
+ if ( kr )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Can not create interface Iterator");
+ return TrRv_ERR;
+ }
+
+ USBIface = IOIteratorNext(iter);
+ //+++ We do not support a device with 2 CCID interfaces on it as
+ //++ pcscd does not support it either (Lun management would need to
+ //++ be upgraded).
+ IOObjectRelease(iter);
+ iter = 0;
+
+ if ( USBIface == 0 ) {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "No interface found");
+ return TrRv_ERR;
+ }
+
+ score = 0;
+
+
+ // Create the plugin for the interface service
+ kr = IOCreatePlugInInterfaceForService(USBIface, kIOUSBInterfaceUserClientTypeID,
+ kIOCFPlugInInterfaceID, &iodevB, &score);
+ if ( kr || !iodevB )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "No interface found");
+ IOObjectRelease(USBIface);
+ return TrRv_ERR;
+ }
+
+ // Now get the real interface
+ res = (*iodevB)->QueryInterface(iodevB, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID245),
+ (LPVOID)&(intFace[rdrLun]).iface);
+ IODestroyPlugInInterface(iodevB); // done with this
+ IOObjectRelease(USBIface);
+ if ( res || !(intFace[rdrLun]).iface)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Could not query interface");
+ return TrRv_ERR;
+ }
+
+
+ // Open the interface to open all the pipes
+ kr = (*(intFace[rdrLun]).iface)->USBInterfaceOpen((intFace[rdrLun]).iface);
+ if ( kr )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "unable to open device: 0x%08X", kr);
+ return TrRv_ERR;
+ }
+
+
+
+ // Get nb of end points
+ kr = (*(intFace[rdrLun]).iface)->GetNumEndpoints((intFace[rdrLun]).iface, &intfNumEndpoints);
+ if (kr != kIOReturnSuccess )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get number of end points: 0x%08X", kr);
+ return TrRv_ERR;
+ }
+ // pipes are one based, since zero is the default control pipe
+ for (i=1; i <= intfNumEndpoints; i++)
+ {
+ kr = (*(intFace[rdrLun]).iface)->GetPipeProperties((intFace[rdrLun]).iface, i,
+ &direction, &number,
+ &transferType, &maxPacketSize,
+ &interval);
+ if (kr != kIOReturnSuccess )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get pipe properties: 0x%08X", kr);
+ return TrRv_ERR;
+ }
+ if (transferType != kUSBBulk)
+ {
+ continue;
+ }
+ if ((direction == kUSBIn) && !((intFace[rdrLun]).inPipeRef))
+ {
+ (intFace[rdrLun]).inPipeRef = i;
+ }
+ if ((direction == kUSBOut) && !((intFace[rdrLun]).outPipeRef))
+ {
+ (intFace[rdrLun]).outPipeRef = i;
+ }
+ //+++ Need to add optional management of interrupt pipe
+
+ }
+
+
+ if ( !((intFace[rdrLun]).outPipeRef) )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get outPipe: 0x%08X", kr);
+ CloseUSB(lun);
+ return TrRv_ERR;
+ }
+
+ if (!( (intFace[rdrLun]).inPipeRef))
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to get inPipe: 0x%08X", kr);
+ CloseUSB(lun);
+ return TrRv_ERR;
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelImportant,
+ "New reader fully set-up at USB address: %08X\n",
+ (intFace[rdrLun]).usbAddr);
+ (intFace[rdrLun]).ready = 1;
+ return TrRv_OK;
+}
+
+
+
+TrRv WriteUSB( DWORD lun, DWORD length, unsigned char *buffer )
+{
+ IOReturn iorv;
+ DWORD rdrLun;
+
+ rdrLun = lun >> 16;
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+ if ( ! (intFace[rdrLun]).ready )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to write to USB: set-up not completed for lun %d", lun);
+ return TrRv_ERR;
+ }
+
+ LogHexBuffer(__FILE__, __LINE__, LogLevelVeryVerbose, buffer, length,
+ "Attempt to write: ");
+
+ /* Make sure the pipe is OK */
+ iorv = (*(intFace[rdrLun]).iface)->GetPipeStatus( (intFace[rdrLun]).iface,
+ (intFace[rdrLun]).outPipeRef );
+ if ( iorv != kIOReturnSuccess )
+ {
+ return TrRv_ERR;
+ }
+
+ /* Write the data */
+ iorv = (*(intFace[rdrLun]).iface)->WritePipe((intFace[rdrLun]).iface,
+ (intFace[rdrLun]).outPipeRef,
+ buffer, length);
+
+ if ( iorv != kIOReturnSuccess )
+ {
+ return TrRv_ERR;
+ }
+
+ return TrRv_OK;
+}
+
+TrRv ReadUSB( DWORD lun, DWORD *length, unsigned char *buffer )
+{
+ IOReturn iorv;
+ UInt32 recvLen;
+ UInt32 noDataTO, completeTO;
+ DWORD rdrLun;
+
+
+ rdrLun = lun >> 16;
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "OpenUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+ if ( ! (intFace[rdrLun]).ready )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "unable to write to USB: set-up not completed for lun %d", lun);
+ return TrRv_ERR;
+ }
+
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose,
+ "Attempt to read %ld bytes", *length);
+
+ /* Make sure the pipe is OK */
+ iorv = (*(intFace[rdrLun]).iface)->GetPipeStatus( (intFace[rdrLun]).iface,
+ (intFace[rdrLun]).inPipeRef
+ );
+ if ( iorv != kIOReturnSuccess )
+ {
+ return TrRv_ERR;
+ }
+
+ recvLen = *length;
+ completeTO = ReadTimeOut;
+ noDataTO = ReadTimeOut;
+
+ iorv = (*(intFace[rdrLun]).iface)->ReadPipeTO( (intFace[rdrLun]).iface,
+ (intFace[rdrLun]).inPipeRef,
+ buffer, &recvLen, noDataTO, completeTO);
+ if ( iorv != 0 )
+ {
+ (*(intFace[rdrLun]).dev)->ResetDevice(((intFace[rdrLun]).dev));
+ return TrRv_ERR;
+ }
+
+ LogHexBuffer(__FILE__, __LINE__, LogLevelVeryVerbose, buffer, recvLen, "received: ");
+
+ *length = recvLen;
+ return TrRv_OK;
+}
+
+TrRv CloseUSB( DWORD lun )
+{
+ IOReturn iorv;
+ DWORD rdrLun;
+
+ rdrLun = lun >> 16;
+ if ( rdrLun >= USBMAX_READERS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "CloseUSB error: lun too large: %08X", lun);
+ return TrRv_ERR;
+ }
+
+ // Reset struct
+ (intFace[rdrLun]).usbAddr = 0;
+ (intFace[rdrLun]).outPipeRef = 0;
+ (intFace[rdrLun]).inPipeRef = 0;
+ (intFace[rdrLun]).used = 0;
+ (intFace[rdrLun]).ready = 0;
+ (intFace[rdrLun]).class = 0;
+ (intFace[rdrLun]).subClass = 0;
+
+
+ /* Close the interface */
+ // Check if it was allocated
+ if ( (intFace[rdrLun]).iface )
+ {
+ iorv = (*(intFace[rdrLun]).iface)->USBInterfaceClose( (intFace[rdrLun]).iface );
+ if (iorv)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "ERR: Couldn't close interface (%08x)\n", (int)iorv);
+ }
+
+ /* Release the interface */
+ (*(intFace[rdrLun]).iface)->Release((intFace[rdrLun]).iface);
+ (intFace[rdrLun]).iface = 0;
+ }
+ if ( (intFace[rdrLun]).dev )
+ {
+ iorv = (*(intFace[rdrLun]).dev)->USBDeviceClose((intFace[rdrLun]).dev);
+ if (iorv) {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "ERR: Couldn't close device (%08x)\n", (int)iorv);
+ }
+
+ (*(intFace[rdrLun]).dev)->Release((intFace[rdrLun]).dev);
+ if ( iorv != kIOReturnSuccess ) {
+ return TrRv_ERR;
+ }
+ (intFace[rdrLun]).dev = 0;
+ }
+ return TrRv_OK;
+}
+
+
+
+
+void ReadUSBString(IOUSBDeviceInterface245 **dev, UInt8 bIndex,
+ const char* pcHeader)
+{
+ IOUSBDevRequest stDevRequest;
+ unsigned char pcArray[512];
+ kern_return_t kr;
+
+ // Generate the USB request manually
+ stDevRequest.bmRequestType = USBmakebmRequestType( kUSBIn, kUSBStandard,
+ kUSBDevice );
+ stDevRequest.bRequest = kUSBRqGetDescriptor;
+ stDevRequest.wValue = ( kUSBStringDesc << 8 ) | bIndex;
+ // Select language
+ stDevRequest.wIndex = LANGUAGE_ID;
+ stDevRequest.wLength = sizeof(pcArray);
+ stDevRequest.pData = (void *) pcArray;
+ bzero(pcArray, sizeof(pcArray));
+ kr = (*dev)->DeviceRequest(dev, &stDevRequest);
+ if (kr)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "DeviceRequest for USB string failed %08X", kr);
+ return;
+ }
+
+ // Check that we got what we wanted
+ if ( pcArray[1] != STRING_REQUEST )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "DeviceRequest for USB string did not return expected data");
+ return;
+ }
+
+ CFStringRef cfstr;
+ UInt8 tmp = pcArray[0];
+ // Add Unicode BOM to the returned string to allow CFString to
+ // work. array[0:1] stores the length of the Unicode string
+ // and a type byte
+ pcArray[0] = 0xFF;
+ pcArray[1] = 0xFE;
+
+ cfstr = CFStringCreateWithBytes (
+ kCFAllocatorDefault,
+ pcArray,
+ // Length in BYTES
+ tmp,
+ kCFStringEncodingUnicode,
+ 1
+ );
+
+
+ // Turn the CFString in a standard C string
+ if ( !CFStringGetCString (
+ cfstr,
+ (char *)pcArray,
+ sizeof(pcArray)-1,
+ kCFStringEncodingASCII
+ )
+ )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Conversion of USB string to ASCII failed, printing raw data");
+ LogHexBuffer(__FILE__, __LINE__, LogLevelCritical, pcArray+2, tmp,
+ "Raw data: ");
+ CFRelease(cfstr);
+ return;
+
+ }
+ // Manually ensure string is terminated
+ pcArray[sizeof(pcArray)-1] = '\0';
+ CFRelease(cfstr);
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Captured device %s is %s", pcHeader, pcArray);
+
+ return;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/MacOSX/usbserial_mosx.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,30 @@
+/*
+ * usbserial.h
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#ifndef _USBSERIAL_MOSX_H_
+#define _USBSERIAL_MOSX_H_
+
+typedef struct _intFace {
+ IOUSBInterfaceInterface245 **iface;
+ IOUSBDeviceInterface245 **dev;
+ UInt32 usbAddr;
+ UInt8 inPipeRef;
+ UInt8 outPipeRef;
+ UInt8 used;
+ UInt8 ready;
+ UInt16 vendorID;
+ UInt16 productID;
+ UInt8 class;
+ UInt8 subClass;
+ UInt8 protocol;
+} intrFace, *pIntrFace;
+
+#endif
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/usbserial.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/usbserial.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/USB/usbserial.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,34 @@
+/*
+ * usbserial.h
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#ifndef _USBSERIAL_H_
+#define _USBSERIAL_H_
+
+#include "Transport.h"
+
+// Open the base connection
+TrRv OpenUSB( DWORD lun, DWORD channel );
+// returns the number of conifguration descriptors
+TrRv GetConfigDescNumberUSB( DWORD lun, BYTE* pcconfigDescNb );
+// returns product and vendor ID for the USB device connected on LUN lun
+TrRv GetVendorAndProductIDUSB( DWORD lun, DWORD *vendorID, DWORD *productID );
+// Reads Class descriptor once the device has been successfulle opened
+// Can be called with pcdesc == NULL to find out the length
+TrRv GetClassDescUSB( DWORD lun, BYTE configDescNb, BYTE bdescType,
+ BYTE *pcdesc, BYTE *pcdescLength);
+// Sets connection to pipes
+TrRv SetupConnectionsUSB( DWORD lun, BYTE ConfigDescNb, BYTE interruptPipe);
+TrRv SetupUSB( DWORD lun, void* pBuffer, DWORD * pLength);
+TrRv WriteUSB( DWORD lun, DWORD length, BYTE *Buffer );
+TrRv ReadUSB( DWORD lun, DWORD *length, BYTE *Buffer );
+TrRv CloseUSB( DWORD lun );
+
+#endif
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1085 @@
+/*
+ * CCID.c
+ * ifd-CCID
+ *
+ * Created by JL on Sat Jun 28 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+#include <CoreFoundation/CoreFoundation.h>
+#include "global.h"
+
+#include "tools.h"
+#include "CCID.h"
+#include "CCIDprivate.h"
+#include "pcscdefines.h"
+#include "CCIDPropExt.h"
+
+
+CCIDReaderState CCIDReaderStates[PCSCLITE_MAX_CHANNELS];
+static BYTE bCCIDInitialised = 0;
+
+void CCIDParseDesc(BYTE * pcbuffer, CCIDClassDescriptor *classDesc)
+{
+
+ bcopy(pcbuffer, classDesc, sizeof(CCIDClassDescriptor));
+ // Correct endianness of relevant fields
+ classDesc->bcdCCID = CCIDToHostWord(classDesc->bcdCCID);
+ classDesc->dwProtocols = CCIDToHostLong(classDesc->dwProtocols);
+ classDesc->dwDefaultClock = CCIDToHostLong(classDesc->dwDefaultClock);
+ classDesc->dwMaximumClock = CCIDToHostLong(classDesc->dwMaximumClock);
+ classDesc->dwDataRate = CCIDToHostLong(classDesc->dwDataRate);
+ classDesc->dwMaxDataRate = CCIDToHostLong(classDesc->dwMaxDataRate);
+ classDesc->dwMaxIFSD = CCIDToHostLong(classDesc->dwMaxIFSD);
+ classDesc->dwSynchProtocols = CCIDToHostLong(classDesc->dwSynchProtocols);
+ classDesc->dwMechanical = CCIDToHostLong(classDesc->dwMechanical);
+ classDesc->dwFeatures = CCIDToHostLong(classDesc->dwFeatures);
+ classDesc->dwMaxCCIDMessageLength = CCIDToHostLong(classDesc->dwMaxCCIDMessageLength);
+ classDesc->wLcdLayout = CCIDToHostWord(classDesc->wLcdLayout);
+}
+
+void CCIDPrintDesc(CCIDClassDescriptor classDesc)
+{
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbLength = 0x%02X\n", classDesc.bLength);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbDescriptorType = 0x%02X\n", classDesc.bDescriptorType);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbcdCCID = 0x%04X\n", classDesc.bcdCCID);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbMaxSlotIndex = %d\n", classDesc.bMaxSlotIndex);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbVoltageSupport = 0x%02X\n", classDesc.bVoltageSupport);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwProtocols = 0x%08X\n", classDesc.dwProtocols);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwDefaultClock = %ld\n", classDesc.dwDefaultClock);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwMaximumClock = %ld\n", classDesc.dwMaximumClock);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbNumDataRatesSupported = %d\n", classDesc.bNumCockSupported);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwDataRate = %ld\n", classDesc.dwDataRate);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwMaxDataRate = %ld\n", classDesc.dwMaxDataRate);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbNumDataRatesSupported = %d\n", classDesc.bNumDataRatesSupported);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwMaxIFSD = %ld\n", classDesc.dwMaxIFSD);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwSynchProtocols = 0x%08X\n", classDesc.dwSynchProtocols);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwMechanical = 0x%08X\n", classDesc.dwMechanical);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwFeatures = 0x%08X\n", classDesc.dwFeatures);
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_CONF_ATR )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic conf. according to ATR");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_ACT )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic activation of ICC on insertion");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_VOLT )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic voltage selection");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_CLOCK )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic clock frequency change");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_BAUD )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic baud rate selection (freq, FI, DI)");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_PPS_PROP )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic parameter negociation (proprietary)");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_PPS_CUR )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic parameter negociation (current)");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_CLOCK_STOP )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Can set ICC in stop clock mode");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_NAD_NON_0 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Non 00 value for NAD suppported");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_IFSD )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic IFSD exchange as first exchange");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_IFSD )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic IFSD exchange as first exchange");
+ }
+ if ( classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_IFSD )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Automatic IFSD exchange as first exchange");
+ }
+ switch ( classDesc.dwFeatures & CCID_CLASS_FEAT_EXC_LEVEL_MASK )
+ {
+ case CCID_CLASS_FEAT_EXC_LEVEL_CHAR:
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Character level exchanges");
+ break;
+ case CCID_CLASS_FEAT_EXC_LEVEL_TPDU:
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t TPDU level exchanges");
+ break;
+ case CCID_CLASS_FEAT_EXC_LEVEL_SAPDU:
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Short APDU level exchanges");
+ break;
+ case CCID_CLASS_FEAT_EXC_LEVEL_LAPDU:
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\t\t Short and extended APDU level exchanges");
+ break;
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tdwMaxCCIDMessageLength = %ld\n", classDesc.dwMaxCCIDMessageLength);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbClassGetResponse = 0x%02X\n", classDesc.bClassGetResponse);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbClassEnvelope = 0x%02X\n", classDesc.bClassEnvelope);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\twLcdLayout = 0x%04X\n", classDesc.wLcdLayout);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbPINSupport = 0x%02X\n", classDesc.bPINSupport);
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "\tbMaxCCIDBusySlots = %d\n", classDesc.bMaxCCIDBusySlots);
+}
+
+
+// Parses the bStatus byte returned in a Bulk-IN
+// message to return bmICCStatus
+BYTE CCIDGetICCStatus(BYTE bStatus)
+{
+ return (((bStatus) & MASK_ICC_STATUS) >> OFFSET_ICC_STATUS);
+}
+// Gets a pointer to a user friendly message
+static const char* ICCStatusMessage[] =
+{
+ "ICC present and active",
+ "ICC present and inactive",
+ "No ICC",
+ "RFU"
+};
+const char *CCIDGetICCStatusMessage(BYTE bICCStatus)
+{
+ if (bICCStatus < (sizeof(ICCStatusMessage)/sizeof(char*)))
+ return ICCStatusMessage[bICCStatus];
+ return "";
+}
+// Parses the bStatus byte returned in a Bulk-IN
+// message to return bmCommandStatus
+BYTE CCIDGetCommandStatus(BYTE bStatus)
+{
+ return (((bStatus) & MASK_COMMAND_STATUS) >> OFFSET_COMMAND_STATUS);
+}
+static const char* CommandStatusMessage[] =
+{
+ "Success",
+ "Failed",
+ "Time extension required",
+ "RFU"
+};
+
+// Gets a pointer to a user friendly message
+const char *CCIDGetCommandStatusMessage(BYTE bCommandStatus)
+{
+ if (bCommandStatus < (sizeof(CommandStatusMessage)/sizeof(char*)))
+ return CommandStatusMessage[bCommandStatus];
+ return "";
+}
+
+CCIDRv CCID_OpenChannel(DWORD Lun, DWORD ChannelID)
+{
+ WORD wRdrLun;
+ TrRv rv;
+
+ if ( !bCCIDInitialised )
+ {
+ //Intialise structure
+ bzero(CCIDReaderStates, sizeof(CCIDReaderStates));
+ bCCIDInitialised = 1;
+ }
+
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ if ( CCIDReaderStates[wRdrLun].used)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun already used: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ CCIDReaderStates[wRdrLun].used = 1;
+ //++ SHOULD CHECK CHANNELID TO SEE WHICH TRANSPORT TO USE
+ //++ This is to support CCID readers over different transport
+ //++ mechanism (serial or even serial from PCMCIA)
+ CCIDReaderStates[wRdrLun].pTrFunctions = &TrFunctionTable[TrType_USB];
+ // Create an "alias" to the transport functions
+ TrFunctions *pTrFunctions = CCIDReaderStates[wRdrLun].pTrFunctions;
+ rv = pTrFunctions->Open(Lun, ChannelID);
+ if ( rv != TrRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+
+ BYTE bnbOfDesc;
+
+ rv = pTrFunctions->GetConfigDescNumber(Lun, &bnbOfDesc);
+ if ( rv != TrRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+ //+++ Configuration descriptor analysis could take place here.
+ //++ For now, use configuration descriptor 0
+ BYTE bSelectedConfDesc = 0;
+
+ BYTE pcbufferDesc[CCID_DESC_SIZE];
+ BYTE bbufferDescLength = sizeof(pcbufferDesc);
+ rv = pTrFunctions->GetClassDesc(Lun, bSelectedConfDesc, CCID_DESC_TYPE,
+ NULL, &bbufferDescLength);
+ if ( rv != TrRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+ if (bbufferDescLength != CCID_DESC_SIZE)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Incorrect Class Desc size %d ", bbufferDescLength);
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_CLASS_DESC_INVALID;
+ }
+ bbufferDescLength = sizeof(pcbufferDesc);
+ rv = pTrFunctions->GetClassDesc(Lun, bSelectedConfDesc, CCID_DESC_TYPE,
+ pcbufferDesc, &bbufferDescLength);
+ if ( rv != TrRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+ // Convenience pointer
+ CCIDClassDescriptor *pstClassDesc;
+ pstClassDesc = &(CCIDReaderStates[wRdrLun].classDesc);
+ CCIDParseDesc(pcbufferDesc, pstClassDesc);
+ CCIDPrintDesc(CCIDReaderStates[wRdrLun].classDesc);
+
+ // Initialise fields
+ CCIDReaderStates[wRdrLun].bMaxSlotIndex = pstClassDesc->bMaxSlotIndex;
+ CCIDReaderStates[wRdrLun].bMaxCCIDBusySlots = pstClassDesc->bMaxCCIDBusySlots;
+ CCIDReaderStates[wRdrLun].dwMaxCCIDMessageLength = pstClassDesc->dwMaxCCIDMessageLength;
+ CCIDReaderStates[wRdrLun].dwExchangeLevel = (pstClassDesc->dwFeatures)
+ & CCID_CLASS_FEAT_EXC_LEVEL_MASK;
+
+ // Make sure response struct is smaller than command struct
+ assert(sizeof(CCIDMessageBulkOut) >= sizeof(CCIDMessageBulkIn));
+ if ( CCIDReaderStates[wRdrLun].dwMaxCCIDMessageLength < sizeof(CCIDMessageBulkOut) )
+ {
+ // Can't do anything with this reader, its message length is even smaller
+ // than the size of a minimal command
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader dwMaxCCIDMessageLength property is too small: %d",
+ CCIDReaderStates[wRdrLun].dwMaxCCIDMessageLength);
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_UNSPECIFIED;
+
+ }
+ //+++ Interrupt pipes not supported, hence 0 in parameter
+ rv = pTrFunctions->SetupConnections(Lun, bSelectedConfDesc, 0);
+ if ( rv != TrRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+
+ rv = pTrFunctions->GetVendorAndProductID(Lun, & (CCIDReaderStates[wRdrLun].dwVendorID),
+ &(CCIDReaderStates[wRdrLun].dwProductID));
+ if ( rv != TrRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+ CCIDPropExt stCCIDPropExt;
+ rv = CCIDPropExtLookupExt(CCIDReaderStates[wRdrLun].dwVendorID,
+ CCIDReaderStates[wRdrLun].dwProductID,
+ &stCCIDPropExt);
+ if ( rv == CCIDRv_OK )
+ {
+ if ( stCCIDPropExt.OpenChannel != NULL )
+ {
+ rv = stCCIDPropExt.OpenChannel(Lun);
+ if ( rv != CCIDRv_OK )
+ {
+ CCIDReaderStates[wRdrLun].used = 0;
+ // Call close to reset USB structures
+ CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ return rv;
+ }
+ }
+ }
+
+ return CCIDRv_OK;
+}
+
+CCIDRv CCID_CloseChannel(DWORD Lun)
+{
+ WORD wRdrLun;
+ TrRv rv;
+
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ if ( !CCIDReaderStates[wRdrLun].used)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun of unused reader: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ // Close USB connection
+ rv = CCIDReaderStates[wRdrLun].pTrFunctions->Close(Lun);
+ // Clean-up the structure
+ bzero(&CCIDReaderStates[wRdrLun], sizeof(CCIDReaderState));
+ if ( rv != TrRv_OK )
+ {
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+
+ return CCIDRv_OK;
+
+}
+
+
+CCIDRv CCID_Exchange_Command(DWORD Lun, BYTE bMessageTypeCmd,
+ BYTE *abMessageSpecificCmd,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *pbMessageTypeResp,
+ BYTE *pbStatus, BYTE *pbError,
+ BYTE *pbMessageSpecificResp,
+ BYTE *abDataResp, DWORD *pdwDataRespLength,
+ BYTE bTimeExtRetry)
+{
+ CCIDMessageBulkOut *pstmessage;
+ CCIDMessageBulkIn *pstresponse;
+ WORD wSlot;
+ WORD wRdrLun;
+ TrRv trv = 0;
+ BYTE *pcBuffer;
+ DWORD dwRespLength;
+
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ if ( !CCIDReaderStates[wRdrLun].used)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun of unused reader: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ wSlot = LunToSlotNb(Lun);
+ if ( wSlot > CCIDReaderStates[wRdrLun].bMaxSlotIndex )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Slot Lun too large: %d", wSlot);
+ return CCIDRv_ERR_SLOT_LUN;
+ }
+ if ( CCIDReaderStates[wRdrLun].bCurrentCCIDBusySlots
+ >= CCIDReaderStates[wRdrLun].bMaxCCIDBusySlots )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Too many slots busy");
+ return CCIDRv_ERR_SLOTS_BUSY;
+ }
+
+ if ( CCIDReaderStates[wRdrLun].dwMaxCCIDMessageLength < dwDataCmdLength )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Command too long for reader");
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+
+ // Just to make sure buffer will be large enough for the response
+ assert(sizeof(CCIDMessageBulkOut) >= sizeof(CCIDMessageBulkIn));
+
+ // Malloc buffer of size of the message +maximum data for this slot
+ //+++ Could be malloced once and for all at the structure creation
+ pcBuffer = malloc(sizeof(CCIDMessageBulkOut)
+ + CCIDReaderStates[wRdrLun].dwMaxCCIDMessageLength);
+ if ( pcBuffer == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Malloc failed");
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ // See if this is a retry after a time extension request
+ // For T=0, this means that we just have to jump to the read
+ // and not attempt to write
+ if (!bTimeExtRetry)
+ {
+ // Not a retry, send the command
+ //++ bCurrentCCIDBusySlots should be here
+
+ pstmessage = (CCIDMessageBulkOut *) pcBuffer;
+ pstmessage->bMessageType = bMessageTypeCmd;
+ pstmessage->dwLength = HostToCCIDLong(dwDataCmdLength);
+ pstmessage->bSlot = wSlot;
+ pstmessage->bSeq = CCIDReaderStates[wRdrLun].bSeq++;
+ pstmessage->bMessageSpecific1 = abMessageSpecificCmd[0];
+ pstmessage->bMessageSpecific2 = abMessageSpecificCmd[1];
+ pstmessage->bMessageSpecific3 = abMessageSpecificCmd[2];
+ // Copy the command data
+ bcopy(abDataCmd, pcBuffer+sizeof(CCIDMessageBulkOut), dwDataCmdLength);
+
+ trv = CCIDReaderStates[wRdrLun].pTrFunctions->Write(Lun,
+ sizeof(CCIDMessageBulkOut) +
+ dwDataCmdLength,
+ pcBuffer);
+ }
+ bzero(pcBuffer, sizeof(CCIDMessageBulkOut)+dwDataCmdLength);
+ if ( trv != TrRv_OK )
+ {
+ free(pcBuffer);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+ dwRespLength = CCIDReaderStates[wRdrLun].dwMaxCCIDMessageLength;
+ trv = CCIDReaderStates[wRdrLun].pTrFunctions->Read(Lun, &dwRespLength,
+ pcBuffer);
+ if ( trv != TrRv_OK )
+ {
+ free(pcBuffer);
+ return CCIDRv_ERR_TRANSPORT_ERROR;
+ }
+ if ( dwRespLength < sizeof(CCIDMessageBulkIn) )
+ {
+ free(pcBuffer);
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader returned too little data");
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ pstresponse = (CCIDMessageBulkIn *) pcBuffer;
+ // Now parse the returned value and copy it in the parameters
+ *pbMessageTypeResp = pstresponse->bMessageType;
+ *pbStatus = pstresponse->bStatus;
+ *pbError = pstresponse->bError;
+ *pbMessageSpecificResp = pstresponse->bMessageSpecific;
+ dwRespLength -= sizeof(CCIDMessageBulkIn);
+ BYTE bSeq = pstresponse->bSeq;
+ // Check if the returned sequence byte matches that was sent
+ if ( bSeq != ((BYTE)(CCIDReaderStates[wRdrLun].bSeq-1)))
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "CCID sequence byte returned by reader is wrong %d instead of %d",
+ bSeq, (CCIDReaderStates[wRdrLun].bSeq-1));
+ return CCIDRv_ERR_WRONG_SEQUENCE;
+ }
+
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "ICCStats: %s",
+ CCIDGetICCStatusMessage(CCIDGetICCStatus(*pbStatus)));
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "CmdStatus: %s",
+ CCIDGetCommandStatusMessage(CCIDGetCommandStatus(*pbStatus)));
+ // Check for common errors
+ BYTE bICCStatus = CCIDGetCommandStatus(*pbStatus) ;
+ if ( CCIDGetCommandStatus(*pbStatus) == CCID_CMD_STATUS_TIME_REQ )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Reader has requested time extension");
+ return CCIDRv_ERR_TIME_REQUEST;
+ }
+ // Modify return values only if we did not get a Time Request
+ if (abDataResp != NULL)
+ {
+ if ( dwRespLength > *pdwDataRespLength )
+ {
+ dwRespLength = *pdwDataRespLength;
+ }
+ bcopy(pcBuffer + sizeof(CCIDMessageBulkIn), abDataResp, dwRespLength);
+ }
+ *pdwDataRespLength = dwRespLength;
+
+ bzero(pcBuffer, sizeof(CCIDMessageBulkOut)+dwRespLength);
+ free(pcBuffer);
+
+ if ( CCIDGetCommandStatus(*pbStatus) == CCID_CMD_STATUS_FAILED )
+ {
+ // For all values pbICCStatus but RFU:
+ if ( (bICCStatus != CCID_ICC_STATUS_RFU)
+ &&
+ (*pbError == CCID_ERR_CMD_SLOT_BUSY))
+ return CCIDRv_ERR_SLOT_BUSY;
+
+ if ( bICCStatus == CCID_ICC_STATUS_ABSENT )
+ {
+ if ( *pbError == CCID_ERR_5 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Command to inexistant slot");
+ return CCIDRv_ERR_NO_SUCH_SLOT;
+ }
+ if ( *pbError == CCID_ERR_ICC_MUTE )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Card Absent");
+ return CCIDRv_ERR_CARD_ABSENT;
+ }
+ }
+ if ( bICCStatus == CCID_ICC_STATUS_INACTIVE )
+ {
+ if ( *pbError == CCID_ERR_HW_ERROR )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Hardware Error");
+ return CCIDRv_ERR_HW_ERROR;
+ }
+ if ( *pbError == CCID_ERR_CMD_ABORTED )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Command aborted");
+ return CCIDRv_ERR_CMD_ABORTED;
+ }
+ if ( *pbError == CCID_ERR_BUSY_WITH_AUTO_SEQUENCE )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Busy with auto sequence");
+ return CCIDRv_ERR_BUSY_AUTO_SEQ;
+ }
+ }
+
+ if ( (bICCStatus == CCID_ICC_STATUS_ACTIVE)
+ &&
+ (*pbError == CCID_ERR_0)
+ )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Command unsupported");
+ return CCIDRv_ERR_UNSUPPORTED_CMD;
+ }
+
+ // Return an unspecified error code
+ // but higher layers might modify it
+ return CCIDRv_ERR_PRIVATE_ERROR;
+
+ }
+ return CCIDRv_OK;
+
+}
+
+
+CCIDRv CCID_IccPowerOn(DWORD Lun, BYTE *abDataResp, DWORD *pdwDataRespLength)
+{
+ CCIDRv rv;
+ WORD wRdrLun;
+ BYTE bMessageTypeResp;
+ BYTE bStatus;
+ BYTE bError;
+ BYTE bMessageSpecificResp;
+ BYTE abMessageSpecificCmd[3] = "\x00\x00\x00";
+ DWORD dwDataRespLengthBuffer;
+
+ // Save value of the buffer size
+ dwDataRespLengthBuffer = *pdwDataRespLength;
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ if ( !CCIDReaderStates[wRdrLun].used)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun of unused reader: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+
+ // Check if autopower is supported by CCID
+ if (CCIDReaderStates[wRdrLun].classDesc.dwFeatures & CCID_CLASS_FEAT_AUTO_VOLT )
+ {
+ abMessageSpecificCmd[0] = 0x00;
+ }
+ else
+ {
+ // Power-up at 5V
+ //+++ For the proper Power-Up sequence, see 7816-3:1997 section 4.2.2
+ abMessageSpecificCmd[0] = 0x01;
+ }
+ rv = CCID_Exchange_Command(Lun, PC_to_RDR_IccPowerOn,
+ abMessageSpecificCmd,
+ (BYTE *)"", 0,
+ &bMessageTypeResp,
+ &bStatus, &bError,
+ &bMessageSpecificResp,
+ abDataResp, pdwDataRespLength, 0);
+ if ( rv == CCIDRv_ERR_PRIVATE_ERROR )
+ {
+ // ICC Power On has a few specific error cases
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_INACTIVE )
+ {
+ if ( bError == CCID_ERR_7 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Power On mode not supported: %02X", abMessageSpecificCmd[0]);
+ return CCIDRv_ERR_POWERON_MODE_UNSUPPORTED;
+ }
+
+ if ( bError == CCID_ERR_XFR_PARITY_ERROR )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "ATR Parity error");
+ return CCIDRv_ERR_ATR_PARITY_ERROR;
+ }
+
+ if ( bError == CCID_ERR_BAD_ATR_TS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong TS in ATR");
+ return CCIDRv_ERR_BAD_ATR_TS;
+ }
+
+ if ( bError == CCID_ERR_BAD_ATR_TCK )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong TCK in ATR");
+ return CCIDRv_ERR_BAD_ATR_TCK;
+ }
+
+ if ( bError == CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Protocol not supported");
+ return CCIDRv_ERR_PROTOCOL_NOT_SUPPORTED;
+ }
+
+ if ( bError == CCID_ERR_ICC_CLASS_NOT_SUPPORTED )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "ICC Class not supported");
+ return CCIDRv_ERR_CLASS_NOT_SUPPORTED;
+ }
+
+ }
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_ABSENT)
+ {
+ return CCIDRv_ERR_CARD_ABSENT;
+ }
+ // Might be a proprietary error
+ // Check if there is customed extension
+ CCIDPropExt stCCIDPropExt;
+ rv = CCIDPropExtLookupExt(CCIDReaderStates[wRdrLun].dwVendorID,
+ CCIDReaderStates[wRdrLun].dwProductID,
+ &stCCIDPropExt);
+ if ( rv != CCIDRv_OK )
+ {
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ if ( stCCIDPropExt.PowerOn != NULL )
+ {
+ // Restore value of buffer
+ *pdwDataRespLength = dwDataRespLengthBuffer;
+ rv = stCCIDPropExt.PowerOn(Lun, abDataResp, pdwDataRespLength,
+ bStatus, bError);
+ }
+ }
+ if ( rv != CCIDRv_OK )
+ {
+ return rv;
+ }
+ if ( bMessageTypeResp != RDR_to_PC_DataBlock )
+ {
+ return CCIDRv_ERR_WRONG_MESG_RESP_TYPE;
+ }
+ return CCIDRv_OK;
+}
+
+CCIDRv CCID_IccPowerOff(DWORD Lun, BYTE *pbClockStatus)
+{
+ CCIDRv rv;
+ WORD wRdrLun;
+ BYTE bMessageTypeResp;
+ BYTE bStatus;
+ BYTE bError;
+ BYTE bMessageSpecificResp;
+ BYTE abMessageSpecificCmd[3] = "\x00\x00\x00";
+ DWORD dwDataRespLength;
+
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ rv = CCID_Exchange_Command(Lun, PC_to_RDR_IccPowerOff,
+ abMessageSpecificCmd,
+ (BYTE *)"", 0,
+ &bMessageTypeResp,
+ &bStatus, &bError,
+ &bMessageSpecificResp,
+ NULL, &dwDataRespLength, 0);
+ if ( rv == CCIDRv_ERR_PRIVATE_ERROR )
+ {
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ if ( rv != CCIDRv_OK )
+ {
+ return rv;
+ }
+ if ( bMessageTypeResp != RDR_to_PC_SlotStatus )
+ {
+ return CCIDRv_ERR_WRONG_MESG_RESP_TYPE;
+ }
+ *pbClockStatus = bMessageSpecificResp;
+ return CCIDRv_OK;
+
+}
+
+CCIDRv CCID_GetSlotStatus(DWORD Lun, BYTE *pbStatus, BYTE *pbClockStatus)
+{
+ CCIDRv rv;
+ WORD wRdrLun;
+ BYTE bMessageTypeResp;
+ BYTE bStatus;
+ BYTE bError;
+ BYTE bMessageSpecificResp;
+ BYTE abMessageSpecificCmd[3] = "\x00\x00\x00";
+ DWORD dwDataRespLength;
+
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ rv = CCID_Exchange_Command(Lun, PC_to_RDR_GetSlotStatus,
+ abMessageSpecificCmd,
+ (BYTE *)"", 0,
+ &bMessageTypeResp,
+ &bStatus, &bError,
+ &bMessageSpecificResp,
+ NULL, &dwDataRespLength, 0);
+ if ( rv == CCIDRv_ERR_PRIVATE_ERROR )
+ {
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ if ( rv != CCIDRv_OK )
+ {
+ return rv;
+ }
+ if ( bMessageTypeResp != RDR_to_PC_SlotStatus )
+ {
+ return CCIDRv_ERR_WRONG_MESG_RESP_TYPE;
+ }
+ *pbClockStatus = bMessageSpecificResp;
+ *pbStatus = bStatus;
+ return CCIDRv_OK;
+
+}
+CCIDRv CCID_XfrBlock(DWORD Lun, BYTE bBWI,
+ DWORD dwRequestedProtocol,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength)
+{
+ WORD wRdrLun;
+ wRdrLun = LunToReaderLun(Lun);
+
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ if ( !CCIDReaderStates[wRdrLun].used)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun of unused reader: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+
+ switch ( CCIDReaderStates[wRdrLun].dwExchangeLevel )
+ {
+ case CCID_CLASS_FEAT_EXC_LEVEL_CHAR:
+ case CCID_CLASS_FEAT_EXC_LEVEL_LAPDU:
+ return CCIDRv_ERR_READER_LEVEL_UNSUPPORTED;
+ case CCID_CLASS_FEAT_EXC_LEVEL_TPDU:
+ //+++ 1 for T=1 should be replaced by a #define
+ if (dwRequestedProtocol == 1)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Protocol type of card (T=1) not supported by this driver for this type of reader (TPDU)");
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "An APDU-level reader should be used");
+ return CCIDRv_ERR_READER_LEVEL_UNSUPPORTED;
+ }
+ return CCID_XfrBlockTPDU(Lun, bBWI,
+ abDataCmd, dwDataCmdLength,
+ abDataResp, pdwDataRespLength);
+ case CCID_CLASS_FEAT_EXC_LEVEL_SAPDU:
+ return CCID_XfrBlockSAPDU(Lun, bBWI,
+ abDataCmd, dwDataCmdLength,
+ abDataResp, pdwDataRespLength);
+ }
+ return CCIDRv_ERR_UNSPECIFIED;
+}
+
+
+CCIDRv CCID_XfrBlockSAPDU(DWORD Lun, BYTE bBWI,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength)
+{
+ CCIDRv rv;
+ WORD wRdrLun;
+ BYTE bMessageTypeResp;
+ BYTE bStatus;
+ BYTE bError;
+ BYTE bMessageSpecificResp;
+ BYTE abMessageSpecificCmd[3] = "\x00\x00\x00";
+ abMessageSpecificCmd[0] = bBWI;
+ // For Short APDU, no need to change abMessageSpecificCmd[1,2]
+ // as they are RFU at the moment
+
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ if ( !CCIDReaderStates[wRdrLun].used)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "Reader Lun of unused reader: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+
+ //+++ CCID spec not clear on what to do for APDUs where
+ // length(APDU)+sizeof(CCIDMessageBulkOut) > dwMaxCCIDMessageLength
+ // so we just reject it
+ if ( CCIDReaderStates[wRdrLun].classDesc.dwMaxCCIDMessageLength
+ < (dwDataCmdLength+sizeof(CCIDMessageBulkOut)) )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical,
+ "dwMaxCCIDMessageLength is too small for supplied data");
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+
+ rv = CCIDRv_ERR_UNSPECIFIED;
+ BYTE bTimeExtRetry = 0;
+ do
+ {
+ rv = CCID_Exchange_Command(Lun, PC_to_RDR_XfrBlock,
+ abMessageSpecificCmd,
+ abDataCmd, dwDataCmdLength,
+ &bMessageTypeResp,
+ &bStatus, &bError,
+ &bMessageSpecificResp,
+ abDataResp, pdwDataRespLength, bTimeExtRetry);
+ bTimeExtRetry = 1;
+ }
+ while (rv == CCIDRv_ERR_TIME_REQUEST);
+
+ if ( rv == CCIDRv_ERR_PRIVATE_ERROR )
+ {
+ // ICC Power On has a few specific error cases
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_INACTIVE )
+ {
+ if ( bError == CCID_ERR_7 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Power On mode not supported: %02X", abMessageSpecificCmd[0]);
+ return CCIDRv_ERR_POWERON_MODE_UNSUPPORTED;
+ }
+
+ if ( bError == CCID_ERR_XFR_PARITY_ERROR )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Exchange Parity error");
+ return CCIDRv_ERR_XFR_PARITY_ERROR;
+ }
+
+ if ( bError == CCID_ERR_XFR_OVERRUN )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "XFR overrun");
+ return CCIDRv_ERR_XFR_OVERRUN;
+ }
+
+ if ( bError == CCID_ERR_1 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong dwLength");
+ return CCIDRv_ERR_XFR_WRONG_DWLENGTH;
+ }
+
+ if ( bError == CCID_ERR_8 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong dwLevelParameter");
+ return CCIDRv_ERR_XFR_WRONG_DWLEVELPARAMETER;
+ }
+
+ }
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_ABSENT)
+ {
+ return CCIDRv_ERR_CARD_ABSENT;
+ }
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ if ( rv != CCIDRv_OK )
+ {
+ return rv;
+ }
+ if ( bMessageTypeResp != RDR_to_PC_DataBlock )
+ {
+ return CCIDRv_ERR_WRONG_MESG_RESP_TYPE;
+ }
+
+ return CCIDRv_OK;
+
+}
+
+
+
+
+/*
+ CCIDRv CCID_GetParameters(DWORD Lun,
+ BYTE *pbProtocolNum,
+ BYTE *abProtocolDataStructure,
+ DWORD *dwProtocolDataStructureLength);
+CCIDRv CCID_ResetParameters(DWORD Lun,
+ BYTE *pbProtocolNum,
+ BYTE *abProtocolDataStructure,
+ DWORD *dwProtocolDataStructureLength);
+CCIDRv CCID_SetParameter(DWORD Lun,
+ BYTE bProtocolNum,
+ BYTE *abSetProtocolDataStructure,
+ DWORD dwSetProtocolDataStructureLength,
+ BYTE *pbProtocolNum,
+ BYTE *abProtocolDataStructure,
+ DWORD *dwProtocolDataStructureLength);
+*/
+
+CCIDRv CCID_Escape(DWORD Lun,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength,
+ BYTE *pbErrorSpecific)
+{
+ CCIDRv rv;
+ BYTE bMessageTypeResp;
+ BYTE bStatus;
+ BYTE bError;
+ BYTE bMessageSpecificResp;
+ *pbErrorSpecific = 0;
+ rv = CCID_Exchange_Command(Lun, PC_to_RDR_Escape,
+ (BYTE *)"\x00\x00\x00",
+ abDataCmd, dwDataCmdLength,
+ &bMessageTypeResp,
+ &bStatus, &bError,
+ &bMessageSpecificResp,
+ abDataResp, pdwDataRespLength, 0);
+ if ( rv == CCIDRv_ERR_PRIVATE_ERROR )
+ {
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_ACTIVE )
+ {
+ *pbErrorSpecific = bError;
+ return CCIDRv_ERR_MANUFACTURER_ERROR;
+ }
+
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ if ( rv != CCIDRv_OK )
+ {
+ return rv;
+ }
+ if ( bMessageTypeResp != RDR_to_PC_Escape )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong response type from reader");
+ return CCIDRv_ERR_WRONG_MESG_RESP_TYPE;
+ }
+
+ return CCIDRv_OK;
+}
+
+//++ TPDU mode will only work with T=0 cards
+CCIDRv CCID_XfrBlockTPDU(DWORD Lun, BYTE bBWI,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength)
+{
+ DWORD dwDataRespLengthBuffer;
+ CCIDRv rv;
+ BYTE abGetResponse[] = {0x00, 0xC0, 0x00, 0x00, 0x00};
+ BYTE bLe;
+ DWORD dwAPDULength;
+
+ // Save the value of the buffer length in a get response needs to be run
+ dwDataRespLengthBuffer = *pdwDataRespLength;
+
+ //++ For now, use the SAPDU call
+ rv = CCID_XfrBlockSAPDU(Lun, bBWI,
+ abDataCmd, dwDataCmdLength,
+ abDataResp, pdwDataRespLength);
+
+ if ( rv == CCIDRv_OK )
+ {
+ // Check if we did not just get a 4-byte Case 0 APDU
+ if ( dwDataCmdLength < 5 )
+ {
+ // No Lc was provided
+ return rv;
+ }
+ //++ This will not work for extended APDUs
+ // Check if we received a fully qualified APDU Case 4 APDU
+ // Size of the command should be
+ // CLA + INS + P1 + P2 + Lc + value(Lc) + Le
+ dwAPDULength = 1 + 1 + 1 + 1 + 1 + abDataCmd[4] + 1;
+ if ( dwDataCmdLength == dwAPDULength )
+ {
+ bLe = abDataCmd[dwAPDULength-1];
+ // This is really a Case 4
+ // Check if a Get response should be placed
+ // Case 4S.3 : "Command accepted with information added"
+ if ( (*pdwDataRespLength == 2)
+ && (abDataResp[0] = 0x61))
+ {
+ // Card sent a 61 Lx
+ // Send get response with P3 = min(Le, Lx)
+ // minimum is a bit odd as L? = 00 means 256 (0x100)
+ if ( bLe == 0x00 )
+ {
+ // abDataResp[1] can only be smaller that bLe
+ // so change value before the test
+ bLe = abDataResp[1];
+ }
+ if ( abDataResp[1] == 0x00 )
+ {
+ // abDataResp[1] can only be smaller that bLe
+ // so change value before the test
+ abDataResp[1] = bLe;
+ }
+ abGetResponse[4] = (bLe < abDataResp[1]) ? bLe: abDataResp[1];
+ // Set-up buffer response to initial value
+ *pdwDataRespLength = dwDataRespLengthBuffer;
+ rv = CCID_XfrBlockSAPDU(Lun, bBWI,
+ abGetResponse, sizeof(abGetResponse),
+ abDataResp, pdwDataRespLength);
+ goto end;
+ }
+ // Case 4S.2 : "Command accepted"
+ if ( (*pdwDataRespLength == 2)
+ && (abDataResp[0] = 0x90)
+ && (abDataResp[0] = 0x00))
+ {
+ // Card sent a 9000
+ // Send a Get Response with the length
+ // included in the APDU
+ abGetResponse[4] = bLe;
+ // Set-up buffer response to initial value
+ *pdwDataRespLength = dwDataRespLengthBuffer;
+ rv = CCID_XfrBlockSAPDU(Lun, bBWI,
+ abGetResponse, sizeof(abGetResponse),
+ abDataResp, pdwDataRespLength);
+ }
+ }
+ }
+end:
+ return rv;
+}
+
+/*
+
+ CCIDRv CCID_IccClock(DWORD Lun, BYTE bClockCommand,
+ BYTE *pbClockStatus);
+ CCIDRv CCID_T0APDU(DWORD Lun, BYTE bmChanges, BYTE bClassGetResponse
+ BYTE bClassEnvelope,
+ BYTE *pbClockStatus);
+ // CCID_Secure IS CURRENTLY NOT SUPPORTED
+ // FUNCTION PROTOTYPE WILL CHANGE WHEN IT IS
+ CCIDRv CCID_Secure(DWORD Lun);
+ CCIDRv CCID_Mechanical(DWORD Lun, BYTE bFunction,
+ BYTE *pbClockStatus);
+ CCIDRv CCID_Abort(DWORD Lun, BYTE *pbClockStatus);
+ CCIDRv CCID_SetDataRateAndClockFrequency(DWORD Lun,
+ DWORD dwClockFrequencyCmd,
+ DWORD dwDataRateCmd,
+ DWORD *pdwClockFrequencyResp,
+ DWORD *pdwDataRateResp);
+*/
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCID.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,377 @@
+/*
+ *
+ * Created by JL Giraud <jlgiraud at mac.com>.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#ifndef __CCID_H__
+#define __CCID_H__
+#include <CoreFoundation/CoreFoundation.h>
+#include "wintypes.h"
+#include "pcscdefines.h"
+#include "transport.h"
+
+#define CCID_DESC_TYPE (0x21)
+#define CCID_DESC_SIZE (0x36)
+// Data strutuctures definitions
+typedef struct
+{
+ UInt8 bLength __attribute__ ((packed));
+ UInt8 bDescriptorType __attribute__ ((packed));
+ UInt16 bcdCCID __attribute__ ((packed));
+ UInt8 bMaxSlotIndex __attribute__ ((packed));
+ UInt8 bVoltageSupport __attribute__ ((packed));
+ UInt32 dwProtocols __attribute__ ((packed));
+ UInt32 dwDefaultClock __attribute__ ((packed));
+ UInt32 dwMaximumClock __attribute__ ((packed));
+ UInt8 bNumCockSupported __attribute__ ((packed));
+ UInt32 dwDataRate __attribute__ ((packed));
+ UInt32 dwMaxDataRate __attribute__ ((packed));
+ UInt8 bNumDataRatesSupported __attribute__ ((packed));
+ UInt32 dwMaxIFSD __attribute__ ((packed));
+ UInt32 dwSynchProtocols __attribute__ ((packed));
+ UInt32 dwMechanical __attribute__ ((packed));
+ UInt32 dwFeatures __attribute__ ((packed));
+ UInt32 dwMaxCCIDMessageLength __attribute__ ((packed));
+ UInt8 bClassGetResponse __attribute__ ((packed));
+ UInt8 bClassEnvelope __attribute__ ((packed));
+ UInt16 wLcdLayout __attribute__ ((packed));
+ UInt8 bPINSupport __attribute__ ((packed));
+ UInt8 bMaxCCIDBusySlots __attribute__ ((packed));
+} CCIDClassDescriptor;
+
+
+#define OFFSET_bLength 0
+#define OFFSET_bDescriptorType 1
+#define OFFSET_bcdCCID 2
+#define OFFSET_bMaxSlotIndex 4
+#define OFFSET_bVoltageSupport 5
+#define OFFSET_dwProtocols 6
+#define OFFSET_dwDefaultClock 10
+#define OFFSET_dwMaximumClock 14
+#define OFFSET_bNumCockSupported 18
+#define OFFSET_dwDataRate 19
+#define OFFSET_dwMaxDataRate 23
+#define OFFSET_bNumDataRatesSupported 27
+#define OFFSET_dwMaxIFSD 28
+#define OFFSET_dwSynchProtocols 32
+#define OFFSET_dwMechanical 36
+#define OFFSET_dwFeatures 40
+#define OFFSET_dwMaxCCIDMessageLength 44
+#define OFFSET_bClassGetResponse 48
+#define OFFSET_bClassEnvelope 49
+#define OFFSET_wLcdLayout 50
+#define OFFSET_bPINSupport 52
+#define OFFSET_bMaxCCIDBusySlots 53
+
+
+/*
+ From CCID spec:
+ offset, name, size
+ 0 bLength 1
+ 1 bDescriptorType 1
+ 2 bcdCCID 2
+ 4 bMaxSlotIndex 1
+ 5 bVoltageSupport 1
+ 6 dwProtocols 4
+ 10 dwDefaultClock 4
+ 14 dwMaximumClock 4
+ 18 bNumCockSupported 1
+ 19 dwDataRate 4
+ 23 dwMaxDataRate 4
+ 27 bNumDataRatesSupported 1
+ 28 dwMaxIFSD 4
+ 32 dwSynchProtocols 4
+ 36 dwMechanical 4
+ 40 dwFeatures 4
+ 44 dwMaxCCIDMessageLength 4
+ 48 bClassGetResponse 1
+ 49 bClassEnvelope 1
+ 50 wLcdLayout 2
+ 52 bPINSupport 1
+ 53 bMaxCCIDBusySlots 1
+
+ */
+
+
+// Standard CCID message descriptor
+typedef struct
+{
+ BYTE bMessageType __attribute__ ((packed));
+ DWORD dwLength __attribute__ ((packed));
+ BYTE bSlot __attribute__ ((packed));
+ BYTE bSeq __attribute__ ((packed));
+ BYTE bMessageSpecific1 __attribute__ ((packed));
+ BYTE bMessageSpecific2 __attribute__ ((packed));
+ BYTE bMessageSpecific3 __attribute__ ((packed));
+} CCIDMessageBulkOut;
+
+typedef struct
+{
+ BYTE bMessageType __attribute__ ((packed));
+ DWORD dwLength __attribute__ ((packed));
+ BYTE bSlot __attribute__ ((packed));
+ BYTE bSeq __attribute__ ((packed));
+ BYTE bStatus __attribute__ ((packed));
+ BYTE bError __attribute__ ((packed));
+ BYTE bMessageSpecific __attribute__ ((packed));
+} CCIDMessageBulkIn;
+
+#define CCID_CLASS_PROTOCOL_T0 0x00000001
+#define CCID_CLASS_PROTOCOL_T1 0x00000002
+
+
+
+// Related to dwFeatures in Class Desc.
+#define CCID_CLASS_FEAT_AUTO_CONF_ATR 0x00000002
+#define CCID_CLASS_FEAT_AUTO_ACT 0x00000004
+#define CCID_CLASS_FEAT_AUTO_VOLT 0x00000008
+#define CCID_CLASS_FEAT_AUTO_CLOCK 0x00000010
+#define CCID_CLASS_FEAT_AUTO_BAUD 0x00000020
+#define CCID_CLASS_FEAT_AUTO_PPS_PROP 0x00000040
+#define CCID_CLASS_FEAT_AUTO_PPS_CUR 0x00000080
+#define CCID_CLASS_FEAT_CLOCK_STOP 0x00000100
+#define CCID_CLASS_FEAT_NAD_NON_0 0x00000200
+#define CCID_CLASS_FEAT_AUTO_IFSD 0x00000400
+// MASk to get value of Exchange level
+#define CCID_CLASS_FEAT_EXC_LEVEL_MASK 0x00070000
+#define CCID_CLASS_FEAT_EXC_LEVEL_CHAR 0x00000000
+#define CCID_CLASS_FEAT_EXC_LEVEL_TPDU 0x00010000
+#define CCID_CLASS_FEAT_EXC_LEVEL_SAPDU 0x00020000
+#define CCID_CLASS_FEAT_EXC_LEVEL_LAPDU 0x00040000
+
+
+// Used to store the state of a slot for a reader
+typedef struct {
+ DWORD dwProtocol;
+ DWORD nATRLength;
+ UCHAR pcATRBuffer[MAX_ATR_SIZE];
+ UCHAR bPowerFlags;
+} CCIDSlotState;
+
+typedef struct {
+ BYTE used;
+ CCIDClassDescriptor classDesc;
+ TrFunctions *pTrFunctions;
+ BYTE bSeq;
+ BYTE bMaxSlotIndex;
+ BYTE bMaxCCIDBusySlots;
+ BYTE bCurrentCCIDBusySlots;
+ DWORD dwProductID;
+ DWORD dwVendorID;
+ DWORD dwMaxCCIDMessageLength;
+ // Use this instead of class Desc as it maybe
+ // modified in initialisation of some readers
+ DWORD dwExchangeLevel;
+ CCIDSlotState *slotStates;
+} tIo;
+// Used to store the state of a reader (per reader Lun)
+typedef struct {
+ BYTE used;
+ CCIDClassDescriptor classDesc;
+ TrFunctions *pTrFunctions;
+ BYTE bSeq;
+ BYTE bMaxSlotIndex;
+ BYTE bMaxCCIDBusySlots;
+ BYTE bCurrentCCIDBusySlots;
+ DWORD dwProductID;
+ DWORD dwVendorID;
+ DWORD dwMaxCCIDMessageLength;
+ // Use this instead of class Desc as it maybe
+ // modified in initialisation of some readers
+ DWORD dwExchangeLevel;
+ CCIDSlotState *slotStates;
+} CCIDReaderState;
+
+
+// values of bMessageType
+#define PC_to_RDR_IccPowerOn 0x62
+#define PC_to_RDR_IccPowerOff 0x63
+#define PC_to_RDR_GetSlotStatus 0x65
+#define PC_to_RDR_XfrBlock 0x6F
+#define PC_to_RDR_GetParameters 0x6C
+#define PC_to_RDR_ResetParameters 0x6D
+#define PC_to_RDR_SetParameter 0x61
+#define PC_to_RDR_Escape 0x6B
+#define PC_to_RDR_IccClock 0x6E
+#define PC_to_RDR_T0APDU 0x6A
+#define PC_to_RDR_Secure 0x69
+#define PC_to_RDR_Mechanical 0x71
+#define PC_to_RDR_Abort 0x72
+#define PC_to_RDR_SetDataRateAndClockFrequency 0x73
+#define RDR_to_PC_DataBlock 0x80
+#define RDR_to_PC_SlotStatus 0x81
+#define RDR_to_PC_Parameters 0x82
+#define RDR_to_PC_Escape 0x83
+#define RDR_to_PC_DataRateAndClockFrequency 0x84
+
+typedef enum {
+ CCIDRv_OK = 0x00,
+ CCIDRv_ERR_UNSPECIFIED = 0x01,
+ CCIDRv_ERR_NO_IMPLEMENTED = 0x02,
+ CCIDRv_ERR_READER_LUN = 0x03,
+ CCIDRv_ERR_SLOT_LUN = 0x04,
+ CCIDRv_ERR_SLOTS_BUSY = 0x05,
+ CCIDRv_ERR_CLASS_DESC_INVALID = 0x06,
+ CCIDRv_ERR_TRANSPORT_ERROR = 0x07,
+ CCIDRv_ERR_VALUE_NOT_FOUND = 0x08,
+ CCIDRv_ERR_WRONG_MESG_RESP_TYPE = 0x09,
+ CCIDRv_ERR_TIME_REQUEST = 0x0A,
+ CCIDRv_ERR_NO_SUCH_SLOT = 0x0B,
+ CCIDRv_ERR_UNSUPPORTED_CMD = 0x0C,
+ CCIDRv_ERR_SLOT_BUSY ,
+ //CCIDRv_ERR_NO_ICC_PRESENT ,
+ CCIDRv_ERR_CARD_ABSENT ,
+ CCIDRv_ERR_HW_ERROR ,
+ CCIDRv_ERR_CMD_ABORTED ,
+ CCIDRv_ERR_BUSY_AUTO_SEQ ,
+ CCIDRv_ERR_POWERON_MODE_UNSUPPORTED ,
+ CCIDRv_ERR_ICC_MUTE ,
+ CCIDRv_ERR_ATR_PARITY_ERROR ,
+ CCIDRv_ERR_BAD_ATR_TS ,
+ CCIDRv_ERR_BAD_ATR_TCK ,
+ CCIDRv_ERR_PROTOCOL_NOT_SUPPORTED ,
+ CCIDRv_ERR_CLASS_NOT_SUPPORTED ,
+ CCIDRv_ERR_MANUFACTURER_ERROR ,
+ CCIDRv_ERR_READER_LEVEL_UNSUPPORTED ,
+ CCIDRv_ERR_XFR_PARITY_ERROR ,
+ CCIDRv_ERR_XFR_OVERRUN ,
+ CCIDRv_ERR_XFR_WRONG_DWLENGTH ,
+ CCIDRv_ERR_XFR_WRONG_DWLEVELPARAMETER ,
+ CCIDRv_ERR_WRONG_SEQUENCE ,
+ // CCIDRv_ERR_
+ // CCIDRv_ERR_
+ // Error code below means that higher CCID layer
+ // should try to parse the status and error
+ // returned by the reder.
+ // This code should not be returned by any
+ // non private CCID function
+ CCIDRv_ERR_PRIVATE_ERROR
+} CCIDRv;
+
+
+
+void CCIDParseDesc(BYTE * pcbuffer, CCIDClassDescriptor *classDesc);
+void CCIDPrintDesc(CCIDClassDescriptor classDesc);
+
+// Parses the bStatus byte returned in a Bulk-IN
+// message to return bmICCStatus
+BYTE CCIDGetICCStatus(BYTE bStatus);
+// Gets a pointer to a user friendly message
+const char *CCIDGetICCStatusMessage(BYTE bICCStatus);
+// Parses the bStatus byte returned in a Bulk-IN
+// message to return bmCommandStatus
+BYTE CCIDGetCommandStatus(BYTE bStatus);
+// Gets a pointer to a user friendly message
+const char *CCIDGetCommandStatusMessage(BYTE bCommandStatus);
+
+
+CCIDRv CCID_OpenChannel(DWORD Lun, DWORD ChannelID);
+CCIDRv CCID_CloseChannel(DWORD Lun);
+
+
+
+CCIDRv CCID_IccPowerOn(DWORD Lun, BYTE *abDataResp, DWORD *pdwDataRespLength);
+CCIDRv CCID_IccPowerOff(DWORD Lun, BYTE *pbClockStatus);
+CCIDRv CCID_GetSlotStatus(DWORD Lun, BYTE *pbStatus, BYTE *pbClockStatus);
+// XfrBlock expects to receive APDU level commands
+// and manages the communication with the CCID reader
+// transparently according to the reader communication level
+CCIDRv CCID_XfrBlock(DWORD Lun, BYTE bBWI,
+ DWORD dwRequestedProtocol,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength);
+CCIDRv CCID_GetParameters(DWORD Lun,
+ BYTE *pbProtocolNum,
+ BYTE *abProtocolDataStructure,
+ DWORD *dwProtocolDataStructureLength);
+CCIDRv CCID_ResetParameters(DWORD Lun,
+ BYTE *pbProtocolNum,
+ BYTE *abProtocolDataStructure,
+ DWORD *dwProtocolDataStructureLength);
+CCIDRv CCID_SetParameter(DWORD Lun,
+ BYTE bProtocolNum,
+ BYTE *abSetProtocolDataStructure,
+ DWORD dwSetProtocolDataStructureLength,
+ BYTE *pbProtocolNum,
+ BYTE *abProtocolDataStructure,
+ DWORD *dwProtocolDataStructureLength);
+
+
+CCIDRv CCID_Escape(DWORD Lun,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength,
+ BYTE *pbErrorSpecific);
+
+CCIDRv CCID_IccClock(DWORD Lun, BYTE bClockCommand,
+ BYTE *pbClockStatus);
+CCIDRv CCID_T0APDU(DWORD Lun, BYTE bmChanges, BYTE bClassGetResponse,
+ BYTE bClassEnvelope,
+ BYTE *pbClockStatus);
+// CCID_Secure IS CURRENTLY NOT SUPPORTED
+// FUNCTION PROTOTYPE WILL CHANGE WHEN IT IS
+CCIDRv CCID_Secure(DWORD Lun);
+CCIDRv CCID_Mechanical(DWORD Lun, BYTE bFunction,
+ BYTE *pbClockStatus);
+CCIDRv CCID_Abort(DWORD Lun, BYTE *pbClockStatus);
+CCIDRv CCID_SetDataRateAndClockFrequency(DWORD Lun,
+ DWORD dwClockFrequencyCmd,
+ DWORD dwDataRateCmd,
+ DWORD *pdwClockFrequencyResp,
+ DWORD *pdwDataRateResp);
+
+
+
+
+#define CCID_ERR_CMD_ABORTED 0xFF
+#define CCID_ERR_ICC_MUTE 0xFE
+#define CCID_ERR_XFR_PARITY_ERROR 0xFD
+#define CCID_ERR_XFR_OVERRUN 0xFC
+#define CCID_ERR_HW_ERROR 0xFB
+#define CCID_ERR_BAD_ATR_TS 0xF8
+#define CCID_ERR_BAD_ATR_TCK 0xF7
+#define CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED 0xF6
+#define CCID_ERR_ICC_CLASS_NOT_SUPPORTED 0xF5
+#define CCID_ERR_PROCEDURE_BYTE_CONFLICT 0xF4
+#define CCID_ERR_DEACTIVATED_PROTOCOL 0xF3
+#define CCID_ERR_BUSY_WITH_AUTO_SEQUENCE 0xF2
+#define CCID_ERR_PIN_TIMEOUT 0xF0
+#define CCID_ERR_PIN_CANCELLED 0xEF
+#define CCID_ERR_CMD_SLOT_BUSY 0xE0
+
+// Errors with no officla names in spec
+#define CCID_ERR_0 0x00
+#define CCID_ERR_1 0x01
+#define CCID_ERR_5 0x05
+#define CCID_ERR_7 0x07
+#define CCID_ERR_8 0x08
+
+
+#define CCID_CMD_STATUS_SUCCESS 0
+#define CCID_CMD_STATUS_FAILED 1
+#define CCID_CMD_STATUS_TIME_REQ 2
+#define CCID_CMD_STATUS_RFU 3
+
+#define CCID_ICC_STATUS_ACTIVE 0
+#define CCID_ICC_STATUS_INACTIVE 1
+#define CCID_ICC_STATUS_ABSENT 2
+#define CCID_ICC_STATUS_RFU 3
+
+#define CCID_SLOT_STATUS_CLK_RUNNING 0x00
+#define CCID_SLOT_STATUS_CLK_STOPPED_H 0x01
+#define CCID_SLOT_STATUS_CLK_STOPPED_L 0x02
+#define CCID_SLOT_STATUS_CLK_STOPPED_UNKNOWN 0x03
+
+
+
+#define MASK_ICC_STATUS (0x03)
+#define OFFSET_ICC_STATUS (0)
+#define MASK_COMMAND_STATUS (0xC0)
+#define OFFSET_COMMAND_STATUS (6)
+
+
+
+
+#endif
\ No newline at end of file
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,191 @@
+/*
+ * CCIDPropExt.c
+ * ifd-CCID
+ *
+ * Created by JL on Sun Jul 20 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#include "global.h"
+
+#include "tools.h"
+#include "CCID.h"
+#include "CCIDprivate.h"
+#include "pcscdefines.h"
+#include "CCIDPropExt.h"
+
+typedef struct {
+ DWORD dwVendorID;
+ DWORD dwProductID;
+ CCIDPropExt stPropExt;
+} CCIDExtendedPropExt;
+
+CCIDRv CCIDPropExtOpenChannelGemPCKeyTwin(DWORD lun);
+CCIDRv CCIDPropExtOpenChannelGemPC433(DWORD lun);
+CCIDRv CCIDPropExtIccPowerOnGemPC433(DWORD Lun, BYTE *abDataResp, DWORD *pdwDataRespLength, BYTE bStatus, BYTE bError);
+
+
+static CCIDExtendedPropExt astCCIDPropExt[] =
+{
+ // GemPC433
+ {0x8E6, 0x4433, {NULL, NULL, CCIDPropExtIccPowerOnGemPC433}},
+ // GemPCKey
+ {0x8E6, 0x3438, {CCIDPropExtOpenChannelGemPCKeyTwin, NULL, NULL}},
+ // GemPCTwin
+ {0x8E6, 0x3437, {CCIDPropExtOpenChannelGemPCKeyTwin, NULL, NULL}},
+
+};
+
+
+CCIDRv CCIDPropExtLookupExt(DWORD dwVendorID, DWORD dwProductID, CCIDPropExt *pstCCIDPropExt)
+{
+ WORD wIndex;
+
+ for (wIndex = 0; wIndex < (sizeof(astCCIDPropExt)/sizeof(CCIDExtendedPropExt)); wIndex++)
+ {
+ if ( (astCCIDPropExt[wIndex].dwVendorID == dwVendorID)
+ && (astCCIDPropExt[wIndex].dwProductID == dwProductID)
+ )
+ {
+ pstCCIDPropExt->OpenChannel = astCCIDPropExt[wIndex].stPropExt.OpenChannel;
+ pstCCIDPropExt->CloseChannel = astCCIDPropExt[wIndex].stPropExt.CloseChannel;
+ pstCCIDPropExt->PowerOn = astCCIDPropExt[wIndex].stPropExt.PowerOn;
+ return CCIDRv_OK;
+ }
+ }
+ return CCIDRv_ERR_VALUE_NOT_FOUND;
+}
+
+
+// Used to set the GemPCKey and the GemPCTwin in APDU mode
+// Connections need to be set-up before this call
+CCIDRv CCIDPropExtOpenChannelGemPCKeyTwin(DWORD Lun)
+{
+ CCIDRv rv;
+
+ //BYTE abGemPCTwinSetAPDUMode[] = {0xA0, 0x01}; (from FB)
+ BYTE abGemPCTwinSetAPDUMode[] = {0xA0, 0x02};
+ BYTE pcBuffer[100];
+ BYTE bSpecificErrorCode;
+ DWORD dwBufferLength = sizeof(pcBuffer);
+ rv = CCID_Escape(Lun, abGemPCTwinSetAPDUMode, sizeof(abGemPCTwinSetAPDUMode),
+ pcBuffer, &dwBufferLength, &bSpecificErrorCode);
+ if ( rv != CCIDRv_OK )
+ return rv;
+ // Successfull initialisation, update Exchange Level
+ CCIDReaderStates[ LunToReaderLun(Lun)].dwExchangeLevel = CCID_CLASS_FEAT_EXC_LEVEL_SAPDU;
+ return CCIDRv_OK;
+}
+
+
+// Used to set the GemPC433 in APDU mode
+// Connections need to be set-up before this call
+CCIDRv CCIDPropExtOpenChannelGemPC433(DWORD Lun)
+{
+ CCIDRv rv;
+ BYTE abGemPC433SetISOMode[] = {0x1F, 0x01};
+ BYTE pcBuffer[100];
+ BYTE bSpecificErrorCode;
+ DWORD dwBufferLength = sizeof(pcBuffer);
+ rv = CCID_Escape(Lun, abGemPC433SetISOMode, sizeof(abGemPC433SetISOMode),
+ pcBuffer, &dwBufferLength, &bSpecificErrorCode);
+ if ( rv != CCIDRv_OK )
+ return rv;
+ // Successfull initialisation, update Exchange Level
+ CCIDReaderStates[ LunToReaderLun(Lun)].dwExchangeLevel = CCID_CLASS_FEAT_EXC_LEVEL_SAPDU;
+ return CCIDRv_OK;
+}
+
+// Perform second power-up in ISO mode for the GemPC433
+CCIDRv CCIDPropExtIccPowerOnGemPC433(DWORD Lun, BYTE *abDataResp, DWORD *pdwDataRespLength,
+ BYTE bStatus, BYTE bError)
+{
+ CCIDRv rv;
+ WORD wRdrLun;
+ BYTE bMessageTypeResp;
+ BYTE bMessageSpecificResp;
+ BYTE abMessageSpecificCmd[3] = "\x00\x00\x00";
+
+ // Check if it is a non EMV-compliant ATR issue
+ if ( bError != 0xBB )
+ {
+ // Other error, exit
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ wRdrLun = LunToReaderLun(Lun);
+ if ( wRdrLun >= PCSCLITE_MAX_CHANNELS)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Reader Lun too large: %d", wRdrLun);
+ return CCIDRv_ERR_READER_LUN;
+ }
+ // First set reader in ISO mode
+ if ( CCIDPropExtOpenChannelGemPC433(Lun) != CCIDRv_OK )
+ {
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ // Power-up at 5V
+ //+++ For the proper Power-Up sequence, see 7816-3:1997 section 4.2.2
+ abMessageSpecificCmd[0] = 0x01;
+ rv = CCID_Exchange_Command(Lun, PC_to_RDR_IccPowerOn,
+ abMessageSpecificCmd,
+ (BYTE *)"", 0,
+ &bMessageTypeResp,
+ &bStatus, &bError,
+ &bMessageSpecificResp,
+ abDataResp, pdwDataRespLength, 0);
+ if ( rv == CCIDRv_ERR_PRIVATE_ERROR )
+ {
+ // ICC Power On has a few specific error cases
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_INACTIVE )
+ {
+ if ( bError == CCID_ERR_7 )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Power On mode not supported: %02X", abMessageSpecificCmd[0]);
+ return CCIDRv_ERR_POWERON_MODE_UNSUPPORTED;
+ }
+
+ if ( bError == CCID_ERR_XFR_PARITY_ERROR )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "ATR Parity error");
+ return CCIDRv_ERR_ATR_PARITY_ERROR;
+ }
+
+ if ( bError == CCID_ERR_BAD_ATR_TS )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong TS in ATR");
+ return CCIDRv_ERR_BAD_ATR_TS;
+ }
+
+ if ( bError == CCID_ERR_BAD_ATR_TCK )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Wrong TCK in ATR");
+ return CCIDRv_ERR_BAD_ATR_TCK;
+ }
+
+ if ( bError == CCID_ERR_ICC_PROTOCOL_NOT_SUPPORTED )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Protocol not supported");
+ return CCIDRv_ERR_PROTOCOL_NOT_SUPPORTED;
+ }
+
+ if ( bError == CCID_ERR_ICC_CLASS_NOT_SUPPORTED )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "ICC Class not supported");
+ return CCIDRv_ERR_CLASS_NOT_SUPPORTED;
+ }
+
+ }
+ if ( CCIDGetICCStatus(bStatus) == CCID_ICC_STATUS_ABSENT)
+ {
+ return CCIDRv_ERR_CARD_ABSENT;
+ }
+ return CCIDRv_ERR_UNSPECIFIED;
+ }
+ if ( bMessageTypeResp != RDR_to_PC_DataBlock )
+ {
+ return CCIDRv_ERR_WRONG_MESG_RESP_TYPE;
+ }
+ return CCIDRv_OK;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDPropExt.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,30 @@
+/*
+ * CCIDPropExt.h
+ * ifd-CCID
+ *
+ * Created by JL on Sun Jul 20 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+// CCID Proprietary extension management
+
+#ifndef __CCIDPROPEXT_H__
+#define __CCIDPROPEXT_H__
+
+#include "CCID.h"
+
+typedef struct {
+ CCIDRv (*OpenChannel)(DWORD lun);
+ CCIDRv (*CloseChannel)(DWORD lun);
+ CCIDRv (*PowerOn)(DWORD Lun, BYTE *abDataResp, DWORD *pdwDataRespLength,
+ BYTE bStatus, BYTE bError);
+} CCIDPropExt;
+
+// Looks-up for a proprietary extension structure according to vendorID/ProductID
+CCIDRv CCIDPropExtLookupExt(DWORD dwVendorID, DWORD dwProductID, CCIDPropExt *pstCCIDPropExt);
+
+
+
+#endif
\ No newline at end of file
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDprivate.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDprivate.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/CCIDprivate.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,39 @@
+/*
+ * CCIDprivate.h
+ * ifd-CCID
+ *
+ * Created by JL on Mon Jul 21 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#ifndef __CCIDPRIVATE_H__
+#define __CCIDPRIVATE_H__
+extern CCIDReaderState CCIDReaderStates[PCSCLITE_MAX_CHANNELS];
+
+// Performs a Bulk-IN/Bluk-Out exchange with reader
+// Seq and Slot are automatically managed
+// "TimeExtension" messages can be handled through bTimeExtRetry:
+// If set to 1, CCID_Exchange_Command does not send the command and reads
+// directly
+// If set to 0, CCID_Exchange_Command sends the command (used for a normal call
+// or time extension management in T=1)
+CCIDRv CCID_Exchange_Command(DWORD Lun, BYTE bMessageTypeCmd,
+ BYTE *abMessageSpecificCmd,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *pbMessageTypeResp,
+ BYTE *pbStatus, BYTE *pbError,
+ BYTE *pbMessageSpecificResp,
+ BYTE *abDataResp, DWORD *pdwDataRespLength,
+ BYTE bTimeExtRetry);
+CCIDRv CCID_XfrBlockSAPDU(DWORD Lun, BYTE bBWI,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength);
+
+CCIDRv CCID_XfrBlockTPDU(DWORD Lun, BYTE bBWI,
+ BYTE *abDataCmd, DWORD dwDataCmdLength,
+ BYTE *abDataResp, DWORD *pdwDataRespLength);
+
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,32 @@
+/*
+ * Transport.c
+ * ifd-CCID
+ *
+ * Created by JL on Sat Jun 14 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+#include "pcscdefines.h"
+
+#include "Transport.h"
+#include "usbserial.h"
+
+
+// MAKE SURE VALUES AND ORDER MATCH ENUM IN Transport.h
+TrFunctions TrFunctionTable[] =
+{
+ {
+ OpenUSB,
+ GetConfigDescNumberUSB,
+ GetVendorAndProductIDUSB,
+ GetClassDescUSB,
+ SetupConnectionsUSB,
+ WriteUSB,
+ ReadUSB,
+ CloseUSB
+ }
+
+};
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/Transport.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,53 @@
+/*
+ * Transport.h
+ * ifd-CCID
+ *
+ * Created by JL on Sat Jun 14 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#ifndef __TRANSPORT_H__
+#define __TRANSPORT_H__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "wintypes.h"
+
+
+typedef enum {
+ TrRv_OK = 0x00,
+ TrRv_ERR = 0x01,
+} TrRv;
+
+
+typedef struct {
+ TrRv (*Open)( DWORD lun, DWORD channel );
+ // returns the number of conifguration descriptors once the device has been successfully opened
+ TrRv (*GetConfigDescNumber)( DWORD lun, BYTE* pcconfigDescNb );
+ TrRv (*GetVendorAndProductID)( DWORD lun, DWORD *vendorID, DWORD *productID );
+ // Reads the class descriptor once the device has been successfully opened
+ TrRv (*GetClassDesc)( DWORD lun, BYTE configDescNb, BYTE bdescType,
+ BYTE *pcdesc, BYTE *pcdescLength);
+ TrRv (*SetupConnections)( DWORD lun, BYTE ConfigDescNb, BYTE interruptPipe);
+ TrRv (*Write)( DWORD lun, DWORD length, BYTE *Buffer );
+ TrRv (*Read)( DWORD lun, DWORD *length, BYTE *Buffer );
+ TrRv (*Close)( DWORD lun );
+} TrFunctions;
+
+// MAKE SURE VALUES AND ORDER MATCH TABLE IN Transport.c
+typedef enum {
+ TrType_USB = 0x00,
+ TrType_SERIAL = 0x01,
+} TrType;
+
+extern TrFunctions TrFunctionTable[];
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
\ No newline at end of file
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/global.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/global.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/global.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,15 @@
+/*
+ * global.h
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ */
+
+#ifndef _GLOBAL_H_
+#define _GLOBAL_H_
+
+#define BUNDLE_IDENTIFIER "com.apple.ccidclassdriver"
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,637 @@
+/*****************************************************************
+/
+/ File : ifdhandler.c
+/ Authors : David Corcoran <corcoran at linuxnet.com>
+/ Jean-Luc Giraud <jlgiraud at mac.com>
+/ Date : April 9, 2003
+/ Purpose: This provides reader specific low-level calls
+/ for the GemPC family of Gemplus. The function
+/ stubs were written by D. Corcoran, the CCID
+/ +specific code was added by JL Giraud.
+/ See http://www.linuxnet.com for more information.
+/ License: See file COPYING
+/
+/
+******************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wintypes.h"
+#include "pcscdefines.h"
+#include "ifdhandler.h"
+#include "global.h"
+
+#include "tools.h"
+#include "CCID.h"
+
+#define POWERFLAGS_RAZ 0x00
+//Flag set when a power up has been requested
+#define MASK_POWERFLAGS_PUP 0x01
+//Flag set when a power down is requested
+#define MASK_POWERFLAGS_PDWN 0x02
+
+//+++ NEEDS TO BE READ FROM CCID DESC
+#define MAX_SLOT_NB 2
+
+enum
+{
+ T_0 = 0,
+ T_1 = 1
+};
+
+
+
+
+typedef struct
+{
+ DWORD nATRLength;
+ UCHAR pcATRBuffer[MAX_ATR_SIZE];
+ UCHAR bPowerFlags;
+} IFDDesc;
+
+int iLunCheck(DWORD Lun)
+{
+ if ((LunToReaderLun(Lun) >= PCSCLITE_MAX_CHANNELS))
+ return TRUE;
+
+ return FALSE;
+} /* iLunCheck */
+
+
+// Array of structures to hold the ATR and other state value of each slot
+static IFDDesc pstIFDDescs[PCSCLITE_MAX_CHANNELS][MAX_SLOT_NB];
+static int iLogValue = LogLevelCritical;
+
+BYTE bLogPeriodic = 0;
+
+RESPONSECODE IFDHCreateChannel(DWORD Lun, DWORD Channel)
+{
+ /*
+ * Lun - Logical Unit Number, use this for multiple card slots or
+ * multiple readers. 0xXXXXYYYY - XXXX multiple readers, YYYY multiple
+ * slots. The resource manager will set these automatically. By
+ * default the resource manager loads a new instance of the driver so
+ * if your reader does not have more than one smartcard slot then
+ * ignore the Lun in all the functions. Future versions of PC/SC might
+ * support loading multiple readers through one instance of the driver
+ * in which XXXX would be important to implement if you want this.
+ */
+
+ /*
+ * Channel - Channel ID. This is denoted by the following: 0x000001 -
+ * /dev/pcsc/1 0x000002 - /dev/pcsc/2 0x000003 - /dev/pcsc/3
+ *
+ * USB readers may choose to ignore this parameter and query the bus
+ * for the particular reader.
+ */
+
+ /*
+ * This function is required to open a communications channel to the
+ * port listed by Channel. For example, the first serial reader on
+ * COM1 would link to /dev/pcsc/1 which would be a sym link to
+ * /dev/ttyS0 on some machines This is used to help with intermachine
+ * independance.
+ *
+ * Once the channel is opened the reader must be in a state in which
+ * it is possible to query IFDHICCPresence() for card status.
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_COMMUNICATION_ERROR
+ */
+ const char *pcStringValue;
+
+ StartLogging();
+ SetLogType(LogTypeSysLog);
+ pcStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, "ifdLogType");
+ if ( pcStringValue == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Could not get ifdLogType info, use syslog");
+ }
+ else
+ {
+ if (!strncmp(pcStringValue, "stderr", strlen("stderr")))
+ {
+ SetLogType(LogTypeStderr);
+ }
+ else
+ {
+ SetLogType(LogTypeSysLog);
+ }
+ }
+
+
+ pcStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, "ifdLogLevel");
+ if ( pcStringValue == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Could not get ifdLogLevel info, use minimal level");
+ SetLogLevel(LogLevelCritical);
+ }
+ else
+ {
+ iLogValue = atoi(pcStringValue);
+ SetLogLevel((BYTE)iLogValue);
+ }
+
+ bLogPeriodic = 0;
+ pcStringValue = ParseInfoPlist(BUNDLE_IDENTIFIER, "ifdLogPeriodic");
+ if ( pcStringValue == NULL )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Could not get ifdLogPeriodic info, will not log periodic info");
+ }
+ else
+ {
+ if ( toupper(*pcStringValue) == 'Y' )
+ bLogPeriodic = 1;
+ }
+
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "Entering IFDHCreateChannel");
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ // Reset ATR buffer
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].nATRLength = 0;
+ *pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].pcATRBuffer = '\0';
+
+ // Reset PowerFlags
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].bPowerFlags =
+ POWERFLAGS_RAZ;
+
+ if (CCID_OpenChannel(Lun, Channel) != CCIDRv_OK)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "OpenReader failed");
+ return IFD_COMMUNICATION_ERROR;
+ }
+
+ return IFD_SUCCESS;
+} /* IFDHCreateChannel */
+
+
+RESPONSECODE IFDHCloseChannel(DWORD Lun)
+{
+ /*
+ * This function should close the reader communication channel for the
+ * particular reader. Prior to closing the communication channel the
+ * reader should make sure the card is powered down and the terminal
+ * is also powered down.
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_COMMUNICATION_ERROR
+ */
+ BYTE bClockStatus;
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "entering IFDHCloseChannel");
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ CCID_IccPowerOff(Lun, &bClockStatus);
+ // No error status check, if it failed, what can you do ? :)
+
+ CCID_CloseChannel(Lun);
+ return IFD_SUCCESS;
+} /* IFDHCloseChannel */
+
+
+RESPONSECODE IFDHGetCapabilities(DWORD Lun, DWORD Tag,
+ PDWORD Length, PUCHAR Value)
+{
+ /*
+ * This function should get the slot/card capabilities for a
+ * particular slot/card specified by Lun. Again, if you have only 1
+ * card slot and don't mind loading a new driver for each reader then
+ * ignore Lun.
+ *
+ * Tag - the tag for the information requested example: TAG_IFD_ATR -
+ * return the Atr and it's size (required). these tags are defined in
+ * ifdhandler.h
+ *
+ * Length - the length of the returned data Value - the value of the
+ * data
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_ERROR_TAG
+ */
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "entering IFDHGetCapabilities\n");
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ switch (Tag)
+ {
+ case TAG_IFD_ATR:
+ // If Length is not zero, powerICC has been performed.
+ // Otherwise, return NULL pointer
+ // Buffer size is stored in *Length
+ *Length = (*Length < pstIFDDescs[LunToReaderLun(Lun)]
+ [LunToSlotNb(Lun)].nATRLength) ?
+ *Length : pstIFDDescs[LunToReaderLun(Lun)]
+ [LunToSlotNb(Lun)].nATRLength;
+
+ if (*Length)
+ memcpy(Value, pstIFDDescs[LunToReaderLun(Lun)]
+ [LunToSlotNb(Lun)].pcATRBuffer, *Length);
+ break;
+
+ case TAG_IFD_SIMULTANEOUS_ACCESS:
+ if (*Length >= 1)
+ {
+ *Length =1;
+ *Value = PCSCLITE_MAX_CHANNELS;
+ break;
+ }
+
+ default:
+ return IFD_ERROR_TAG;
+ }
+ return IFD_SUCCESS;
+} /* IFDHGetCapabilities */
+
+
+RESPONSECODE IFDHSetCapabilities(DWORD Lun, DWORD Tag,
+ DWORD Length, PUCHAR Value)
+{
+ /*
+ * This function should set the slot/card capabilities for a
+ * particular slot/card specified by Lun. Again, if you have only 1
+ * card slot and don't mind loading a new driver for each reader then
+ * ignore Lun.
+ *
+ * Tag - the tag for the information needing set
+ *
+ * Length - the length of the returned data Value - the value of the
+ * data
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_ERROR_TAG IFD_ERROR_SET_FAILURE
+ * IFD_ERROR_VALUE_READ_ONLY
+ */
+
+ // By default, say it worked
+
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "entering IFDHSetCapabilities");
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ return IFD_SUCCESS;
+} /* IFDHSetCapabilities */
+
+
+RESPONSECODE IFDHSetProtocolParameters(DWORD Lun, DWORD Protocol,
+ UCHAR Flags, UCHAR PTS1, UCHAR PTS2, UCHAR PTS3)
+{
+ /*
+ * This function should set the PTS of a particular card/slot using
+ * the three PTS parameters sent
+ *
+ * Protocol - 0 .... 14 T=0 .... T=14 Flags - Logical OR of possible
+ * values: IFD_NEGOTIATE_PTS1 IFD_NEGOTIATE_PTS2 IFD_NEGOTIATE_PTS3 to
+ * determine which PTS values to negotiate. PTS1,PTS2,PTS3 - PTS
+ * Values.
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_ERROR_PTS_FAILURE IFD_COMMUNICATION_ERROR
+ * IFD_PROTOCOL_NOT_SUPPORTED
+ */
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "entering IFDHSetProtocolParameters");
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ return IFD_SUCCESS;
+} /* IFDHSetProtocolParameters */
+
+
+RESPONSECODE IFDHPowerICC(DWORD Lun, DWORD Action,
+ PUCHAR Atr, PDWORD AtrLength)
+{
+ /*
+ * This function controls the power and reset signals of the smartcard
+ * reader at the particular reader/slot specified by Lun.
+ *
+ * Action - Action to be taken on the card.
+ *
+ * IFD_POWER_UP - Power and reset the card if not done so (store the
+ * ATR and return it and it's length).
+ *
+ * IFD_POWER_DOWN - Power down the card if not done already
+ * (Atr/AtrLength should be zero'd)
+ *
+ * IFD_RESET - Perform a quick reset on the card. If the card is not
+ * powered power up the card. (Store and return the Atr/Length)
+ *
+ * Atr - Answer to Reset of the card. The driver is responsible for
+ * caching this value in case IFDHGetCapabilities is called requesting
+ * the ATR and it's length. This should not exceed MAX_ATR_SIZE.
+ *
+ * AtrLength - Length of the Atr. This should not exceed
+ * MAX_ATR_SIZE.
+ *
+ * Notes:
+ *
+ * Memory cards without an ATR should return IFD_SUCCESS on reset but
+ * the Atr should be zero'd and the length should be zero
+ *
+ * Reset errors should return zero for the AtrLength and return
+ * IFD_ERROR_POWER_ACTION.
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_ERROR_POWER_ACTION IFD_COMMUNICATION_ERROR
+ * IFD_NOT_SUPPORTED
+ */
+
+ DWORD nlength;
+ CCIDRv rv;
+ BYTE bClockStatus;
+ BYTE pcbuffer[200];
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "entering IFDHPowerICC");
+
+ // By default, assume it won't work :)
+ *AtrLength = 0;
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ switch (Action)
+ {
+ case IFD_POWER_UP:
+ case IFD_RESET:
+ nlength = sizeof(pcbuffer);
+ if ((rv = CCID_IccPowerOn(Lun, pcbuffer, &nlength)) != CCIDRv_OK)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "PowerUp failed");
+ return IFD_ERROR_POWER_ACTION;
+ }
+
+ // Power up successful, set state variable to memorise it
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ bPowerFlags |= MASK_POWERFLAGS_PUP;
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ bPowerFlags &= ~MASK_POWERFLAGS_PDWN;
+
+ // Reset is returned, even if TCK is wrong
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ nATRLength = *AtrLength =
+ (nlength < MAX_ATR_SIZE) ? nlength : MAX_ATR_SIZE;
+ memcpy(Atr, pcbuffer, *AtrLength);
+ memcpy(pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ pcATRBuffer, pcbuffer, *AtrLength);
+
+ break;
+
+ case IFD_POWER_DOWN:
+ // Clear ATR buffer
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].nATRLength =
+ 0;
+ *pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ pcATRBuffer = '\0';
+ // Memorise the request
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].bPowerFlags
+ |= MASK_POWERFLAGS_PDWN;
+ // send the command
+ rv = CCID_IccPowerOff(Lun, &bClockStatus);
+ if (rv != CCIDRv_OK)
+ {
+ return IFD_ERROR_POWER_ACTION;
+ }
+ break;
+
+ default:
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "IFDHPowerICC Action not supported");
+ return IFD_NOT_SUPPORTED;
+ }
+ return IFD_SUCCESS;
+} /* IFDHPowerICC */
+
+
+RESPONSECODE IFDHTransmitToICC(DWORD Lun, SCARD_IO_HEADER SendPci,
+ PUCHAR TxBuffer, DWORD TxLength,
+ PUCHAR RxBuffer, PDWORD RxLength, PSCARD_IO_HEADER RecvPci)
+{
+ /*
+ * This function performs an APDU exchange with the card/slot
+ * specified by Lun. The driver is responsible for performing any
+ * protocol specific exchanges such as T=0/1 ... differences. Calling
+ * this function will abstract all protocol differences.
+ *
+ * SendPci Protocol - 0, 1, .... 14 Length - Not used.
+ *
+ * TxBuffer - Transmit APDU example (0x00 0xA4 0x00 0x00 0x02 0x3F
+ * 0x00) TxLength - Length of this buffer. RxBuffer - Receive APDU
+ * example (0x61 0x14) RxLength - Length of the received APDU. This
+ * function will be passed the size of the buffer of RxBuffer and this
+ * function is responsible for setting this to the length of the
+ * received APDU. This should be ZERO on all errors. The resource
+ * manager will take responsibility of zeroing out any temporary APDU
+ * buffers for security reasons.
+ *
+ * RecvPci Protocol - 0, 1, .... 14 Length - Not used.
+ *
+ * Notes: The driver is responsible for knowing what type of card it
+ * has. If the current slot/card contains a memory card then this
+ * command should ignore the Protocol and use the MCT style commands
+ * for support for these style cards and transmit them appropriately.
+ * If your reader does not support memory cards or you don't want to
+ * then ignore this.
+ *
+ * RxLength should be set to zero on error.
+ *
+ * returns:
+ *
+ * IFD_SUCCESS IFD_COMMUNICATION_ERROR IFD_RESPONSE_TIMEOUT
+ * IFD_ICC_NOT_PRESENT IFD_PROTOCOL_NOT_SUPPORTED
+ */
+
+ RESPONSECODE return_value = IFD_SUCCESS; // Assume it will work
+ CCIDRv rv;
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "entering IFDHTransmitToICC");
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ LogHexBuffer(__FILE__, __LINE__, LogLevelVeryVerbose, TxBuffer, TxLength, "APDU sent: ");
+
+ switch (SendPci.Protocol)
+ {
+ case T_0:
+ case T_1:
+ rv = CCID_XfrBlock(Lun, 0, SendPci.Protocol, TxBuffer, TxLength,
+ RxBuffer, RxLength);
+ if ( rv != CCIDRv_OK)
+ {
+ switch (rv)
+ {
+ case CCIDRv_ERR_ICC_MUTE:
+ return_value = IFD_RESPONSE_TIMEOUT;
+ break;
+ case CCIDRv_ERR_CARD_ABSENT:
+ return_value = IFD_ICC_NOT_PRESENT;
+ break;
+ default:
+ return_value = IFD_COMMUNICATION_ERROR;
+ }
+ }
+
+ break;
+
+ default:
+ return_value = IFD_PROTOCOL_NOT_SUPPORTED;
+ }
+
+ if (return_value != CCIDRv_OK)
+ *RxLength = 0;
+
+ if (*RxLength)
+ LogHexBuffer(__FILE__, __LINE__, LogLevelVeryVerbose, RxBuffer, *RxLength, "APDU response: ");
+
+ return return_value;
+
+} /* IFDHTransmitToICC */
+
+
+RESPONSECODE IFDHControl(DWORD Lun, PUCHAR TxBuffer,
+ DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
+{
+ /*
+ * This function performs a data exchange with the reader (not the
+ * card) specified by Lun. Here XXXX will only be used. It is
+ * responsible for abstracting functionality such as PIN pads,
+ * biometrics, LCD panels, etc. You should follow the MCT, CTBCS
+ * specifications for a list of accepted commands to implement.
+ *
+ * TxBuffer - Transmit data TxLength - Length of this buffer. RxBuffer
+ * - Receive data RxLength - Length of the received data. This
+ * function will be passed the length of the buffer RxBuffer and it
+ * must set this to the length of the received data.
+ *
+ * Notes: RxLength should be zero on error.
+ */
+
+ LogMessage( __FILE__, __LINE__, LogLevelVerbose, "entering IFDHControl");
+
+ if (iLunCheck(Lun))
+ return IFD_COMMUNICATION_ERROR;
+
+ return IFD_SUCCESS;
+} /* IFDHControl */
+
+
+RESPONSECODE IFDHICCPresence(DWORD Lun)
+{
+ /*
+ * This function returns the status of the card inserted in the
+ * reader/slot specified by Lun. It will return either:
+ *
+ * returns: IFD_ICC_PRESENT IFD_ICC_NOT_PRESENT
+ * IFD_COMMUNICATION_ERROR
+ */
+ BYTE bStatus, bClockStatus;
+ BYTE bICCStatus;
+ // Set log level to only critical
+ if ( !bLogPeriodic )
+ {
+ SetLogLevel((BYTE)LogLevelCritical);
+ }
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "entering IFDHICCPresence");
+
+ if (iLunCheck(Lun))
+ {
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_COMMUNICATION_ERROR;
+ }
+ if (CCID_GetSlotStatus(Lun, &bStatus, &bClockStatus) != CCIDRv_OK)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "GCCmdCardStatus failed");
+ {
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_COMMUNICATION_ERROR;
+ }
+ }
+ bICCStatus = CCIDGetICCStatus(bStatus);
+ if ( bICCStatus == CCID_ICC_STATUS_ABSENT )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "Card absent");
+ // Clear ATR buffer
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].nATRLength = 0;
+ *pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ pcATRBuffer = '\0';
+ // Card removed, clear the flags
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].bPowerFlags =
+ POWERFLAGS_RAZ;
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_ICC_NOT_PRESENT;
+ }
+ else
+ {
+ // Card is present, but is it powered-up?
+ if (bICCStatus == CCID_ICC_STATUS_ACTIVE)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "Card present and powered");
+ // Powered, so the ressource manager did not miss a quick
+ // removal/re-insertion
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_ICC_PRESENT;
+ }
+ else
+ {
+ // Card present but not powered up
+ // Check if a power down has been requested
+ if (pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ bPowerFlags & MASK_POWERFLAGS_PDWN)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "Card present not powered, power down requested");
+ // Powerdown requested, so situation is normal
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_ICC_PRESENT;
+ }
+
+ // Card inserted, not powered on but power down has not been
+ // requested
+ // Has the card been powered up already?
+ if (pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ bPowerFlags & MASK_POWERFLAGS_PUP)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "Card pull-out+re-insert detected CARD OUT SIMULATION");
+ // Power-up has been requested, but not power down and power is
+ // down. This should happen only if the card has been pulled
+ // out and reinserted too quickly for the resource manager to
+ // realise. A card out event is therefore simulated. Clear ATR
+ // buffer
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ nATRLength = 0;
+ *pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ pcATRBuffer = '\0';
+ // reset power flags
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ bPowerFlags = POWERFLAGS_RAZ;
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_ICC_NOT_PRESENT;
+ }
+
+ LogMessage( __FILE__, __LINE__, LogLevelVeryVerbose, "Card present, just inserted");
+ // If control gets here, the card is in, not powered on, with
+ // no power down request and no previous power up request
+ // it is therefore a card insertion event
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ nATRLength = 0;
+ *pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ pcATRBuffer = '\0';
+ // reset power flags
+ pstIFDDescs[LunToReaderLun(Lun)][LunToSlotNb(Lun)].
+ bPowerFlags = POWERFLAGS_RAZ;
+ SetLogLevel((BYTE)iLogValue);
+ return IFD_ICC_PRESENT;
+ }
+ }
+} /* IFDHICCPresence */
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/ifdhandler.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,140 @@
+/*****************************************************************
+/
+/ File : ifdhandler.h
+/ Author : David Corcoran <corcoran at linuxnet.com>
+/ Date : June 15, 2000
+/ Purpose: This provides reader specific low-level calls.
+/ See http://www.linuxnet.com for more information.
+/ License: See file COPYING.BSD
+/
+/ $Id: ifdhandler.h,v 1.2 2004/08/16 17:50:35 stuartha Exp $
+/
+******************************************************************/
+
+#ifndef _ifd_handler_h_
+#define _ifd_handler_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* List of data structures available to ifdhandler */
+
+ typedef struct _DEVICE_CAPABILITIES {
+
+ LPSTR Vendor_Name; /* Tag 0x0100 */
+ LPSTR IFD_Type; /* Tag 0x0101 */
+ DWORD IFD_Version; /* Tag 0x0102 */
+ LPSTR IFD_Serial; /* Tag 0x0103 */
+ DWORD IFD_Channel_ID; /* Tag 0x0110 */
+
+ DWORD Asynch_Supported; /* Tag 0x0120 */
+ DWORD Default_Clock; /* Tag 0x0121 */
+ DWORD Max_Clock; /* Tag 0x0122 */
+ DWORD Default_Data_Rate; /* Tag 0x0123 */
+ DWORD Max_Data_Rate; /* Tag 0x0124 */
+ DWORD Max_IFSD; /* Tag 0x0125 */
+ DWORD Synch_Supported; /* Tag 0x0126 */
+ DWORD Power_Mgmt; /* Tag 0x0131 */
+ DWORD Card_Auth_Devices; /* Tag 0x0140 */
+ DWORD User_Auth_Device; /* Tag 0x0142 */
+ DWORD Mechanics_Supported; /* Tag 0x0150 */
+ DWORD Vendor_Features; /* Tag 0x0180 - 0x01F0 User Defined. */
+
+ } DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
+
+ typedef struct _ICC_STATE {
+
+ UCHAR ICC_Presence; /* Tag 0x0300 */
+ UCHAR ICC_Interface_Status; /* Tag 0x0301 */
+ UCHAR ATR[MAX_ATR_SIZE]; /* Tag 0x0303 */
+ UCHAR ICC_Type; /* Tag 0x0304 */
+
+ } ICC_STATE, *PICC_STATE;
+
+ typedef struct _PROTOCOL_OPTIONS {
+
+ DWORD Protocol_Type; /* Tag 0x0201 */
+ DWORD Current_Clock; /* Tag 0x0202 */
+ DWORD Current_F; /* Tag 0x0203 */
+ DWORD Current_D; /* Tag 0x0204 */
+ DWORD Current_N; /* Tag 0x0205 */
+ DWORD Current_W; /* Tag 0x0206 */
+ DWORD Current_IFSC; /* Tag 0x0207 */
+ DWORD Current_IFSD; /* Tag 0x0208 */
+ DWORD Current_BWT; /* Tag 0x0209 */
+ DWORD Current_CWT; /* Tag 0x020A */
+ DWORD Current_EBC; /* Tag 0x020B */
+ } PROTOCOL_OPTIONS, *PPROTOCOL_OPTIONS;
+
+ typedef struct _SCARD_IO_HEADER {
+ DWORD Protocol;
+ DWORD Length;
+ } SCARD_IO_HEADER, *PSCARD_IO_HEADER;
+
+ /* End of structure list */
+
+
+
+ /* The list of tags should be alot more but
+ this is all I use in the meantime */
+
+#define TAG_IFD_ATR 0x0303
+#define TAG_IFD_SLOTNUM 0x0180
+#define TAG_IFD_SLOTS_NUMBER 0x0FAE
+#define TAG_IFD_SIMULTANEOUS_ACCESS 0x0FAF
+
+ /* End of tag list */
+
+
+
+ /* List of defines available to ifdhandler */
+
+#define IFD_POWER_UP 500
+#define IFD_POWER_DOWN 501
+#define IFD_RESET 502
+
+#define IFD_NEGOTIATE_PTS1 1
+#define IFD_NEGOTIATE_PTS2 2
+#define IFD_NEGOTIATE_PTS3 4
+
+#define IFD_SUCCESS 0
+#define IFD_ERROR_TAG 600
+#define IFD_ERROR_SET_FAILURE 601
+#define IFD_ERROR_VALUE_READ_ONLY 602
+#define IFD_ERROR_PTS_FAILURE 605
+#define IFD_ERROR_NOT_SUPPORTED 606
+#define IFD_PROTOCOL_NOT_SUPPORTED 607
+#define IFD_ERROR_POWER_ACTION 608
+#define IFD_ERROR_SWALLOW 609
+#define IFD_ERROR_EJECT 610
+#define IFD_ERROR_CONFISCATE 611
+#define IFD_COMMUNICATION_ERROR 612
+#define IFD_RESPONSE_TIMEOUT 613
+#define IFD_NOT_SUPPORTED 614
+#define IFD_ICC_PRESENT 615
+#define IFD_ICC_NOT_PRESENT 616
+
+ /* List of Defined Functions Available to IFD_Handler */
+
+ RESPONSECODE IFDHCreateChannel ( DWORD, DWORD );
+ RESPONSECODE IFDHCloseChannel ( DWORD );
+ RESPONSECODE IFDHGetCapabilities ( DWORD, DWORD, PDWORD,
+ PUCHAR );
+ RESPONSECODE IFDHSetCapabilities ( DWORD, DWORD, DWORD, PUCHAR );
+ RESPONSECODE IFDHSetProtocolParameters ( DWORD, DWORD, UCHAR,
+ UCHAR, UCHAR, UCHAR );
+ RESPONSECODE IFDHPowerICC ( DWORD, DWORD, PUCHAR, PDWORD );
+ RESPONSECODE IFDHTransmitToICC ( DWORD, SCARD_IO_HEADER, PUCHAR,
+ DWORD, PUCHAR, PDWORD,
+ PSCARD_IO_HEADER );
+ RESPONSECODE IFDHControl ( DWORD, PUCHAR, DWORD,
+ PUCHAR, PDWORD );
+ RESPONSECODE IFDHICCPresence( DWORD );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ifd_hander_h_ */
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/pcscdefines.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/pcscdefines.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/pcscdefines.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,38 @@
+/*****************************************************************
+/
+/ File : pcscdefines.h
+/ Author : David Corcoran <corcoran at linuxnet.com>
+/ Date : June 15, 2000
+/ Purpose: This provides PC/SC shared defines.
+/ See http://www.linuxnet.com for more information.
+/ License: See file COPYING.BSD
+/
+/
+******************************************************************/
+
+#ifndef _pcscdefines_h_
+#define _pcscdefines_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ // do not use RESPONSECODE (long, 64 bits) when 32 bits are enough
+ typedef int ifd_t;
+
+ typedef enum {
+ STATUS_SUCCESS = 0xFA,
+ STATUS_UNSUCCESSFUL = 0xFB,
+ STATUS_COMM_ERROR = 0xFC,
+ STATUS_DEVICE_PROTOCOL_ERROR = 0xFD
+ } status_t;
+
+ #define MAX_RESPONSE_SIZE 264
+ #define MAX_ATR_SIZE 33
+ #define PCSCLITE_MAX_CHANNELS 16 /* Maximum channels */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _pcscdefines_h_ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,146 @@
+/*
+ * tools.c
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#include "tools.h"
+#include "global.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <syslog.h>
+
+LogLevel bGlobalLogLevel = LogLevelMaximum;
+BYTE bLogging = 1;
+LogType bGlobalLogType = LogTypeStderr; //LogTypeStderr;LogTypeSysLog
+
+// Logging tools
+void LogMessage(const char * pcFile, WORD wLine, BYTE bLogLevel, const char* pcFormat,...)
+{
+ va_list ap;
+ int rv;
+ char *pcLogMessage = NULL;
+
+ // Do not log if log level > 0 and logging is disabled
+ if ( (!bLogging) && bGlobalLogLevel )
+ {
+ return;
+ }
+ if ( bGlobalLogLevel >= bLogLevel )
+ {
+
+ va_start(ap, pcFormat);
+ rv = vasprintf(&pcLogMessage, pcFormat, ap);
+ if ( rv == -1 )
+ {
+ pcLogMessage = "Could not allocate buffer for vasprintf";
+ }
+ va_end(ap);
+
+ if ( bGlobalLogType == LogTypeSysLog)
+ {
+ syslog(LOG_INFO, "%s (%d): %s", pcFile, (int)wLine, pcLogMessage);
+ }
+ else
+ {
+ fprintf(stderr, "%s (%d): %s\n", pcFile, (int)wLine, pcLogMessage);
+ }
+ if ( rv != -1 )
+ {
+ free(pcLogMessage);
+ }
+ }
+}
+void LogHexBuffer(const char * pcFile, WORD wLine, BYTE bLogLevel,
+ BYTE * pbData, WORD wLength, const char* pcFormat,...)
+{
+ WORD index;
+ va_list ap;
+ int rv, rvHex = -1;
+ char *pcLogMessage = NULL;
+ char *pcLogHexData = NULL;
+ char *pcLogHexCurrent;
+
+ if ( (!bLogging) && bGlobalLogLevel )
+ {
+ return;
+ }
+ if ( bGlobalLogLevel >= bLogLevel )
+ {
+ va_start(ap, pcFormat);
+ rv = vasprintf(&pcLogMessage, pcFormat, ap);
+ if ( rv == -1 )
+ {
+ pcLogMessage = "Could not allocate buffer for vasprintf";
+
+ }
+ else
+ {
+ // Allocate buffer string for printing of data
+ // Each byte is 3 chars (1 per nibble + space)
+ // Plus 1 for NULL byte
+ pcLogHexData = malloc(wLength * 3 * sizeof(char) + 1);
+ rvHex = 0;
+ if ( pcLogHexData == NULL )
+ {
+ rvHex = -1;
+ pcLogHexData = "Could not allocate buffer to print binary buffer";
+ }
+ else
+ {
+ pcLogHexCurrent = pcLogHexData;
+ for (index = 0; index < wLength; index++)
+ {
+ sprintf(pcLogHexCurrent, "%02X ", pbData[index]);
+ pcLogHexCurrent += 3 * sizeof(char);
+ }
+ }
+ }
+ va_end(ap);
+
+ if ( bGlobalLogType == LogTypeSysLog)
+ {
+ syslog(LOG_INFO, "%s (%d): %s : %s", pcFile, (int)wLine, pcLogMessage,
+ pcLogHexData);
+ }
+ else
+ {
+ fprintf(stderr, "%s (%d): %s : %s\n", pcFile, (int)wLine, pcLogMessage,
+ pcLogHexData);
+ }
+ if ( rv != -1 )
+ {
+ free(pcLogMessage);
+ }
+ if ( rvHex != -1 )
+ {
+ free(pcLogHexData);
+ }
+ }
+}
+
+void SetLogLevel(BYTE bLogLevel)
+{
+ bGlobalLogLevel = bLogLevel;
+}
+
+void SetLogType(LogType bLogtype)
+{
+ bGlobalLogType = bLogtype;
+}
+
+void StartLogging()
+{
+ bLogging = 1;
+}
+
+void StopLogging()
+{
+ bLogging = 0;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/common/tools.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,58 @@
+/*
+ * tools.h
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#ifndef __TOOLS_H__
+#define __TOOLS_H__
+#include "wintypes.h"
+
+
+// Get the value of a key in a bundle according to its identifier
+// This function is not time-optimal if many keys are to be searched
+// on the same bundle (the bundle is re-opened and re-parsed at
+// every call
+const char* ParseInfoPlist(const char *bundleIdentifier, const char *keyName);
+
+
+DWORD CCIDToHostLong(DWORD dword);
+DWORD HostToCCIDLong(DWORD dword);
+WORD CCIDToHostWord(WORD word);
+WORD HostToCCIDWord(WORD word);
+
+#define LunToSlotNb(Lun) ((WORD)((Lun) & 0x0000FFFF))
+#define LunToReaderLun(Lun) ((WORD)((Lun) >> 16))
+
+typedef enum {
+ LogTypeSysLog = 0x00,
+ LogTypeStderr = 0x01
+} LogType;
+typedef enum {
+ LogLevelCritical = 0x00,
+ LogLevelImportant = 0x01,
+ LogLevelVerbose = 0x02,
+ LogLevelVeryVerbose = 0x03,
+ LogLevelMaximum = 0xFF
+} LogLevel;
+
+
+// Logging tools
+// pcLine should be called as __FILE__
+// wLine should be called as __LINE__
+// LogMessage( __FILE__, __LINE__, LogLevelCritical, "Move failed, rv = %08X", rv);
+void LogMessage(const char * pcFile, WORD wLine, BYTE bLogLevel, const char* pcFormat,...);
+void LogHexBuffer(const char * pcFile, WORD wLine, BYTE bLogLevel,
+ BYTE * pbData, WORD wLength, const char* pcFormat,...);
+
+void SetLogLevel(BYTE bLogLevel);
+void SetLogType(LogType bLogtype);
+// Logging is only stopped for log levels > 0
+void StartLogging();
+void StopLogging();
+
+#endif
\ No newline at end of file
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/specific/MacOSX/tools_mosx.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/specific/MacOSX/tools_mosx.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CCIDDriver/specific/MacOSX/tools_mosx.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,88 @@
+/*
+ * tools_mosx.c
+ * ifd-CCID
+ *
+ * Created by JL on Mon Feb 10 2003.
+ * Copyright (c) 2003 Jean-Luc Giraud. All rights reserved.
+ * See COPYING file for license.
+ *
+ */
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreFoundation/CFURL.h>
+#include <CoreFoundation/CFPlugIn.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/usb/IOUSBLib.h>
+
+
+#include "tools.h"
+
+
+
+const char* ParseInfoPlist(const char *bundleIdentifier, const char *keyName)
+{
+ CFBundleRef myBundle;
+ CFStringRef propertyString;
+ CFDictionaryRef bundleInfoDict;
+ const char *cStringValue;
+ CFStringRef stringCF;
+
+ stringCF = CFStringCreateWithCString ( NULL, bundleIdentifier, kCFStringEncodingASCII);
+ if (stringCF == NULL)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "bundleIdentiferCF error");
+ return NULL;
+ }
+
+
+ // Look for a bundle using its identifier
+ myBundle = CFBundleGetBundleWithIdentifier(stringCF);
+ if ( !myBundle )
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Bundle Identifier not found: %s", bundleIdentifier);
+ return NULL;
+ }
+ bundleInfoDict = CFBundleGetInfoDictionary(myBundle);
+ if (bundleInfoDict == NULL)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Bundle InfoDic error");
+ return NULL;
+ }
+
+ stringCF = CFStringCreateWithCString ( NULL, keyName, kCFStringEncodingASCII);
+ if (stringCF == NULL)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "keyName error");
+ return NULL;
+ }
+
+ propertyString = CFDictionaryGetValue(bundleInfoDict, stringCF);
+ CFRelease(stringCF);
+ if (propertyString == NULL)
+ {
+ LogMessage( __FILE__, __LINE__, LogLevelCritical, "Bundle InfoDic error: %s not found", keyName);
+ return NULL;
+ }
+
+ cStringValue = CFStringGetCStringPtr(propertyString,
+ CFStringGetSystemEncoding());
+ return cStringValue;
+}
+
+
+DWORD CCIDToHostLong(DWORD dword)
+{
+ return (USBToHostLong((UInt32) dword));
+}
+DWORD HostToCCIDLong(DWORD dword)
+{
+ return (HostToUSBLong((UInt32) dword));
+}
+WORD CCIDToHostWord(WORD word)
+{
+ return (USBToHostWord((UInt16) word));
+}
+WORD HostToCCIDWord(WORD word)
+{
+ return (USBToHostWord((UInt16) word));
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,3040 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : cryptoflex.c
+ Package: Cryptoflex Plugin
+ Author : David Corcoran
+ Piotr Gorak
+ Date : 09/26/01
+ License: Copyright (C) 2001 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts the Card Edge Interface APDU's
+ into client side function calls.
+
+********************************************************************/
+
+#ifdef WIN32
+#include "../win32/CFlexPlugin.h"
+#endif
+
+#ifndef __APPLE__
+#include <musclecard.h>
+#else
+#include <PCSC/musclecard.h>
+#endif
+
+#include "cryptoflex.h"
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define CRYPTOFLEX_RSA_KEYSTART -1
+#define CRYPTOFLEX_DES_KEYSTART 1
+#define CRYPTOFLEX_OBJ_DIR 0x3FCE
+#define CRYPTOFLEX_MSC_KEY_DIR 0x3FCF
+#define CRYPTOFLEX_INFOBJ_ID "#FFFE"
+#define CRYPTOFLEX_INFOBJ_LEN 0x0080 /* 128 bytes */
+#define CRYPTOFLEX_MAXMSC_KEY_NUM 0x0005 /* 3 public, 3 private 0-5 */
+#define CRYPTOFLEX_MAX_KEYS 0x0006
+
+typedef struct {
+ MSCUChar8 pBuffer[MAX_BUFFER_SIZE];
+ MSCULong32 bufferSize;
+ MSCUChar8 apduResponse[MAX_BUFFER_SIZE];
+ MSCULong32 apduResponseSize;
+ LPSCARD_IO_REQUEST ioType;
+} MSCTransmitBuffer, *MSCLPTransmitBuffer;
+
+
+static MSCUChar8 keyInfoBytes[CRYPTOFLEX_INFOBJ_LEN];
+static int suppressResponse = 0;
+
+/* Some local function definitions */
+
+MSC_RV convertPCSC( MSCLong32 );
+int idToString( MSCString, MSCULong32 );
+int stringToID( MSCPUShort16, MSCString );
+int bytesToString( MSCString, MSCPUChar8 );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCSelect(MSCLPTokenConnection, MSCULong32 );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGetResponse(MSCLPTokenConnection, MSCUChar8, MSCPUChar8 );
+MSCUShort16 convertSW( MSCPUChar8 );
+void MemCopy16( MSCPUChar8, MSCPUShort16 );
+void MemCopy32( MSCPUChar8, MSCPULong32 );
+void MemCopyTo16( MSCPUShort16, MSCPUChar8 );
+void MemCopyTo32( MSCPULong32, MSCPUChar8 );
+MSCUShort16 getUShort16( MSCPUChar8 );
+void setUShort16( MSCPUChar8, MSCUShort16 );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection, MSCLPTransmitBuffer );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCReadAllocateObject( MSCLPTokenConnection, MSCString,
+ MSCPUChar8*, MSCPULong32 );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCReadLargeObjectOffCB( MSCLPTokenConnection,
+ MSCString, MSCULong32,
+ MSCPUChar8, MSCULong32,
+ LPRWEventCallback rwCallback,
+ MSCPVoid32 addParams );
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteLargeObjectOffCB( MSCLPTokenConnection,
+ MSCString, MSCULong32, MSCPUChar8,
+ MSCULong32, LPRWEventCallback rwCallback,
+ MSCPVoid32 addParams );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCListKeys( MSCLPTokenConnection, MSCUChar8, MSCLPKeyInfo);
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteObject( MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCPUChar8, MSCUChar8 );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCReadObject( MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCPUChar8, MSCUChar8 );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCListObjects( MSCLPTokenConnection,
+ MSCUChar8, MSCLPObjectInfo );
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCIdentifyToken( MSCLPTokenConnection );
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV mapCryptoflexKeys(MSCLPTokenConnection pConnection, MSCUChar8 keyType,
+ MSCUShort16 keySize, MSCUChar8 mscKeyNum,
+ MSCPUChar8 cflKeyNum);
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCCreateObject( MSCLPTokenConnection,
+ MSCString, MSCULong32,
+ MSCLPObjectACL );
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCDeleteObject( MSCLPTokenConnection,
+ MSCString, MSCUChar8 );
+
+MSC_RV mapCryptoflexKeys(MSCLPTokenConnection pConnection, MSCUChar8 keyType,
+ MSCUShort16 keySize, MSCUChar8 mscKeyNum,
+ MSCPUChar8 cflKeyNum) {
+
+ MSCLong32 rv;
+ MSCKeyInfo keyStruct;
+ MSCUChar8 targetCFNum;
+ char highestKey;
+ int i;
+
+ typedef struct {
+ MSCUChar8 keyNumCF;
+ MSCUChar8 keyType;
+ } _keyMask;
+
+ _keyMask keyMask[MSC_MAX_KEYS];
+
+ targetCFNum = 0xFF;
+
+ if ( keyType == MSC_KEY_DES || keyType == MSC_KEY_3DES ||
+ keyType == MSC_KEY_3DES3 ) {
+ highestKey = CRYPTOFLEX_DES_KEYSTART; /* Des keys start from 2 */
+ } else if ( keyType == MSC_KEY_RSA_PUBLIC ||
+ keyType == MSC_KEY_RSA_PRIVATE ||
+ keyType == MSC_KEY_RSA_PRIVATE_CRT ) {
+ highestKey = CRYPTOFLEX_RSA_KEYSTART; /* RSA keys start from 0 */
+ } else {
+ return MSC_INVALID_PARAMETER;
+ }
+
+
+ for (i=0; i < MSC_MAX_KEYS; i++) {
+ keyMask[i].keyNumCF = 0xFF;
+ keyMask[i].keyType = 0xFF;
+ }
+
+
+ /* Algorithm:
+
+ List keys
+
+ If a match on numbers occurs:
+
+ Errors:
+ - If they key type/size doesn't match the existing key.
+
+ Otherwise:
+
+ - Find the next available spot and generate the keys
+ */
+
+ rv = PL_MSCListKeys(pConnection, MSC_SEQUENCE_RESET, &keyStruct);
+
+ if ( rv != MSC_SEQUENCE_END ) {
+
+ do {
+
+ if ( keyStruct.keyNum == mscKeyNum ) {
+
+ if ( targetCFNum != 0xFF ) {
+ /* 2 keys with the same number, ouch */
+ return MSC_INTERNAL_ERROR;
+ }
+
+ if ( keyStruct.keyType == keyType &&
+ keyStruct.keySize == keySize ) {
+ targetCFNum = keyStruct.keyPartner;
+ } else {
+ return MSC_INVALID_PARAMETER;
+ }
+ }
+
+ /* Caching - indice in mask is MSC key num, keyNumCF is
+ the cryptoflex key number, and type is the key type */
+
+ keyMask[keyStruct.keyNum].keyNumCF = keyStruct.keyPartner;
+ keyMask[keyStruct.keyNum].keyType = keyStruct.keyType;
+
+ rv = PL_MSCListKeys(pConnection, MSC_SEQUENCE_NEXT, &keyStruct);
+ } while ( rv != MSC_SEQUENCE_END );
+ }
+
+ if (targetCFNum != 0xFF) {
+ /* matching key num, type, and size - regenerate */
+ *cflKeyNum = targetCFNum;
+ return MSC_SUCCESS;
+ } else {
+ /* No matching number - lets find one for that type of key */
+
+ for (i=0; i < MSC_MAX_KEYS; i++) {
+ if ( keyMask[i].keyType == keyType ) {
+ if ( keyMask[i].keyNumCF > highestKey ) {
+ highestKey = keyMask[i].keyNumCF;
+ }
+ }
+ }
+
+ /* Only support one more DES key, for now */
+
+ if (keyType == MSC_KEY_DES || keyType == MSC_KEY_3DES ||
+ keyType == MSC_KEY_3DES3) {
+ if (highestKey != CRYPTOFLEX_DES_KEYSTART) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+ }
+
+ *cflKeyNum = highestKey + 1;
+ return MSC_SUCCESS;
+ }
+
+ return MSC_INVALID_PARAMETER;
+}
+
+
+void MemCopyReverse(unsigned char *output, unsigned char *input, int length) {
+
+ int i, j;
+
+ j=0;
+
+ for (i=length-1; i >=0; i--) {
+ output[j++] = input[i];
+ }
+
+}
+
+/* Private helpers */
+
+unsigned char ACL2Byte(MSCLPObjectACL pObjectACL)
+{
+
+ unsigned char retByte;
+
+ retByte = 0x00;
+
+ if ( pObjectACL->readPermission == MSC_AUT_ALL ) {
+ retByte = 0x00;
+ } else if ( pObjectACL->readPermission == MSC_AUT_NONE ) {
+ retByte |= 0xF0;
+ }
+
+ if ( pObjectACL->writePermission == MSC_AUT_ALL ) {
+ retByte |= 0x00;
+ } else if ( pObjectACL->writePermission == MSC_AUT_NONE ) {
+ retByte |= 0x0F;
+ }
+
+ /* Check for CHV 1 */
+ if ( pObjectACL->readPermission & MSC_AUT_PIN_1 ) {
+ retByte |= 0x10;
+ }
+
+ if ( pObjectACL->writePermission & MSC_AUT_PIN_1 ) {
+ retByte |= 0x01;
+ }
+
+ /* Check for AUT */
+ if ( pObjectACL->readPermission & MSC_AUT_PIN_0 ) {
+ retByte |= 0x40;
+ }
+
+ if ( pObjectACL->writePermission & MSC_AUT_PIN_0 ) {
+ retByte |= 0x04;
+ }
+
+ return retByte;
+}
+
+void Byte2ACL(unsigned char inByte, MSCLPObjectACL pObjectACL)
+{
+
+ pObjectACL->readPermission = 0;
+ pObjectACL->writePermission = 0;
+ pObjectACL->deletePermission = 0;
+
+ if ( (inByte/256) == 0x00 ) {
+ pObjectACL->readPermission = MSC_AUT_ALL;
+ } else if ((inByte/256) == 0xF ) {
+ pObjectACL->readPermission = MSC_AUT_NONE;
+ }
+
+ if ( (inByte%256) == 0x00 ) {
+ pObjectACL->writePermission = MSC_AUT_ALL;
+ } else if ((inByte%256) == 0xF ) {
+ pObjectACL->writePermission = MSC_AUT_NONE;
+ }
+
+ /* Check for CHV 1 */
+ if ( inByte & 0x10 ) {
+ pObjectACL->readPermission |= MSC_AUT_PIN_1;
+ }
+
+ if ( inByte & 0x01 ) {
+ pObjectACL->writePermission |= MSC_AUT_PIN_1;
+ }
+
+ /* Check for AUT */
+ if ( inByte & 0x40 ) {
+ pObjectACL->readPermission |= MSC_AUT_PIN_0;
+ }
+
+ if ( inByte & 0x04 ) {
+ pObjectACL->writePermission |= MSC_AUT_PIN_0;
+ }
+
+ /* Delete permission is static */
+ pObjectACL->deletePermission = MSC_AUT_PIN_1;
+
+}
+
+
+
+MSC_RV PL_MSCReadKeyInfo( MSCLPTokenConnection pConnection,
+ MSCLPKeyInfo keyInfo ) {
+ MSCLong32 rv;
+ MSCUChar8 currentPointer;
+
+ /* Read the whole file and cache it until it is reset */
+ /* Must do this for performance reasons */
+
+ if ( keyInfo == 0 ) {
+ rv = PL_MSCReadObject(pConnection, CRYPTOFLEX_INFOBJ_ID,
+ 0, keyInfoBytes,
+ MSC_SIZEOF_KEYINFO*CRYPTOFLEX_MAX_KEYS);
+ return rv;
+ }
+
+
+ currentPointer = MSC_SIZEOF_KEYINFO * keyInfo->keyNum;
+
+ keyInfo->keyNum = keyInfoBytes[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYNUMBER;
+ keyInfo->keyType = keyInfoBytes[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYTYPE;
+ keyInfo->keyPartner = keyInfoBytes[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYPARTNER;
+ keyInfo->keyMapping = keyInfoBytes[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYMAPPING;
+ MemCopyTo16(&keyInfo->keySize, &keyInfoBytes[currentPointer]);
+ currentPointer += MSC_SIZEOF_KEYSIZE;
+
+ /* copy the policy */
+
+ MemCopyTo16(&keyInfo->keyPolicy.cipherMode,
+ &keyInfoBytes[currentPointer]);
+ currentPointer += MSC_SIZEOF_POLICYVALUE;
+ MemCopyTo16(&keyInfo->keyPolicy.cipherDirection,
+ &keyInfoBytes[currentPointer]);
+ currentPointer += MSC_SIZEOF_POLICYVALUE;
+
+ /* copy the ACL */
+
+ MemCopyTo16(&keyInfo->keyACL.readPermission, &keyInfoBytes[currentPointer]);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+ MemCopyTo16(&keyInfo->keyACL.writePermission, &keyInfoBytes[currentPointer]);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+ MemCopyTo16(&keyInfo->keyACL.usePermission, &keyInfoBytes[currentPointer]);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ return MSC_SUCCESS;
+}
+
+
+MSC_RV PL_MSCWriteKeyInfo( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCUChar8 keyType, MSCUChar8 keyPartner,
+ MSCUChar8 keyMapping, MSCUShort16 keySize,
+ MSCLPKeyPolicy keyPolicy, MSCLPKeyACL keyACL ) {
+
+ MSCLong32 rv;
+
+ MSCUChar8 keyInfoBytes[MSC_SIZEOF_KEYINFO];
+ MSCUChar8 currentPointer;
+
+ currentPointer = 0;
+ keyInfoBytes[currentPointer] = keyNum;
+ currentPointer += MSC_SIZEOF_KEYNUMBER;
+ keyInfoBytes[currentPointer] = keyType;
+ currentPointer += MSC_SIZEOF_KEYTYPE;
+ keyInfoBytes[currentPointer] = keyPartner;
+ currentPointer += MSC_SIZEOF_KEYPARTNER;
+ keyInfoBytes[currentPointer] = keyMapping;
+ currentPointer += MSC_SIZEOF_KEYMAPPING;
+ MemCopy16(&keyInfoBytes[currentPointer], &keySize);
+ currentPointer += MSC_SIZEOF_KEYSIZE;
+
+ /* copy the policy */
+
+ MemCopy16(&keyInfoBytes[currentPointer], &keyPolicy->cipherMode);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+ MemCopy16(&keyInfoBytes[currentPointer], &keyPolicy->cipherDirection);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ /* copy the acl */
+
+ MemCopy16(&keyInfoBytes[currentPointer], &keyACL->readPermission);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+ MemCopy16(&keyInfoBytes[currentPointer], &keyACL->writePermission);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+ MemCopy16(&keyInfoBytes[currentPointer], &keyACL->usePermission);
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ rv = PL_MSCWriteObject(pConnection, CRYPTOFLEX_INFOBJ_ID,
+ MSC_SIZEOF_KEYINFO*keyNum,
+ keyInfoBytes, MSC_SIZEOF_KEYINFO);
+ return rv;
+}
+
+
+MSC_RV PL_MSCVerifyKey(MSCLPTokenConnection pConnection,
+ MSCPUChar8 key, MSCUChar8 key_length) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = 0x2A;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x01;
+ pBuffer[OFFSET_P3] = key_length;
+
+ memcpy(&pBuffer[OFFSET_DATA], key, key_length);
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if(transmitBuffer.apduResponseSize == 2) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteFramework( MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams ) {
+
+ MSCLong32 rv;
+ MSCULong32 rCV;
+ MSCUChar8 rx[200];
+
+ MSCUChar8 deleteObjDir[7] = {0xF0, 0xE4, 0x00, 0x00, 0x02, 0x3F, 0xCE};
+ MSCUChar8 deleteInfFile[7] = {0xF0, 0xE4, 0x00, 0x00, 0x02, 0xFF, 0xFE};
+ MSCUChar8 deleteKeyDir[7] = {0xF0, 0xE4, 0x00, 0x00, 0x02, 0x3F, 0xCF};
+ MSCUChar8 deletePubFile[7] = {0xF0, 0xE4, 0x00, 0x00, 0x02, 0x10, 0x12};
+ MSCUChar8 deletePrvFile[7] = {0xF0, 0xE4, 0x00, 0x00, 0x02, 0x00, 0x12};
+ MSCUChar8 deletePinFile[7] = {0xF0, 0xE4, 0x00, 0x00, 0x02, 0x00, 0x00};
+
+ MSCUChar8 verifyKey[13] = {0xF0, 0x2A, 0x00, 0x01, 0x08, 0x2C, 0x15,
+ 0xE5, 0x26, 0xE9, 0x3E, 0x8A, 0x19};
+
+ MSCUChar8 createObjDir[21] = {0xF0, 0xE0, 0x00, 0x00, 0x10, 0xFF, 0xFF,
+ 0x61, 0xA8, 0x3F, 0xCE, 0x38, 0x00, 0x00,
+ 0x10, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00};
+
+ MSCUChar8 createInfFile[21] = {0xF0, 0xE0, 0x00, 0x01, 0x10, 0xFF, 0xFF,
+ 0x00, 0x80, 0xFF, 0xFE, 0x01, 0x00, 0x01,
+ 0x44, 0x44, 0x01, 0x03, 0x00, 0x00, 0x00};
+
+ MSCUChar8 createKeyDir[21] = {0xF0, 0xE0, 0x00, 0x00, 0x10, 0xFF, 0xFF,
+ 0x05, 0x50, 0x3F, 0xCF, 0x38, 0x00, 0x00,
+ 0x44, 0x00, 0x01, 0x03, 0x00, 0x11, 0x00};
+
+ /* Note: the Write Binary 8 LSB should be changed for AUT0 */
+
+ MSCUChar8 createPrivFile[21] = {0xF0, 0xE0, 0x00, 0x01, 0x10, 0xFF, 0xFF,
+ 0x02, 0x98, 0x00, 0x12, 0x01, 0x00, 0xF1,
+ 0xFF, 0x11, 0x01, 0x03, 0x00, 0x00, 0x00};
+
+ MSCUChar8 createPubFile[21] = { 0xF0, 0xE0, 0x00, 0x01, 0x10, 0xF1, 0xFF,
+ 0x02, 0x98, 0x10, 0x12, 0x01, 0x00, 0x01,
+ 0xFF, 0x44, 0x01, 0x03, 0x00, 0x00, 0x00};
+
+ MSCUChar8 createPinFile[21] = { 0xF0, 0xE0, 0x00, 0x01, 0x10, 0xFF, 0xFF,
+ 0x00, 0x17, 0x00, 0x00, 0x01, 0x00, 0xF0,
+ 0xFF, 0x44, 0x01, 0x03, 0x00, 0x00, 0x00};
+
+ MSCUChar8 writeDefaultPin[28] = { 0xC0, 0xD6, 0x00, 0x00, 0x17, 0xFF, 0xFF,
+ 0xFF, 'M', 'u', 's', 'c', 'l', 'e',
+ '0', '0', 0x05, 0x05, 'M', 'u', 's', 'c',
+ 'l', 'e', '0', '1', 0x05, 0x05};
+
+ MSCUChar8 writeDefaultAAK[17] = { 0xC0, 0xD6, 0x00, 0x0D, 0x0C, 0x08, 0x00,
+ 'M', 'u', 's', 'c', 'l', 'e', '0', '0',
+ 0x0A, 0x0A };
+
+ /* FIX :: Add support for alternative transport keys */
+
+ if ( pInitParams->transportBehavior == MSC_INIT_DEFAULT_KEY ) {
+ /* Do nothing */
+ } else if ( pInitParams->transportBehavior == MSC_INIT_IGNORE_KEY ) {
+ /* Do nothing */
+ } else if ( pInitParams->transportBehavior == MSC_INIT_USE_KEY ) {
+ if ( pInitParams->transportKeyLen != 8 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+ memcpy(&verifyKey[5], pInitParams->transportKey, 8);
+ }
+
+ if ( pInitParams->objectMemory == 0 ) {
+ pInitParams->objectMemory = 8500;
+ }
+
+ if (pInitParams->newTransportKeyLen == 8) {
+ memcpy(&writeDefaultAAK[7], pInitParams->newTransportKey, 8);
+ }
+
+ if (pInitParams->defaultCHVTries != 0) {
+ writeDefaultPin[16] = pInitParams->defaultCHVTries;
+ writeDefaultPin[17] = pInitParams->defaultCHVTries;
+ }
+
+ if (pInitParams->defaultCHVUnblockTries != 0) {
+ writeDefaultPin[26] = pInitParams->defaultCHVUnblockTries;
+ writeDefaultPin[27] = pInitParams->defaultCHVUnblockTries;
+ }
+
+ if (pInitParams->defaultCHVLen == 8) {
+ memcpy(&writeDefaultPin[8], pInitParams->defaultCHV, 8);
+ }
+
+ if (pInitParams->defaultCHVUnblockSize == 8) {
+ memcpy(&writeDefaultPin[18], pInitParams->defaultCHVUnblock, 8);
+ }
+
+ createObjDir[7] = pInitParams->objectMemory / 256;
+ createObjDir[8] = pInitParams->objectMemory % 256;
+
+ if ( pInitParams->transportBehavior != MSC_INIT_IGNORE_KEY ) {
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ verifyKey, 13, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+ }
+
+ /*************************************/
+ /* Delete this file structure off of */
+ /* the card if it already exists */
+ /*************************************/
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x3FCE);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ deleteInfFile, 7, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x3FCF);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ deletePrvFile, 7, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ deletePinFile, 7, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x3FCF);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ deletePubFile, 7, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ deleteKeyDir, 7, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ deleteObjDir, 7, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+
+
+ /*************************************/
+ /* Add the new file structure */
+ /*************************************/
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ createObjDir, 21, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x3FCE);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ createInfFile, 21, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ createKeyDir, 21, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x3FCF);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ createPubFile, 21, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x3FCF);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ createPrivFile, 21, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ createPinFile, 21, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x0000);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ writeDefaultPin, 28, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+/*************************************************************************/
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, 0x0011);
+
+ rCV = 100;
+ rv = SCardTransmit(pConnection->hCard, SCARD_PCI_T0,
+ writeDefaultAAK, 17, 0, rx, &rCV);
+ if ( rv != SCARD_S_SUCCESS ) return convertPCSC(rv);
+ if ( convertSW(rx) != MSC_SUCCESS ) return convertSW(rx);
+
+ return MSC_SUCCESS;
+}
+
+/* MSC Functions */
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGetStatus( MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCObjectInfo objInfo;
+ MSCULong32 totalMemory, freeMemory;
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = 0xA4;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = 0x02;
+ pBuffer[OFFSET_DATA] = 0x3F;
+ pBuffer[OFFSET_DATA+1] = 0xCE;
+
+ transmitBuffer.bufferSize = 7;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ }
+
+
+ freeMemory = apduResponse[2] * 0x100 + apduResponse[3];
+ totalMemory = freeMemory;
+
+ pStatusInfo->appVersion = 0xFF;
+ pStatusInfo->swVersion = 0xFF;
+ pStatusInfo->usedPINs = 0x01;
+ pStatusInfo->usedKeys = 0x00;
+ pStatusInfo->loggedID = pConnection->loggedIDs;
+
+ rv = PL_MSCListObjects( pConnection, MSC_SEQUENCE_RESET, &objInfo );
+
+ while (rv == MSC_SUCCESS) {
+ totalMemory += objInfo.objectSize;
+ rv = PL_MSCListObjects( pConnection, MSC_SEQUENCE_NEXT, &objInfo );
+ }
+
+ pStatusInfo->totalMemory = totalMemory;
+ pStatusInfo->freeMemory = freeMemory - CRYPTOFLEX_INFOBJ_LEN - 16;
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGetCapabilities( MSCLPTokenConnection pConnection, MSCULong32 Tag,
+ MSCPUChar8 Value, MSCPULong32 Length ) {
+
+ MSCULong32 ulValue;
+ MSCUShort16 usValue;
+ MSCUChar8 ucValue;
+ MSCUChar8 tagType;
+
+ /* 4 - MSCULong32, 2 - MSCUShort16, 1 - MSCUChar8 */
+
+ ulValue = 0; usValue = 0; ucValue = 0; tagType = 0;
+
+ switch(Tag) {
+
+ case MSC_TAG_SUPPORT_FUNCTIONS:
+ ulValue = MSC_SUPPORT_GENKEYS | MSC_SUPPORT_EXPORTKEY |
+ MSC_SUPPORT_COMPUTECRYPT | MSC_SUPPORT_LISTKEYS | MSC_SUPPORT_IMPORTKEY |
+ MSC_SUPPORT_VERIFYPIN | MSC_SUPPORT_CHANGEPIN |
+ MSC_SUPPORT_UNBLOCKPIN | MSC_SUPPORT_LISTPINS |
+ MSC_SUPPORT_CREATEOBJECT | MSC_SUPPORT_DELETEOBJECT |
+ MSC_SUPPORT_WRITEOBJECT | MSC_SUPPORT_READOBJECT |
+ MSC_SUPPORT_LISTOBJECTS | MSC_SUPPORT_LOGOUTALL |
+ MSC_SUPPORT_GETCHALLENGE;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_SUPPORT_CRYPTOALG:
+ ulValue = MSC_SUPPORT_RSA;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_RSA:
+ ulValue = MSC_CAPABLE_RSA_1024 | MSC_CAPABLE_RSA_NOPAD |
+ MSC_CAPABLE_RSA_KEYGEN;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_ATTR:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_IDSIZE:
+ ucValue = 2;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_AUTH:
+ usValue = MSC_AUT_ALL;
+ tagType = 2;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_MAXNUM:
+ ulValue = 100;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_ATTR:
+ ulValue = MSC_CAPABLE_PIN_RESET;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MAXNUM:
+ ucValue = 2;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MINSIZE:
+ ucValue = 1;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MAXSIZE:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_CHARSET:
+ ulValue = MSC_CAPABLE_PIN_A_Z | MSC_CAPABLE_PIN_a_z |
+ MSC_CAPABLE_PIN_0_9 | MSC_CAPABLE_PIN_CALC | MSC_CAPABLE_PIN_NONALPHA;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_POLICY:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_ID_STATE:
+ ucValue = 0;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_RANDOM_MAX:
+ ucValue = 32;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_RANDOM_MIN:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_KEY_AUTH:
+ usValue = MSC_AUT_PIN_1;
+ tagType = 2;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_AUTH:
+ usValue = MSC_AUT_NONE;
+ tagType = 2;
+ break;
+
+ default:
+ return MSC_INVALID_PARAMETER;
+ }
+
+ switch(tagType) {
+ case 1:
+ memcpy(Value, &ucValue, 1);
+ break;
+ case 2:
+ memcpy(Value, &usValue, 2);
+ break;
+ case 4:
+ memcpy(Value, &ulValue, 4);
+ break;
+ }
+
+ *Length = tagType;
+
+ return MSC_SUCCESS;
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCExtendedFeature( MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature, MSCPUChar8 outData,
+ MSCULong32 outLength, MSCPUChar8 inData,
+ MSCPULong32 inLength ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGenerateKeys( MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum, MSCUChar8 pubKeyNum,
+ MSCLPGenKeyParams pParams ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCUChar8 pubKeyNumBak;
+ MSCUChar8 prvKeyNumBak;
+ MSCKeyACL privACL;
+ MSCKeyACL pubACL;
+ MSCPUChar8 pBuffer;
+
+ /* PG: a common key pair number can only be set in Cryptoflex,
+ so enforce that pubKeyNum and prvKeyNum match. */
+
+ /* DC: Musclecard has each key number as a unique number but
+ keys should be in sequence - priv 0, pub 1 ...
+ Here we will set the pubKeyNum to be the same as the
+ private key number, but public keys will be one + the
+ private key number
+ */
+
+ if ( pubKeyNum > CRYPTOFLEX_MAXMSC_KEY_NUM ||
+ prvKeyNum > CRYPTOFLEX_MAXMSC_KEY_NUM ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( pParams->algoType != MSC_GEN_ALG_RSA_CRT ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ prvKeyNumBak = prvKeyNum;
+ pubKeyNumBak = pubKeyNum;
+
+ rv = mapCryptoflexKeys(pConnection, MSC_KEY_RSA_PRIVATE_CRT,
+ pParams->keySize, prvKeyNumBak,
+ &prvKeyNum);
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ rv = mapCryptoflexKeys(pConnection, MSC_KEY_RSA_PUBLIC,
+ pParams->keySize, pubKeyNumBak,
+ &pubKeyNum);
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, 0x3FCF);
+
+ if ( rv != MSC_SUCCESS ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = INS_MSC_GEN_KEYPAIR;
+ pBuffer[OFFSET_P1] = prvKeyNum;
+
+ switch(pParams->keySize) {
+ case 1024:
+ pBuffer[OFFSET_P2] = 0x80;
+ break;
+ case 768:
+ pBuffer[OFFSET_P2] = 0x60;
+ break;
+ case 512:
+ pBuffer[OFFSET_P2] = 0x40;
+ break;
+ default:
+ return MSC_INVALID_PARAMETER;
+ }
+
+ /* PG: length of the public exponent, e */
+
+ if ( pParams->keyGenOptions != MSC_OPT_DEFAULT ) {
+ pBuffer[OFFSET_P3] = pParams->keyGenOptions;
+ /* PG: the public exponent value */
+ memcpy(&pBuffer[OFFSET_DATA], pParams->pOptParams,
+ pParams->optParamsSize);
+
+ transmitBuffer.bufferSize = 5 + pParams->keyGenOptions;
+
+ } else {
+ /* Take the defaults */
+ pBuffer[OFFSET_P3] = 0x04; /* Length of the following */
+ pBuffer[OFFSET_DATA] = 0x01; /* Common public exponent */
+ pBuffer[OFFSET_DATA+1] = 0x00;
+ pBuffer[OFFSET_DATA+2] = 0x01;
+ pBuffer[OFFSET_DATA+3] = 0x00;
+ transmitBuffer.bufferSize = 9;
+ }
+
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+
+ if ( convertSW(apduResponse) == MSC_SUCCESS ) {
+
+ privACL.readPermission = MSC_AUT_NONE;
+ privACL.writePermission = MSC_AUT_PIN_1;
+ privACL.usePermission = MSC_AUT_PIN_1;
+
+ rv = PL_MSCWriteKeyInfo( pConnection, prvKeyNumBak,
+ MSC_KEY_RSA_PRIVATE_CRT,
+ prvKeyNum, pubKeyNumBak,
+ pParams->keySize, &pParams->privateKeyPolicy,
+ &privACL );
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ pubACL.readPermission = MSC_AUT_ALL;
+ pubACL.writePermission = MSC_AUT_PIN_1;
+ pubACL.usePermission = MSC_AUT_PIN_1;
+
+ rv = PL_MSCWriteKeyInfo( pConnection, pubKeyNumBak, MSC_KEY_RSA_PUBLIC,
+ pubKeyNum, prvKeyNumBak, pParams->keySize,
+ &pParams->publicKeyPolicy, &pubACL );
+ return rv;
+ }
+
+
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCImportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL,
+ MSCPUChar8 pKeyBlob, MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy, MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize ) {
+
+ MSCLong32 rv;
+ MSCUChar8 keyBlobCryptoflex[2500];
+ MSCULong32 currentPointer;
+ MSCKeyACL currentACL;
+ MSCUChar8 keyType;
+ MSCUChar8 keyNumBak;
+ MSCUShort16 keySize;
+ MSCULong32 expSize;
+
+ keyNumBak = keyNum;
+ keyType = pKeyBlob[OFFSET_KEYTYPE];
+ MemCopyTo16(&keySize, &pKeyBlob[OFFSET_KEYSIZE]);
+
+
+ if ( keyType != MSC_KEY_RSA_PRIVATE_CRT &&
+ keyType != MSC_KEY_DES &&
+ keyType != MSC_KEY_RSA_PUBLIC )
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ rv = mapCryptoflexKeys(pConnection, keyType,
+ keySize, keyNumBak, &keyNum);
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ if ( keyType == MSC_KEY_RSA_PRIVATE_CRT ) {
+
+ if ( keySize != 1024 ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, 0x3FCF);
+
+ if ( rv != MSC_SUCCESS ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Place the key in bytes in Cryptoflex style */
+
+ currentPointer = 0;
+ keyBlobCryptoflex[currentPointer] = CF_1024_FULLSIZE_1;
+ currentPointer += CF_SIZEOF_MSBLEN;
+ keyBlobCryptoflex[currentPointer] = CF_1024_FULLSIZE_2;
+ currentPointer += CF_SIZEOF_LSBLEN;
+ keyBlobCryptoflex[currentPointer] = keyNum + 1;
+ currentPointer += CF_SIZEOF_KEYNUM;
+
+ /* Copy P */
+
+ MemCopyReverse(&keyBlobCryptoflex[currentPointer],
+ &pKeyBlob[MC_1024_OFFSET_P+2], CF_1024_COMPSIZE);
+
+ currentPointer += CF_1024_COMPSIZE;
+
+ /* Copy Q */
+
+ MemCopyReverse(&keyBlobCryptoflex[currentPointer],
+ &pKeyBlob[MC_1024_OFFSET_Q+2], CF_1024_COMPSIZE);
+
+ currentPointer += CF_1024_COMPSIZE;
+
+ /* Copy PQ */
+
+ MemCopyReverse(&keyBlobCryptoflex[currentPointer],
+ &pKeyBlob[MC_1024_OFFSET_PQ+2], CF_1024_COMPSIZE);
+
+ currentPointer += CF_1024_COMPSIZE;
+
+ /* Copy DP1 */
+
+ MemCopyReverse(&keyBlobCryptoflex[currentPointer],
+ &pKeyBlob[MC_1024_OFFSET_DP1+2], CF_1024_COMPSIZE);
+
+ currentPointer += CF_1024_COMPSIZE;
+
+ /* Copy DQ1 */
+
+ MemCopyReverse(&keyBlobCryptoflex[currentPointer],
+ &pKeyBlob[MC_1024_OFFSET_DQ1+2], CF_1024_COMPSIZE);
+
+ currentPointer += CF_1024_COMPSIZE;
+
+ rv = PL_MSCWriteLargeObjectOffCB( pConnection, "#0x0012",
+ keyNum * CF_1024_FULLSIZE,
+ keyBlobCryptoflex, CF_1024_FULLSIZE,
+ 0, 0 );
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ } else if ( keyType == MSC_KEY_RSA_PUBLIC ) {
+
+ if ( keySize != 1024 ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, 0x3FCF);
+
+ if ( rv != MSC_SUCCESS ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ /* Place the key in bytes in Cryptoflex style */
+
+ currentPointer = 0;
+ keyBlobCryptoflex[currentPointer] = 0x01;
+ currentPointer += CF_SIZEOF_MSBLEN;
+ keyBlobCryptoflex[currentPointer] = 0x47;
+ currentPointer += CF_SIZEOF_LSBLEN;
+ keyBlobCryptoflex[currentPointer] = keyNum + 1;
+ currentPointer += CF_SIZEOF_KEYNUM;
+
+ /* Copy N */
+ memset(&keyBlobCryptoflex[currentPointer],
+ 0x00, MC_1024P_MODSIZE);
+
+ currentPointer += MC_1024P_MODSIZE;
+
+ /* Skip J0 + H */
+ memset(&keyBlobCryptoflex[currentPointer], 0x00, 192);
+ currentPointer += 192;
+
+ /* Copy E */
+ expSize = (pKeyBlob[MC_1024P_EXP] * 256)+pKeyBlob[MC_1024P_EXP+1];
+ memset(&keyBlobCryptoflex[currentPointer], 0x00, 0x04);
+
+ MemCopyReverse(&keyBlobCryptoflex[currentPointer],
+ &pKeyBlob[MC_1024P_EXP+2], expSize);
+
+ rv = PL_MSCWriteLargeObjectOffCB( pConnection, "#0x1012",
+ keyNum * 0x0147,
+ keyBlobCryptoflex, 0x0147,
+ 0, 0 );
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ } else if ( keyType == MSC_KEY_DES ) {
+
+ if ( keySize != 64 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ /* FIX :: Must be careful here - old manual list an RFU byte first
+ but the new manual lists no RFU byte at all
+ */
+
+ keyBlobCryptoflex[0] = 0x08; /* key size */
+ keyBlobCryptoflex[1] = 0x00; /* key type */
+ memcpy(&keyBlobCryptoflex[2], &pKeyBlob[MC_DES_OFFSET_KEY+2], 8);
+ keyBlobCryptoflex[10] = 0x0A;
+ keyBlobCryptoflex[11] = 0x0A;
+
+ rv = PL_MSCWriteObject( pConnection, "#0x0011", CF_DES_OFFSET_UKEY,
+ keyBlobCryptoflex, 0x0C );
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ } else {
+ /* RSA public would go here */
+
+ rv = MSC_UNSUPPORTED_FEATURE;
+ }
+
+ switch(keyType) {
+ case MSC_KEY_RSA_PRIVATE_CRT:
+ case MSC_KEY_RSA_PRIVATE:
+ currentACL.readPermission = MSC_AUT_NONE;
+ currentACL.writePermission = MSC_AUT_PIN_1;
+ currentACL.usePermission = MSC_AUT_PIN_1;
+ break;
+
+ case MSC_KEY_RSA_PUBLIC:
+ currentACL.readPermission = MSC_AUT_ALL;
+ currentACL.writePermission = MSC_AUT_PIN_1;
+ currentACL.usePermission = MSC_AUT_PIN_1;
+ break;
+
+ case MSC_KEY_DES:
+ case MSC_KEY_3DES:
+ case MSC_KEY_3DES3:
+ currentACL.readPermission = MSC_AUT_PIN_0;
+ currentACL.writePermission = MSC_AUT_PIN_0;
+ currentACL.usePermission = MSC_AUT_ALL;
+ break;
+
+ default:
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ rv = PL_MSCWriteKeyInfo( pConnection, keyNumBak, keyType,
+ keyNum, 0xFF, keySize, keyPolicy,
+ ¤tACL );
+
+ return rv;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCExportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize ) {
+
+ MSCLong32 rv;
+ MSCUChar8 keyBuffer[2500];
+ MSCKeyInfo keyStruct;
+ MSCULong32 currentPointer;
+ MSCULong32 blobSize;
+ MSCUShort16 currentVal;
+ MSCUChar8 keyNumCF;
+ int i;
+
+ i=0; blobSize=0; rv=0; currentPointer=0; keyNumCF=0; currentVal=0;
+
+ if ( pConnection == 0 || keyBlobSize == 0 || pKeyBlob == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ keyStruct.keyNum = 0xFF;
+ rv = MSCListKeys(pConnection, MSC_SEQUENCE_RESET, &keyStruct);
+
+ if ( rv != MSC_SEQUENCE_END ) {
+ do {
+ if ( keyStruct.keyNum == keyNum ) {
+ break;
+ }
+ rv = MSCListKeys(pConnection, MSC_SEQUENCE_NEXT, &keyStruct);
+ /* FIX :: potential problem if error occurs ... */
+ } while ( rv != MSC_SEQUENCE_END );
+ }
+
+ /* Match not found */
+ if ( keyStruct.keyNum == 0xFF ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( keyStruct.keyType != MSC_KEY_RSA_PUBLIC ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ keyNumCF = keyStruct.keyPartner;
+
+ /* not sure if this is right */
+
+ rv = PL_MSCReadLargeObjectOffCB( pConnection, "#0x1012",
+ keyNumCF*CF_1024P_FULLSIZE,
+ keyBuffer, CF_1024P_FULLSIZE, 0, 0);
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ /* Copy to a MuscleCard defined RSA_PUB key blob as defined
+ in the protocol spec
+ */
+
+ pKeyBlob[OFFSET_ENCODING] = MSC_BLOB_ENC_PLAIN;
+ pKeyBlob[OFFSET_KEYTYPE] = MSC_KEY_RSA_PUBLIC;
+
+ currentVal = CF_1024_KEYSIZE;
+ MemCopy16(&pKeyBlob[OFFSET_KEYSIZE], ¤tVal);
+
+ currentVal = CF_1024P_MODSIZE;
+ MemCopy16(&pKeyBlob[MC_1024P_MOD], ¤tVal);
+ MemCopyReverse(&pKeyBlob[MC_1024P_MOD + 2],
+ &keyBuffer[CF_1024P_MOD], CF_1024P_MODSIZE);
+
+ currentVal = CF_1024P_EXPSIZE;
+ MemCopy16(&pKeyBlob[MC_1024P_EXP], ¤tVal);
+ MemCopyReverse(&pKeyBlob[MC_1024P_EXP + 2],
+ &keyBuffer[CF_1024P_EXP], CF_1024P_EXPSIZE);
+
+ *keyBlobSize = MC_1024P_FULLSIZE;
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCComputeCrypt( MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCUChar8 cflKeyNum;
+
+ if ( cryptInit->cipherMode == MSC_MODE_RSA_NOPAD ) {
+ /* Some RSA */
+ rv = mapCryptoflexKeys(pConnection, MSC_KEY_RSA_PRIVATE_CRT,
+ 1024, cryptInit->keyNum,
+ &cflKeyNum);
+
+
+ if ( rv != MSC_SUCCESS ) return rv;
+ } else if ( cryptInit->cipherMode == MSC_MODE_DES_ECB_NOPAD ) {
+ /* Some DES */
+ rv = mapCryptoflexKeys(pConnection, MSC_KEY_DES,
+ 64, cryptInit->keyNum,
+ &cflKeyNum);
+ if ( rv != MSC_SUCCESS ) return rv;
+ } else {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, CRYPTOFLEX_MSC_KEY_DIR);
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_COMPUTE_CRYPT;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = cflKeyNum;
+
+ /* PG: 0x40, 0x60, 0x80 - possible lengths of the cryptogram */
+ /* DC: Only support for 1023 bit RSA for now */
+ if(inputDataSize != 8 && inputDataSize != 128)
+ return MSC_INVALID_PARAMETER;
+
+ pBuffer[OFFSET_P3] = inputDataSize;
+
+ /* PG: 64, 96 or 128 bytes (respectively) to be encrypted
+ NOTE: you must enter the data in LSB format */
+ MemCopyReverse(&pBuffer[OFFSET_DATA], pInputData, inputDataSize);
+
+ transmitBuffer.bufferSize = 5 + inputDataSize;
+
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == inputDataSize + 2 ) {
+ *outputDataSize = transmitBuffer.apduResponseSize - 2;
+ MemCopyReverse(pOutputData, apduResponse,
+ *outputDataSize);
+
+ return MSC_SUCCESS;
+ } else if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCExtAuthenticate( MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData,
+ MSCULong32 dataSize )
+{
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ /* PG: Cryptoflex uses DES for external authentication */
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_EXT_AUTH;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ /* PG: the length of the input data
+ (a 1-byte key number plus a 6-byte truncated cryptogram) */
+ pBuffer[OFFSET_P3] = 0x07;
+
+ pBuffer[OFFSET_DATA] = keyNum;
+
+ /* The cryptogram must be 6 bytes long */
+ memcpy(&pBuffer[OFFSET_DATA + 1], pData, 6);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ /* dumpBinary(apduResponse, transmitBuffer.apduResponseSize); */
+ return convertSW(&apduResponse[transmitBuffer.apduResponseSize-2]);
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCListKeys( MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo ) {
+
+ /* PG: Since we don't provide neither AUT nor PRO protection
+ it's useless to give information about these keys */
+
+ /* Dave: One key pair is by default in directory 3FCF
+ more work needs to be done here
+ */
+
+
+ MSCLong32 rv;
+ static MSCUChar8 keyByteMask[CRYPTOFLEX_MAXMSC_KEY_NUM+1];
+ static int sequenceNumber = 0;
+ int i, j;
+
+ if ( seqOption == MSC_SEQUENCE_RESET ) {
+ rv = PL_MSCReadKeyInfo(pConnection, 0);
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ for (i=0; i <= CRYPTOFLEX_MAXMSC_KEY_NUM; i++) {
+ pKeyInfo->keyNum = i;
+ rv = PL_MSCReadKeyInfo(pConnection, pKeyInfo);
+
+ if ( rv != MSC_SUCCESS ) return rv;
+
+ /* Check if the key entry is present or missing */
+ if ( pKeyInfo->keyNum == 0 && pKeyInfo->keyType == 0 &&
+ pKeyInfo->keyPartner == 0 && pKeyInfo->keySize == 0 ) {
+ keyByteMask[i] = 0;
+ } else {
+ keyByteMask[i] = 1;
+ }
+
+ }
+
+ sequenceNumber = 1;
+ } else {
+ sequenceNumber += 1;
+ }
+
+ j = 0;
+
+ for (i=0; i < sequenceNumber; i++) {
+ do {
+ if ( keyByteMask[j] == 1 ) {
+ j += 1;
+ break;
+ }
+
+ j += 1;
+
+ if ( j > CRYPTOFLEX_MAXMSC_KEY_NUM )
+ return MSC_SEQUENCE_END;
+
+ } while (1);
+ }
+
+
+ pKeyInfo->keyNum = j - 1;
+ rv = PL_MSCReadKeyInfo(pConnection, pKeyInfo);
+
+ return rv;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCCreatePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts, MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCVerifyPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode, MSCULong32 pinCodeSize ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ /*
+ if ( pinCodeSize != 8 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+ */
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+
+ if ( pinNum == 0 ) {
+ rv = PL_MSCVerifyKey(pConnection, pPinCode, pinCodeSize);
+ if ( rv == MSC_SUCCESS ) { pConnection->loggedIDs |= MSC_AUT_PIN_0; }
+ return rv;
+ }
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_VERIFY_PIN;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = pinNum;
+ /* PIN code size is enforced by Cryptoflex */
+ pBuffer[OFFSET_P3] = 0x08;
+
+
+ memset(&pBuffer[OFFSET_DATA], 0xFF, 8);
+ memcpy(&pBuffer[OFFSET_DATA], pPinCode, pinCodeSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ if ( convertSW(apduResponse) == MSC_SUCCESS ) {
+ /* FIX :: Only did 4 PINs */
+ switch(pinNum) {
+ case 1:
+ pConnection->loggedIDs |= MSC_AUT_PIN_1;
+ break;
+ case 2:
+ pConnection->loggedIDs |= MSC_AUT_PIN_2;
+ break;
+ case 3:
+ pConnection->loggedIDs |= MSC_AUT_PIN_3;
+ break;
+ case 4:
+ pConnection->loggedIDs |= MSC_AUT_PIN_4;
+ break;
+ };
+ }
+
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCChangePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize ) {
+
+ MSCLong32 rv, rvb;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ if ( pinNum == 0 ) {
+
+ if ( oldPinCodeSize != 8 || newPinCodeSize != 8 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ rv = PL_MSCVerifyKey(pConnection, pOldPinCode, oldPinCodeSize);
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, 0x0011);
+
+ if ( rv != MSC_SUCCESS ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_WRITE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x0D; /* offset for key 1 */
+ pBuffer[OFFSET_P3] = 0x0C;
+
+ pBuffer[OFFSET_DATA] = 0x08;
+ pBuffer[OFFSET_DATA+1] = 0x00;
+ memcpy(&pBuffer[OFFSET_DATA+2], pNewPinCode, 8);
+
+ pBuffer[OFFSET_DATA+10] = 0x05;
+ pBuffer[OFFSET_DATA+11] = 0x05;
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ } else {
+ /* FIX: Add support for additional PINs */
+ /* PG: PIN code size is enforced by Cryptoflex */
+
+ rv = PL_MSCVerifyPIN(pConnection, pinNum, pOldPinCode, oldPinCodeSize);
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, 0x0000);
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_WRITE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = 0x0B;
+ pBuffer[OFFSET_DATA] = 0xFF;
+ pBuffer[OFFSET_DATA+1] = 0xFF;
+ pBuffer[OFFSET_DATA+2] = 0xFF;
+
+
+ memset(&pBuffer[OFFSET_DATA+3], 0xFF, 8);
+ memcpy(&pBuffer[OFFSET_DATA+3], pNewPinCode, newPinCodeSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+ }
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ rvb = PL_MSCSelect(pConnection, 0x3F00);
+ rvb = PL_MSCSelect(pConnection, CRYPTOFLEX_OBJ_DIR);
+
+ if ( rvb != MSC_SUCCESS ) {
+ return rvb;
+ }
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCUnblockPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode, MSCULong32 unblockCodeSize ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = INS_UNBLOCK_PIN;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = pinNum;
+ pBuffer[OFFSET_P3] = 0x10;
+
+ /* PG: Code length is enforced by Cryptoflex */
+ memcpy(&pBuffer[OFFSET_DATA], pUnblockCode, 8);
+
+ /* PG: API PROBLEM: Cryptoflex requires that after the
+ unblocking code the new PIN code must be entered */
+
+ memcpy(&pBuffer[OFFSET_DATA + 8], "Muscle00", 8);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCListPINs( MSCLPTokenConnection pConnection, MSCPUShort16 pPinBitMask ) {
+
+ /* PG: There are only two well-known PINs on Cryptoflex card */
+ *pPinBitMask = 0x00000003;
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCCreateObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 objectSize,
+ MSCLPObjectACL pObjectACL ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCULong32 currentPointer;
+ MSCUShort16 _objectSize;
+ MSCUShort16 _objectID;
+
+ /* PG: conversions */
+ _objectSize = 256 * ((objectSize & 0xFF00) >> 8 ) + (objectSize & 0x00FF);
+
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, CRYPTOFLEX_OBJ_DIR);
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = INS_CREATE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ /* PG: Number of records - used only for linear EFs */
+ pBuffer[OFFSET_P2] = 0x00;
+ /* PG: Assumption: transparent EF not protected by PRO AC */
+ pBuffer[OFFSET_P3] = 0x10;
+
+ currentPointer = 0;
+
+ /* PG: RFU */
+ pBuffer[OFFSET_DATA] = 0xFF;
+ pBuffer[OFFSET_DATA+1] = 0xFF;
+ currentPointer = 2;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &_objectSize);
+ currentPointer += 2;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &_objectID);
+ currentPointer += 2;
+
+ /* PG: Assumption: transparent EF */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x01;
+ currentPointer++;
+
+ /* PG: Access conditions */
+ /* PG: Availibility of Increase and Decrease commands
+ - 0x00 since these commands do not apply to transparent EFs*/
+ pBuffer[OFFSET_DATA+currentPointer] = 0x00;
+ currentPointer++;
+
+ /* PG: Read/Write permissions */
+ pBuffer[OFFSET_DATA+currentPointer] = ACL2Byte(pObjectACL);
+ currentPointer++;
+
+ /* PG: RFU */
+ pBuffer[OFFSET_DATA+currentPointer] = 0xFF;
+ currentPointer++;
+
+ /* PG: Rehabilitate/Invalidate - never possible, since
+ we cannot invoke these commands with this API */
+ pBuffer[OFFSET_DATA+currentPointer] = 0xFF;
+ currentPointer++;
+
+ /* PG: Validation status - activated */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x01;
+ currentPointer++;
+
+ /* PG: Length of the input data from byte 14 to EOF
+ in case of transparent EF must be 0x03 */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x03;
+ currentPointer++;
+
+ /* PG: Key numbers for AC */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x11;
+ currentPointer++;
+ pBuffer[OFFSET_DATA+currentPointer] = 0x11;
+ currentPointer++;
+ pBuffer[OFFSET_DATA+currentPointer] = 0x11;
+ currentPointer++;
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCDeleteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCUChar8 zeroFlag ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCULong32 currentPointer;
+ MSCUShort16 _objectID;
+
+ /* PG: conversions */
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ PL_MSCSelect(pConnection, CRYPTOFLEX_OBJ_DIR);
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = INS_DELETE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = 0x02;
+
+ currentPointer = 0;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &_objectID);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pInputData,
+ MSCUChar8 dataSize ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCULong32 currentPointer;
+ MSCUShort16 _objectID;
+
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+ PL_MSCSelect(pConnection, 0x3F00);
+ if(_objectID == 0x0012) {
+ PL_MSCSelect(pConnection, CRYPTOFLEX_MSC_KEY_DIR);
+ } else if (_objectID == 0x1012 ) {
+ PL_MSCSelect(pConnection, CRYPTOFLEX_MSC_KEY_DIR);
+ } else if ( _objectID == 0x0011 ) {
+ /* stay in root */
+ } else {
+ PL_MSCSelect(pConnection, CRYPTOFLEX_OBJ_DIR);
+ }
+
+ PL_MSCSelect(pConnection, _objectID);
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_WRITE_OBJ;
+ pBuffer[OFFSET_P1] = (offset & 0xFF00) >> 8;
+ pBuffer[OFFSET_P2] = offset & 0x00FF;
+ pBuffer[OFFSET_P3] = dataSize;
+
+ currentPointer = 0;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInputData, dataSize);
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCReadObject( MSCLPTokenConnection pConnection, MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pOutputData,
+ MSCUChar8 dataSize ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCUShort16 _objectID;
+
+
+ if ( stringToID(&_objectID, objectID) ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ PL_MSCSelect(pConnection, 0x3F00);
+
+ if ( _objectID == 0x1012 ) {
+ PL_MSCSelect(pConnection, CRYPTOFLEX_MSC_KEY_DIR);
+ } else {
+ PL_MSCSelect(pConnection, CRYPTOFLEX_OBJ_DIR);
+ }
+
+ PL_MSCSelect(pConnection, _objectID);
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_READ_OBJ;
+ pBuffer[OFFSET_P1] = (offset & 0xFF00) >> 8;
+ pBuffer[OFFSET_P2] = offset & 0x00FF;
+ pBuffer[OFFSET_P3] = dataSize;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else if (transmitBuffer.apduResponseSize == dataSize + 2 ) {
+ memcpy(pOutputData, apduResponse, dataSize);
+ return convertSW(&apduResponse[dataSize]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCListObjects( MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo ) {
+
+ MSCLong32 rv;
+ static int sequenceNumber;
+ MSCTransmitBuffer transmitBuffer;
+ MSCTransmitBuffer transmitBufferB;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 apduResponseB;
+ MSCPUChar8 pBuffer;
+ MSCPUChar8 pBufferB;
+ MSCULong32 currentPointer;
+ MSCUChar8 cTemp[2];
+ int i;
+
+ rv=0; currentPointer=0;
+
+ if ( seqOption == MSC_SEQUENCE_RESET ) {
+ sequenceNumber = 1;
+
+ } else {
+ sequenceNumber += 1;
+ }
+
+ while (1) {
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, CRYPTOFLEX_OBJ_DIR);
+
+ if ( rv != MSC_SUCCESS ) {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = INS_LIST_OBJECTS;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = 0x09;
+
+ transmitBuffer.bufferSize = 5;
+
+ for (i=0; i < sequenceNumber; i++ ) {
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ /* PG: TODO: define a constant here */
+ if ( convertSW(apduResponse) == MSC_OBJECT_NOT_FOUND ) { /* Vinnie 1740 */
+ /* Must have finished */
+ return MSC_SEQUENCE_END;
+ } else {
+ return convertSW(apduResponse);
+ }
+ }
+ } /* End of for ... loop */
+
+ if (transmitBuffer.apduResponseSize == pBuffer[OFFSET_P3] + 2 ) {
+
+ /* PG: Omit 8 most significant 8 bytes which are only used
+ to indicate whether the size of an object was rounded up */
+
+ memcpy(cTemp, &apduResponse[2], 2);
+ bytesToString(pObjectInfo->objectID, cTemp);
+
+ if ( strcmp(pObjectInfo->objectID, CRYPTOFLEX_INFOBJ_ID) == 0 ) {
+ sequenceNumber += 1;
+ continue;
+ }
+
+ /* PG: skipping to byte 7, where access conditions begin */
+
+ Byte2ACL(apduResponse[6], &pObjectInfo->objectACL);
+
+ /* Whoever did Cryptoflex mask is an idiot - I can't believe they
+ round to the nearest 4 bytes on the size for Dir Next
+ */
+
+ apduResponseB = transmitBufferB.apduResponse;
+ pBufferB = transmitBufferB.pBuffer;
+
+ pBufferB[OFFSET_CLA] = CLA_C0;
+ pBufferB[OFFSET_INS] = 0xA4;
+ pBufferB[OFFSET_P1] = 0x00;
+ pBufferB[OFFSET_P2] = 0x00;
+ pBufferB[OFFSET_P3] = 0x02;
+ pBufferB[OFFSET_DATA] = cTemp[0];
+ pBufferB[OFFSET_DATA+1] = cTemp[1];
+
+ transmitBufferB.bufferSize = 7;
+
+ /* Set up the APDU exchange */
+ transmitBufferB.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBufferB );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBufferB.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ }
+
+ pObjectInfo->objectSize = apduResponseB[2] * 0x100 + apduResponseB[3];
+
+ return convertSW(&apduResponseB[15]);
+
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+
+ break;
+ }
+
+ return MSC_UNSPECIFIED_ERROR;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCLogoutAll( MSCLPTokenConnection pConnection ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_F0;
+ pBuffer[OFFSET_INS] = INS_LOGOUT_ALL;
+ /* PG: Cryptoflex Logout AC command can be used to reset
+ multiple access conditions - however, setting P1 to 0x07
+ simply means "Logout All" */
+ pBuffer[OFFSET_P1] = 0x07;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = 0x00;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ rv = convertSW(apduResponse);
+
+ if ( rv == MSC_SUCCESS ) {
+ pConnection->loggedIDs = 0;
+ }
+
+ return rv;
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGetChallenge( MSCLPTokenConnection pConnection, MSCPUChar8 pSeed,
+ MSCUShort16 seedSize, MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize ) {
+
+ MSCLong32 rv;
+ MSCULong32 currentPointer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+
+ /* PG: randomDataSize is the only parameter
+ that can be passed to Cryptoflex */
+
+ if ( pRandomData == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( randomDataSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = INS_GET_CHALLENGE;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = randomDataSize;
+
+ currentPointer = 0;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ /* PG: or randomDataSize + 4 ??? */
+ if(transmitBuffer.apduResponseSize == randomDataSize + 2)
+ {
+ memcpy(pRandomData, apduResponse, randomDataSize);
+ return convertSW(&apduResponse[transmitBuffer.apduResponseSize-2]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGetObjectAttributes( MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCLPObjectInfo pObjectInfo ) {
+
+ MSC_RV rv;
+ MSCObjectInfo objInfo;
+
+ if ( pConnection == NULL ) return MSC_INVALID_PARAMETER;
+
+ rv = PL_MSCListObjects( pConnection, MSC_SEQUENCE_RESET, &objInfo );
+
+ if ( rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS) {
+ return rv;
+ }
+
+ if ( rv == MSC_SEQUENCE_END ) {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0 ) {
+ pObjectInfo->objectSize = objInfo.objectSize;
+ pObjectInfo->objectACL.readPermission =
+ objInfo.objectACL.readPermission;
+ pObjectInfo->objectACL.writePermission =
+ objInfo.objectACL.writePermission;
+ pObjectInfo->objectACL.deletePermission =
+ objInfo.objectACL.deletePermission;
+ strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID);
+ return MSC_SUCCESS;
+ }
+
+ do {
+ rv = PL_MSCListObjects( pConnection, MSC_SEQUENCE_NEXT, &objInfo );
+ if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0 )
+ break;
+ } while ( rv == MSC_SUCCESS );
+
+ if ( rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ if ( rv == MSC_SEQUENCE_END ) {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ pObjectInfo->objectSize = objInfo.objectSize;
+ pObjectInfo->objectACL.readPermission =
+ objInfo.objectACL.readPermission;
+ pObjectInfo->objectACL.writePermission =
+ objInfo.objectACL.writePermission;
+ pObjectInfo->objectACL.deletePermission =
+ objInfo.objectACL.deletePermission;
+ strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID);
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCReadAllocateObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCPUChar8 *pOutputData,
+ MSCPULong32 dataSize ) {
+
+ MSC_RV rv;
+ MSCObjectInfo objInfo;
+
+ if ( pConnection == NULL ) return MSC_INVALID_PARAMETER;
+
+ if ( pOutputData == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ rv = PL_MSCGetObjectAttributes( pConnection, objectID, &objInfo );
+
+ if ( rv != MSC_SUCCESS ) {
+ *dataSize = 0;
+ *pOutputData = 0;
+ return rv;
+ }
+
+ *pOutputData = (MSCPUChar8)malloc(sizeof(MSCUChar8)*objInfo.objectSize);
+
+ return PL_MSCReadLargeObjectOffCB( pConnection, objectID, 0,
+ *pOutputData, objInfo.objectSize,
+ 0, 0 );
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteLargeObjectOffCB( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offSet,
+ MSCPUChar8 pInputData,
+ MSCULong32 dataSize,
+ LPRWEventCallback rwCallback,
+ MSCPVoid32 addParams ) {
+ MSC_RV rv;
+ MSCULong32 objectSize;
+ int totalSteps, stepInterval;
+ MSC_RV (*callBackFunction)(void*, int);
+ int i;
+
+ callBackFunction = (MSC_RV(*)(void*, int)) rwCallback;
+ objectSize = dataSize;
+ rv = MSC_UNSPECIFIED_ERROR;
+
+
+ /* Figure out the number of steps total and present this
+ in a percent step basis
+ */
+
+ totalSteps = objectSize/MSC_SIZEOF_KEYPACKET + 1;
+ stepInterval = MSC_PERCENT_STEPSIZE / totalSteps;
+
+
+ for (i=0; i < objectSize/MSC_SIZEOF_KEYPACKET; i++) {
+ rv = PL_MSCWriteObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET + offSet,
+ &pInputData[i*MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) { return rv; }
+
+ if ( rwCallback ) {
+ if ((*callBackFunction)(addParams, stepInterval*i) == MSC_CANCELLED) {
+ return MSC_CANCELLED;
+ }
+ }
+
+ }
+
+
+ if ( objectSize%MSC_SIZEOF_KEYPACKET ) {
+ rv = PL_MSCWriteObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET + offSet,
+ &pInputData[i*MSC_SIZEOF_KEYPACKET],
+ objectSize%MSC_SIZEOF_KEYPACKET );
+
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+ if ( rwCallback ) {
+ (*callBackFunction)(addParams, MSC_PERCENT_STEPSIZE);
+ }
+ return rv;
+}
+
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCReadLargeObjectOffCB( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offSet,
+ MSCPUChar8 pOutputData,
+ MSCULong32 dataSize,
+ LPRWEventCallback rwCallback,
+ MSCPVoid32 addParams ) {
+
+ MSC_RV rv;
+ MSCULong32 objectSize;
+ int totalSteps, stepInterval;
+ MSC_RV (*callBackFunction)(void*, int);
+ int i;
+
+ callBackFunction = (MSC_RV(*)(void*, int)) rwCallback;
+ objectSize = dataSize;
+ rv = MSC_UNSPECIFIED_ERROR;
+
+ /* Figure out the number of steps total and present this
+ in a percent step basis
+ */
+
+ totalSteps = objectSize/MSC_SIZEOF_KEYPACKET + 1;
+ stepInterval = MSC_PERCENT_STEPSIZE / totalSteps;
+
+ for (i=0; i < objectSize/MSC_SIZEOF_KEYPACKET; i++) {
+ rv = PL_MSCReadObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET + offSet,
+ &pOutputData[i*MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) { return rv; }
+
+ if ( rwCallback ) {
+ if ((*callBackFunction)(addParams, stepInterval*i) == MSC_CANCELLED) {
+ return MSC_CANCELLED;
+ }
+ }
+ }
+
+ if ( objectSize%MSC_SIZEOF_KEYPACKET ) {
+ rv = PL_MSCReadObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET + offSet,
+ &pOutputData[i*MSC_SIZEOF_KEYPACKET],
+ objectSize%MSC_SIZEOF_KEYPACKET );
+
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+ if ( rwCallback ) {
+ (*callBackFunction)(addParams, MSC_PERCENT_STEPSIZE);
+ }
+
+ return rv;
+}
+
+int bytesToString( MSCString objectString, MSCPUChar8 objBytes ) {
+
+ MSCUShort16 objInt;
+
+ /* Cryptoflex must truncate objectID's to 16 bits */
+
+ MemCopyTo16(&objInt, objBytes);
+
+ if ( objBytes[0] == 0xFF && objBytes[1] == 0xFE ) {
+ snprintf(objectString, MSC_MAXSIZE_OBJID, "#%X", objInt);
+ return 0;
+ }
+
+ snprintf(objectString, MSC_MAXSIZE_OBJID, "%c%c", objBytes[0],
+ objBytes[1]);
+
+ return 0;
+}
+
+int idToString( MSCString objectString, MSCULong32 objectID ) {
+
+ MSCUShort16 objInt;
+ MSCUChar8 objBytes[MSC_MAXSIZE_OBJID];
+
+ objInt = (MSCUShort16)objectID;
+ MemCopy16(objBytes, &objInt);
+
+
+ if ( objBytes[0] == 0xFF && objBytes[1] == 0xFE ) {
+ snprintf(objectString, MSC_MAXSIZE_OBJID, "#%X", objInt);
+ return 0;
+ }
+
+ /* Cryptoflex must truncate objectID's to 16 bits */
+
+ snprintf(objectString, MSC_MAXSIZE_OBJID, "%c%c", objBytes[0],
+ objBytes[1]);
+
+ return 0;
+}
+
+int stringToID( MSCPUShort16 objectID, MSCString objectString ) {
+
+ MSCUShort16 localID;
+ MSCUChar8 objBytes[MSC_MAXSIZE_OBJID];
+
+ localID = 0;
+
+ if ( strncmp(CRYPTOFLEX_INFOBJ_ID, objectString,
+ MSC_MAXSIZE_OBJID) == 0 ) {
+ *objectID = 0xFFFE;
+ return 0;
+ } else if ( strncmp("#0x0011", objectString,
+ MSC_MAXSIZE_OBJID) == 0 ) {
+ *objectID = 0x0011;
+ return 0;
+ } else if ( strncmp("#0x0012", objectString,
+ MSC_MAXSIZE_OBJID) == 0 ) {
+ *objectID = 0x0012;
+ return 0;
+ } else if ( strncmp("#0x1012", objectString,
+ MSC_MAXSIZE_OBJID) == 0 ) {
+ *objectID = 0x1012;
+ return 0;
+ }
+
+ if (strlen(objectString) > CF_SIZEOF_OBJID) {
+ return -1;
+ }
+
+ objBytes[0] = objectString[0];
+ objBytes[1] = objectString[1];
+
+ if (strlen(objectString) == 1) {
+ objBytes[1] = 0x00; /* PAD with 0x00 */
+ }
+
+ MemCopyTo16(&localID, objBytes);
+
+ if ( localID == 0 ) {
+ return -1;
+ }
+
+ *objectID = (MSCUShort16)localID;
+ return 0;
+}
+
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCSelect(MSCLPTokenConnection pConnection,
+ MSCULong32 fileID) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCULong32 currentPointer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = 0xA4;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = 0x02;
+
+ currentPointer = 0;
+
+ pBuffer[OFFSET_DATA+currentPointer] = fileID / 256;
+ currentPointer++;
+ pBuffer[OFFSET_DATA+currentPointer] = fileID % 256;
+ currentPointer++;
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_P3] + 5;
+
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+
+ suppressResponse = 1;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+ suppressResponse = 0;
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if(transmitBuffer.apduResponseSize == 2) {
+ if(apduResponse[0] == 0x61) {
+ return MSC_SUCCESS;
+ } else {
+ return convertSW(apduResponse);
+ }
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCGetResponse(MSCLPTokenConnection pConnection, MSCUChar8 len,
+ MSCPUChar8 buf)
+{
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse;
+ MSCPUChar8 pBuffer;
+ MSCULong32 currentPointer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CLA_C0;
+ pBuffer[OFFSET_INS] = 0xC0;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_P3] = len;
+
+ currentPointer = 0;
+
+ transmitBuffer.bufferSize = 5;
+
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU(pConnection, &transmitBuffer);
+
+ if(rv != SCARD_S_SUCCESS) {
+ return convertPCSC(rv);
+ }
+
+ if(transmitBuffer.apduResponseSize == 2) {
+ return convertSW(apduResponse);
+ } else if(transmitBuffer.apduResponseSize == len + 2){
+ memcpy(buf, apduResponse, len);
+ currentPointer += len;
+ return convertSW(&apduResponse[currentPointer]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+MSCUShort16 convertSW(MSCPUChar8 pBuffer) {
+ MSCUShort16 retValue;
+ MSCUShort16 newValue;
+
+ retValue = pBuffer[0] * 0x100;
+ retValue += pBuffer[1];
+
+ switch(retValue) {
+ case CFMSC_SUCCESS:
+ newValue = MSC_SUCCESS;
+ break;
+ case CFMSC_NO_MEMORY_LEFT:
+ case CFMSC_NO_MEMORY_LEFT_1:
+ newValue = MSC_NO_MEMORY_LEFT;
+ break;
+ case CFMSC_AUTH_FAILED:
+ newValue = MSC_AUTH_FAILED;
+ break;
+ case CFMSC_OPERATION_NOT_ALLOWED:
+ newValue = MSC_OPERATION_NOT_ALLOWED;
+ break;
+ case CFMSC_INCONSISTENT_STATUS:
+ newValue = MSC_INCONSISTENT_STATUS;
+ break;
+ case CFMSC_UNSUPPORTED_FEATURE:
+ newValue = MSC_UNSUPPORTED_FEATURE;
+ break;
+ case CFMSC_UNAUTHORIZED:
+ newValue = MSC_UNAUTHORIZED;
+ break;
+ case CFMSC_OBJECT_NOT_FOUND:
+ newValue = MSC_OBJECT_NOT_FOUND;
+ break;
+ case CFMSC_OBJECT_EXISTS:
+ newValue = MSC_OBJECT_EXISTS;
+ break;
+ case CFMSC_INCORRECT_ALG:
+ newValue = MSC_INCORRECT_ALG;
+ break;
+ case CFMSC_SIGNATURE_INVALID:
+ newValue = MSC_SIGNATURE_INVALID;
+ break;
+ case CFMSC_IDENTITY_BLOCKED:
+ newValue = MSC_IDENTITY_BLOCKED;
+ break;
+ case CFMSC_UNSPECIFIED_ERROR:
+ newValue = MSC_UNSPECIFIED_ERROR;
+ break;
+ case CFMSC_TRANSPORT_ERROR:
+ newValue = MSC_TRANSPORT_ERROR;
+ break;
+ case CFMSC_INVALID_PARAMETER:
+ newValue = MSC_INVALID_PARAMETER;
+ break;
+ case CFMSC_SEQUENCE_END:
+ newValue = MSC_SEQUENCE_END;
+ break;
+ case CFMSC_INTERNAL_ERROR:
+ newValue = MSC_INTERNAL_ERROR;
+ break;
+ case CFMSC_CANCELLED:
+ newValue = MSC_CANCELLED;
+ break;
+ default:
+ newValue = retValue;
+ break;
+ }
+
+ return newValue;
+}
+
+void MemCopy16(MSCPUChar8 destValue, MSCPUShort16 srcValue) {
+ destValue[0] = (*srcValue & 0xFF00) >> 8;
+ destValue[1] = (*srcValue & 0x00FF);
+}
+
+void MemCopy32(MSCPUChar8 destValue, MSCPULong32 srcValue) {
+ destValue[0] = (*srcValue >> 24);
+ destValue[1] = (*srcValue & 0x00FF0000) >> 16;
+ destValue[2] = (*srcValue & 0x0000FF00) >> 8;
+ destValue[3] = (*srcValue & 0x000000FF);
+}
+
+void MemCopyTo16(MSCPUShort16 destValue, MSCPUChar8 srcValue) {
+
+ *destValue = srcValue[0] * 0x100;
+ *destValue += srcValue[1];
+
+}
+
+void MemCopyTo32(MSCPULong32 destValue, MSCPUChar8 srcValue) {
+
+ *destValue = srcValue[0] * 0x1000000;
+ *destValue += srcValue[1] * 0x10000;
+ *destValue += srcValue[2] * 0x100;
+ *destValue += srcValue[3];
+
+}
+
+MSCUShort16 getUShort16(MSCPUChar8 srcValue) {
+ return ( (((MSCUShort16)srcValue[0]) << 8) || srcValue[1] );
+}
+
+void setUShort16(MSCPUChar8 dstValue, MSCUShort16 srcValue) {
+ MemCopyTo16(&srcValue, dstValue);
+}
+
+
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection pConnection,
+ MSCLPTransmitBuffer transmitBuffer ) {
+
+ MSCLong32 rv, ret;
+ MSCULong32 originalLength;
+ MSCUChar8 getResponse[5] = {0xC0, 0xC0, 0x00, 0x00, 0x00};
+ MSCULong32 dwActiveProtocol;
+
+#ifdef MSC_DEBUG
+ int i;
+#endif
+
+ originalLength = transmitBuffer->apduResponseSize;
+
+ while (1) {
+
+#ifdef MSC_DEBUG
+ printf("->: ");
+
+ for (i=0; i < transmitBuffer->bufferSize; i++) {
+ printf("%02x ", transmitBuffer->pBuffer[i]);
+ } printf("\n");
+#endif
+
+ while(1) {
+ transmitBuffer->apduResponseSize = originalLength;
+
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ transmitBuffer->pBuffer,
+ transmitBuffer->bufferSize, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+ break;
+
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+ /* Must be a BIG, BAD, ERROR */
+#ifdef MSC_DEBUG
+ printf("Transmit error: %s\n", pcsc_stringify_error(rv));
+#endif
+ return rv;
+ }
+ }
+
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+
+ if ( suppressResponse == 1 ) {
+ /* Do not do the Get Response */
+ break;
+ }
+
+ if ( transmitBuffer->apduResponseSize == 2 &&
+ transmitBuffer->apduResponse[0] == 0x61 ) {
+#ifdef MSC_DEBUG
+ printf("->: 0xC0 0xC0 0x00 0x00 %02x\n",
+ transmitBuffer->apduResponse[1]);
+#endif
+ getResponse[4] = transmitBuffer->apduResponse[1];
+ transmitBuffer->apduResponseSize = originalLength;
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ getResponse, 5, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+ break;
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+#ifdef MSC_DEBUG
+ printf("Transmit error: %s\n", pcsc_stringify_error(rv));
+#endif
+ return rv;
+ }
+ }
+
+ break;
+ } /* End of while */
+
+
+ return rv;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCIdentifyToken( MSCLPTokenConnection pConnection ) {
+
+ MSCLong32 rv;
+
+ rv = PL_MSCSelect(pConnection, 0x3F00);
+ rv = PL_MSCSelect(pConnection, 0x3FCE);
+
+ pConnection->loggedIDs = 0;
+
+ return rv;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCFinalizePlugin( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+#ifdef WIN32
+CFLEXPLUGIN_API
+#endif
+MSC_RV PL_MSCInitializePlugin( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+
+MSC_RV convertPCSC( MSCLong32 pcscCode ) {
+
+ switch(pcscCode) {
+ case SCARD_S_SUCCESS:
+ return MSC_SUCCESS;
+ case SCARD_E_INVALID_HANDLE:
+ return MSC_INVALID_HANDLE;
+ case SCARD_E_SHARING_VIOLATION:
+ return MSC_SHARING_VIOLATION;
+ case SCARD_W_REMOVED_CARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_E_NO_SMARTCARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_W_RESET_CARD:
+ return MSC_TOKEN_RESET;
+ case SCARD_W_INSERTED_CARD:
+ return MSC_TOKEN_INSERTED;
+ case SCARD_E_NO_SERVICE:
+ return MSC_SERVICE_UNRESPONSIVE;
+ case SCARD_E_UNKNOWN_CARD:
+ case SCARD_W_UNSUPPORTED_CARD:
+ case SCARD_E_CARD_UNSUPPORTED:
+ return MSC_UNRECOGNIZED_TOKEN;
+ case SCARD_E_INVALID_PARAMETER:
+ case SCARD_E_INVALID_VALUE:
+ case SCARD_E_UNKNOWN_READER:
+ case SCARD_E_PROTO_MISMATCH:
+ case SCARD_E_READER_UNAVAILABLE:
+ return MSC_INVALID_PARAMETER;
+ case SCARD_E_CANCELLED:
+ return MSC_CANCELLED;
+ case SCARD_E_TIMEOUT:
+ return MSC_TIMEOUT_OCCURRED;
+
+ default:
+ return MSC_INTERNAL_ERROR;
+ }
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/CFlexPlugin/cryptoflex.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : cryptoflex.h
+ Package: card edge
+ Author : David Corcoran
+ Date : 10/02/01
+ License: Copyright (C) 2001 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts the MUSCLE Card Edge Inteface
+
+
+********************************************************************/
+
+#ifndef __cryptoflex_h__
+#define __cryptoflex_h__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#define CLA_F0 0xF0
+#define CLA_C0 0xC0
+
+/* Some useful offsets in the buffer */
+#define OFFSET_CLA 0x00
+#define OFFSET_INS 0x01
+#define OFFSET_P1 0x02
+#define OFFSET_P2 0x03
+#define OFFSET_P3 0x04
+#define OFFSET_DATA 0x05
+
+#define OFFSET_ENCODING 0x00
+#define OFFSET_KEYTYPE 0x01
+#define OFFSET_KEYSIZE 0x02
+#define OFFSET_KEYDATA 0x04
+
+#define CF_SIZEOF_MSBLEN 1
+#define CF_SIZEOF_LSBLEN 1
+#define CF_SIZEOF_KEYNUM 1
+#define CF_SIZEOF_OBJID 2
+
+/* Defines for 1024 bit RSA keys */
+#define CF_1024_FULLSIZE 0x143
+#define CF_1024_FULLSIZE_1 0x01
+#define CF_1024_FULLSIZE_2 0x43
+#define CF_1024P_FULLSIZE 0x147
+
+#define CF_1024_COMPSIZE 0x40
+
+#define CF_1024_KEYSIZE 1024
+#define CF_1024P_MODSIZE 128
+#define CF_1024P_EXPSIZE 4
+#define CF_1024P_MOD 3
+#define CF_1024P_EXP 323
+
+#define MC_1024P_FULLSIZE 140
+#define MC_SIZEOF_COMPSIZE 2
+#define MC_1024_OFFSET_P 4
+#define MC_1024_OFFSET_Q 70
+#define MC_1024_OFFSET_PQ 136
+#define MC_1024_OFFSET_DP1 202
+#define MC_1024_OFFSET_DQ1 268
+
+
+#define MC_1024P_MOD 4
+#define MC_1024P_EXP 134
+#define MC_1024P_MODSIZE 128
+
+
+#define CF_DES_OFFSET_UKEY 0x19
+#define MC_DES_OFFSET_KEY 4
+
+ /* Sizes of particular objects */
+#define MSC_SIZEOF_OBJECTID 4
+#define MSC_SIZEOF_OBJECTSIZE 4
+#define MSC_SIZEOF_KEYINFO 16
+#define MSC_SIZEOF_STATUS 16
+#define MSC_SIZEOF_VERSION 2
+#define MSC_SIZEOF_FREEMEM 4
+#define MSC_SIZEOF_LOGIDS 2
+#define MSC_SIZEOF_ADDINFO 8
+#define MSC_SIZEOF_OPTLEN 2
+#define MSC_SIZEOF_GENOPTIONS 1
+#define MSC_SIZEOF_KEYSIZE 2
+#define MSC_SIZEOF_KEYNUMBER 1
+#define MSC_SIZEOF_KEYTYPE 1
+#define MSC_SIZEOF_KEYPARTNER 1
+#define MSC_SIZEOF_POLICYVALUE 2
+#define MSC_SIZEOF_KEYMAPPING 1
+#define MSC_SIZEOF_CIPHERMODE 1
+#define MSC_SIZEOF_CIPHERDIR 1
+#define MSC_SIZEOF_CRYPTLEN 2
+#define MSC_SIZEOF_ALGOTYPE 1
+#define MSC_SIZEOF_IDUSED 1
+#define MSC_SIZEOF_OFFSET 4
+#define MSC_SIZEOF_ACLSTRUCT 6
+#define MSC_SIZEOF_RWDATA 1
+#define MSC_SIZEOF_PINSIZE 1
+#define MSC_SIZEOF_CIPHERMODE 1
+#define MSC_SIZEOF_CIPHERDIR 1
+#define MSC_SIZEOF_DATALOCATION 1
+#define MSC_SIZEOF_ACLVALUE 2
+#define MSC_SIZEOF_SEEDLENGTH 2
+#define MSC_SIZEOF_RANDOMSIZE 2
+
+ // Keys' use and management
+#define INS_MSC_GEN_KEYPAIR 0x46
+#define INS_IMPORT_KEY 0x32
+#define INS_EXPORT_KEY 0x34
+#define INS_COMPUTE_CRYPT 0x88
+
+ // External authentication
+#define INS_CREATE_PIN 0x40
+#define INS_VERIFY_PIN 0x20
+#define INS_CHANGE_PIN 0x24
+#define INS_UNBLOCK_PIN 0x2C
+#define INS_LOGOUT_ALL 0x22
+#define INS_GET_CHALLENGE 0x84
+#define INS_EXT_AUTH 0x82
+
+ // Objects' use and management
+#define INS_CREATE_OBJ 0xE0
+#define INS_DELETE_OBJ 0xE4
+#define INS_READ_OBJ 0xB0
+#define INS_WRITE_OBJ 0xD6
+
+ // Status information
+#define INS_LIST_OBJECTS 0xA8
+#define INS_LIST_PINS 0x48
+#define INS_LIST_KEYS 0x3A
+#define INS_GET_STATUS 0x3C
+
+ /** success */
+#define CFMSC_SUCCESS 0x9000
+
+ /** There have been memory problems on the card */
+#define CFMSC_NO_MEMORY_LEFT 0x6A84
+#define CFMSC_NO_MEMORY_LEFT_1 0x6A83
+ /** Entered PIN is not correct */
+#define CFMSC_AUTH_FAILED 0x6300
+ /** Required operation is not allowed in actual circumstances */
+#define CFMSC_OPERATION_NOT_ALLOWED 0x9C03
+ /** Required operation is inconsistent with memory contents */
+#define CFMSC_INCONSISTENT_STATUS 0x9C04
+ /** Required feature is not (yet) supported */
+#define CFMSC_UNSUPPORTED_FEATURE 0x6D00
+ /** Required operation was not authorized because of a lack of privileges */
+#define CFMSC_UNAUTHORIZED 0x6982
+ /** Required object is missing */
+#define CFMSC_OBJECT_NOT_FOUND 0x6A82
+ /** New object ID already in use */
+#define CFMSC_OBJECT_EXISTS 0x6A80
+ /** Algorithm specified is not correct */
+#define CFMSC_INCORRECT_ALG 0x6981
+
+ /** Verify operation detected an invalid signature */
+#define CFMSC_SIGNATURE_INVALID 0x9C0B
+ /** Operation has been blocked for security reason */
+#define CFMSC_IDENTITY_BLOCKED 0x6983
+ /** Unspecified error */
+#define CFMSC_UNSPECIFIED_ERROR 0x6F00
+ /** PCSC and driver transport errors */
+#define CFMSC_TRANSPORT_ERROR 0x9C0E
+ /** Invalid parameter given */
+#define CFMSC_INVALID_PARAMETER 0x6B00
+ /** Incorrect P1 parameter */
+#define CFMSC_INCORRECT_P1 0x6B00
+ /** Incorrect P2 parameter */
+#define CFMSC_INCORRECT_P2 0x6B00
+ /** End of sequence */
+#define CFMSC_SEQUENCE_END 0x9C12
+ /** For debugging purposes */
+#define CFMSC_INTERNAL_ERROR 0x6581
+
+
+#define CFMSC_CANCELLED 0x9C50
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __cryptoflex_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,372 @@
+/******************************************************************
+ GSCIS
+ MUSCLE SmartCard Development ( http://www.musclecard.com )
+ Title : GSCISPlugin.c
+ Package: GSCISPlugin
+ Author : David Corcoran
+ Date : 02/19/02
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: A MuscleCard plugin for GSCIS compliant cards.
+
+
+********************************************************************/
+
+#ifndef __APPLE__
+#include <musclecard.h>
+#else
+#include <PCSC/musclecard.h>
+#endif
+
+#include "GSCISPlugin.h"
+#include <string.h>
+#include <stdio.h>
+
+
+typedef struct {
+ MSCUChar8 pBuffer[MAX_BUFFER_SIZE];
+ MSCULong32 bufferSize;
+ MSCUChar8 apduResponse[MAX_BUFFER_SIZE];
+ MSCULong32 apduResponseSize;
+ LPSCARD_IO_REQUEST ioType;
+} MSCTransmitBuffer, *MSCLPTransmitBuffer;
+
+/* internal function */
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection, MSCLPTransmitBuffer );
+MSC_RV convertPCSC( MSCLong32 );
+
+MSC_RV PL_MSCWriteFramework( MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCSelectAID( MSCLPTokenConnection pConnection, MSCPUChar8 aidValue,
+ MSCULong32 aidSize ) {
+
+ /* Make sure the right card is there, select the specified applet
+ if needed. If no applet specified, select the default applet
+ */
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCInitializePlugin( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCFinalizePlugin( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCIdentifyToken( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCGetStatus( MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCGetCapabilities( MSCLPTokenConnection pConnection, MSCULong32 Tag,
+ MSCPUChar8 Value, MSCPULong32 Length ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCExtendedFeature( MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature,
+ MSCPUChar8 outData, MSCULong32 outLength,
+ MSCPUChar8 inData, MSCPULong32 inLength ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCGenerateKeys( MSCLPTokenConnection pConnection, MSCUChar8 prvKeyNum,
+ MSCUChar8 pubKeyNum, MSCLPGenKeyParams pParams ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCImportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL, MSCPUChar8 pKeyBlob,
+ MSCULong32 keyBlobSize, MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCExportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCComputeCrypt( MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCExtAuthenticate( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCUChar8 cipherMode, MSCUChar8 cipherDirection,
+ MSCPUChar8 pData, MSCULong32 dataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCListKeys( MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCCreatePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts, MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCVerifyPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode, MSCULong32 pinCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCChangePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCUnblockPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode, MSCULong32 unblockCodeSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCListPINs( MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask ) {
+
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCCreateObject( MSCLPTokenConnection pConnection, MSCString objectID,
+ MSCULong32 objectSize, MSCLPObjectACL pObjectACL ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCDeleteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCUChar8 zeroFlag ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCWriteObject( MSCLPTokenConnection pConnection, MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pInputData,
+ MSCUChar8 dataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCReadObject( MSCLPTokenConnection pConnection, MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pOutputData,
+ MSCUChar8 dataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCListObjects( MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCLogoutAll( MSCLPTokenConnection pConnection ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCGetChallenge( MSCLPTokenConnection pConnection, MSCPUChar8 pSeed,
+ MSCUShort16 seedSize, MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+
+
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection pConnection,
+ MSCLPTransmitBuffer transmitBuffer ) {
+
+ MSCLong32 rv, ret;
+ MSCULong32 originalLength;
+ MSCUChar8 getResponse[5] = {0x00, 0xC0, 0x00, 0x00, 0x00};
+ MSCULong32 dwActiveProtocol;
+
+ originalLength = transmitBuffer->apduResponseSize;
+
+ while (1) {
+
+#ifdef MSC_DEBUG
+ printf("->: ");
+ for (i=0; i < transmitBuffer->bufferSize; i++) {
+ printf("%02x ", transmitBuffer->pBuffer[i]);
+ } printf("\n");
+#endif
+
+ while(1) {
+ transmitBuffer->apduResponseSize = originalLength;
+
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ transmitBuffer->pBuffer,
+ transmitBuffer->bufferSize, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+ break;
+
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+ /* Must be a BIG, BAD, ERROR */
+#ifdef MSC_DEBUG
+ printf("Transmit error: %s\n", pcsc_stringify_error(rv));
+#endif
+ return rv;
+ }
+ }
+
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+
+#ifdef MSC_NOT_DEFINED
+ if ( suppressResponse == 1 ) {
+ /* Do not do the Get Response */
+ break;
+ }
+#endif
+
+ if ( transmitBuffer->apduResponseSize == 2 &&
+ transmitBuffer->apduResponse[0] == 0x61 ) {
+#ifdef MSC_DEBUG
+ printf("->: 0x00 0xC0 0x00 0x00 %02x\n",
+ transmitBuffer->apduResponse[1]);
+#endif
+ getResponse[4] = transmitBuffer->apduResponse[1];
+ transmitBuffer->apduResponseSize = originalLength;
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ getResponse, 5, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+ break;
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+#ifdef MSC_DEBUG
+ printf("Transmit error: %s\n", pcsc_stringify_error(rv));
+#endif
+ return rv;
+ }
+ }
+
+ break;
+ } /* End of while */
+
+
+ return rv;
+}
+
+MSC_RV convertPCSC( MSCLong32 pcscCode ) {
+
+ switch(pcscCode) {
+ case SCARD_S_SUCCESS:
+ return MSC_SUCCESS;
+ case SCARD_E_INVALID_HANDLE:
+ return MSC_INVALID_HANDLE;
+ case SCARD_E_SHARING_VIOLATION:
+ return MSC_SHARING_VIOLATION;
+ case SCARD_W_REMOVED_CARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_E_NO_SMARTCARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_W_RESET_CARD:
+ return MSC_TOKEN_RESET;
+ case SCARD_W_INSERTED_CARD:
+ return MSC_TOKEN_INSERTED;
+ case SCARD_E_NO_SERVICE:
+ return MSC_SERVICE_UNRESPONSIVE;
+ case SCARD_E_UNKNOWN_CARD:
+ case SCARD_W_UNSUPPORTED_CARD:
+ case SCARD_E_CARD_UNSUPPORTED:
+ return MSC_UNRECOGNIZED_TOKEN;
+ case SCARD_E_INVALID_PARAMETER:
+ case SCARD_E_INVALID_VALUE:
+ case SCARD_E_UNKNOWN_READER:
+ case SCARD_E_PROTO_MISMATCH:
+ case SCARD_E_READER_UNAVAILABLE:
+ return MSC_INVALID_PARAMETER;
+ case SCARD_E_CANCELLED:
+ return MSC_CANCELLED;
+ case SCARD_E_TIMEOUT:
+ return MSC_TIMEOUT_OCCURRED;
+
+ default:
+ return MSC_INTERNAL_ERROR;
+ }
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/GSCISPlugin/GSCISPlugin.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,35 @@
+/******************************************************************
+ GSCIS
+ MUSCLE SmartCard Development ( http://www.musclecard.com )
+ Title : GSCISPlugin.h
+ Package: GSCISPlugin
+ Author : David Corcoran
+ Date : 02/19/02
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: A MuscleCard plugin for GSCIS compliant cards.
+
+
+********************************************************************/
+
+#ifndef __GSCISPlugin_h__
+#define __GSCISPlugin_h__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Some useful offsets in the buffer */
+#define OFFSET_CLA 0x00
+#define OFFSET_INS 0x01
+#define OFFSET_P1 0x02
+#define OFFSET_P2 0x03
+#define OFFSET_P3 0x04
+#define OFFSET_DATA 0x05
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __GSCISPlugin_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,2214 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : musclecardApplet.c
+ Package: MuscleCard Plugin
+ Author : David Corcoran
+ Tommaso Cucinotta
+ Date : 09/26/01
+ License: Copyright (C) 2001-2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts the Card Edge Interface APDU's
+ into client side function calls.
+
+********************************************************************/
+#ifdef WIN32
+#include "../win32/MCardPlugin.h"
+#endif
+
+#ifndef __APPLE__
+#include <musclecard.h>
+#else
+#include <PCSC/musclecard.h>
+#endif
+
+#include "musclecardApplet.h"
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define MSC_DEBUG 1
+
+/* Local transport structure */
+typedef struct {
+ MSCUChar8 pBuffer[MAX_BUFFER_SIZE];
+ MSCULong32 bufferSize;
+ MSCUChar8 apduResponse[MAX_BUFFER_SIZE];
+ MSCULong32 apduResponseSize;
+ LPSCARD_IO_REQUEST ioType;
+} MSCTransmitBuffer, *MSCLPTransmitBuffer;
+
+/* Some locally defined functions */
+
+MSC_RV convertPCSC( MSCLong32 );
+int idToString( char*, MSCULong32 );
+int stringToID( MSCPULong32, char* );
+MSCUShort16 convertSW( MSCPUChar8 );
+void MemCopy16( MSCPUChar8, MSCPUShort16 );
+void MemCopy32( MSCPUChar8, MSCPULong32 );
+void MemCopyTo16( MSCPUShort16, MSCPUChar8 );
+void MemCopyTo32( MSCPULong32, MSCPUChar8 );
+MSCUShort16 getUShort16( MSCPUChar8 );
+void setUShort16( MSCPUChar8, MSCUShort16 );
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection, MSCLPTransmitBuffer );
+MSC_RV lcMSCGetObjectAttributes( MSCLPTokenConnection,
+ MSCString, MSCLPObjectInfo );
+
+/* MSC Functions */
+
+
+MSC_RV PL_MSCGetStatus( MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+
+ MSCULong32 currentPointer;
+
+ rv=0; currentPointer=0;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_GET_STATUS;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_STATUS;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else if (transmitBuffer.apduResponseSize == pBuffer[OFFSET_LC] + 2 ) {
+ currentPointer = 0;
+ MemCopyTo16(&pStatusInfo->appVersion, &apduResponse[currentPointer]);
+ currentPointer += MSC_SIZEOF_VERSION;
+
+ MemCopyTo16(&pStatusInfo->swVersion, &apduResponse[currentPointer]);
+ currentPointer += MSC_SIZEOF_VERSION;
+
+ MemCopyTo32(&pStatusInfo->totalMemory, &apduResponse[currentPointer]);
+ currentPointer += MSC_SIZEOF_FREEMEM;
+
+ MemCopyTo32(&pStatusInfo->freeMemory, &apduResponse[currentPointer]);
+ currentPointer += MSC_SIZEOF_FREEMEM;
+
+ pStatusInfo->usedPINs = apduResponse[currentPointer];
+ currentPointer += MSC_SIZEOF_IDUSED;
+
+ pStatusInfo->usedKeys = apduResponse[currentPointer];
+ currentPointer += MSC_SIZEOF_IDUSED;
+
+ MemCopyTo16(&pStatusInfo->loggedID, &apduResponse[currentPointer]);
+ currentPointer += MSC_SIZEOF_LOGIDS;
+
+ return convertSW(&apduResponse[currentPointer]);
+
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCGetCapabilities( MSCLPTokenConnection pConnection, MSCULong32 Tag,
+ MSCPUChar8 Value, MSCPULong32 Length ) {
+
+ MSCULong32 ulValue;
+ MSCUShort16 usValue;
+ MSCUChar8 ucValue;
+ MSCUChar8 tagType;
+
+ /* 4 - MSCULong32, 2 - MSCUShort16, 1 - MSCUChar8 */
+
+ ulValue = 0; usValue = 0; ucValue = 0; tagType = 0;
+
+ switch(Tag) {
+
+ case MSC_TAG_SUPPORT_FUNCTIONS:
+ ulValue = MSC_SUPPORT_GENKEYS | MSC_SUPPORT_IMPORTKEY |
+ MSC_SUPPORT_EXPORTKEY | MSC_SUPPORT_COMPUTECRYPT |
+ MSC_SUPPORT_EXTAUTH | MSC_SUPPORT_LISTKEYS |
+ MSC_SUPPORT_CREATEPIN |
+ MSC_SUPPORT_VERIFYPIN | MSC_SUPPORT_CHANGEPIN |
+ MSC_SUPPORT_UNBLOCKPIN | MSC_SUPPORT_LISTPINS |
+ MSC_SUPPORT_CREATEOBJECT | MSC_SUPPORT_DELETEOBJECT |
+ MSC_SUPPORT_WRITEOBJECT | MSC_SUPPORT_READOBJECT |
+ MSC_SUPPORT_LISTOBJECTS | MSC_SUPPORT_LOGOUTALL |
+ MSC_SUPPORT_GETCHALLENGE;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_SUPPORT_CRYPTOALG:
+ ulValue = MSC_SUPPORT_RSA |
+ MSC_SUPPORT_DES | MSC_SUPPORT_3DES;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_RSA:
+ ulValue = MSC_CAPABLE_RSA_1024 | MSC_CAPABLE_RSA_768 |
+ MSC_CAPABLE_RSA_NOPAD | MSC_CAPABLE_RSA_KEYGEN;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_DES:
+ ulValue = MSC_CAPABLE_DES_ECB;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_3DES:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_ATTR:
+ ulValue = MSC_CAPABLE_OBJ_ZERO;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_IDSIZE:
+ ucValue = 4;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_AUTH:
+ usValue = MSC_AUT_ALL;
+ tagType = 2;
+ break;
+
+ case MSC_TAG_CAPABLE_OBJ_MAXNUM:
+ ulValue = 100;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_ATTR:
+ ulValue = MSC_CAPABLE_PIN_LEAVE;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MAXNUM:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MINSIZE:
+ ucValue = 4;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_MAXSIZE:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_CHARSET:
+ ulValue = MSC_CAPABLE_PIN_A_Z | MSC_CAPABLE_PIN_a_z |
+ MSC_CAPABLE_PIN_0_9 | MSC_CAPABLE_PIN_CALC | MSC_CAPABLE_PIN_NONALPHA;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_POLICY:
+ ulValue = 0;
+ tagType = 4;
+ break;
+
+ case MSC_TAG_CAPABLE_ID_STATE:
+ ucValue = MSC_CAPABLE_ID_STATE;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_RANDOM_MAX:
+ ucValue = 128;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_RANDOM_MIN:
+ ucValue = 8;
+ tagType = 1;
+ break;
+
+ case MSC_TAG_CAPABLE_KEY_AUTH:
+ usValue = MSC_AUT_PIN_1;
+ tagType = 2;
+ break;
+
+ case MSC_TAG_CAPABLE_PIN_AUTH:
+ usValue = MSC_AUT_ALL;
+ tagType = 2;
+ break;
+
+
+ default:
+ return MSC_INVALID_PARAMETER;
+ }
+
+ switch(tagType) {
+ case 1:
+ memcpy(Value, &ucValue, 1);
+ break;
+ case 2:
+ memcpy(Value, &usValue, 2);
+ break;
+ case 4:
+ memcpy(Value, &ulValue, 4);
+ break;
+ }
+
+ *Length = tagType;
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCWriteFramework( MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ if (pInitParams->transportKeyLen > 8 ||
+ pInitParams->newTransportKeyLen > 8 ||
+ pInitParams->defaultCHVLen > 8 ||
+ pInitParams->defaultCHVUnblockSize > 8 ) {
+
+ return MSC_INVALID_PARAMETER;
+ }
+
+ /* Select the applet */
+ PL_MSCIdentifyToken(pConnection);
+
+ if (pInitParams->newTransportKeyLen == 0) {
+ /* Just use the old transport key */
+ memcpy(pInitParams->newTransportKey, pInitParams->transportKey,
+ pInitParams->transportKeyLen);
+ pInitParams->newTransportKeyLen = pInitParams->transportKeyLen;
+ }
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_WRITE_FRAMEWORK;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] =
+ MSC_SIZEOF_PINSIZE + pInitParams->transportKeyLen +
+ MSC_SIZEOF_PINTRIES + MSC_SIZEOF_PINTRIES +
+ MSC_SIZEOF_PINSIZE + pInitParams->newTransportKeyLen +
+ MSC_SIZEOF_PINSIZE + pInitParams->newTransportKeyLen +
+ MSC_SIZEOF_PINTRIES + MSC_SIZEOF_PINTRIES +
+ MSC_SIZEOF_PINSIZE + pInitParams->defaultCHVLen +
+ MSC_SIZEOF_PINSIZE + pInitParams->defaultCHVUnblockSize +
+ MSC_SIZEOF_OBJECTSIZE + MSC_SIZEOF_MINIACL + MSC_SIZEOF_MINIACL +
+ MSC_SIZEOF_MINIACL;
+
+ currentPointer = 0;
+
+ /* Transport key to verify */
+
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->transportKeyLen;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInitParams->transportKey,
+ pInitParams->transportKeyLen);
+
+ currentPointer += pInitParams->transportKeyLen;
+
+ /* New transport key and attributes */
+
+ pBuffer[OFFSET_DATA+currentPointer] = 4;
+ currentPointer += MSC_SIZEOF_PINTRIES;
+ pBuffer[OFFSET_DATA+currentPointer] = 1; /* One chance to unblock */
+ currentPointer += MSC_SIZEOF_PINTRIES;
+
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->newTransportKeyLen;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInitParams->newTransportKey,
+ pInitParams->newTransportKeyLen);
+
+ currentPointer += pInitParams->newTransportKeyLen;
+
+ /* Write Admin Pin Unblock (Same as Admin) */
+
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->newTransportKeyLen;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInitParams->newTransportKey,
+ pInitParams->newTransportKeyLen);
+
+ currentPointer += pInitParams->newTransportKeyLen;
+
+ /* Write User PIN */
+
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->defaultCHVTries;
+ currentPointer += MSC_SIZEOF_PINTRIES;
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->defaultCHVUnblockTries;
+ currentPointer += MSC_SIZEOF_PINTRIES;
+
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->defaultCHVLen;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInitParams->defaultCHV,
+ pInitParams->defaultCHVLen);
+
+ currentPointer += pInitParams->defaultCHVLen;
+
+ /* Write User Pin Unblock */
+
+ pBuffer[OFFSET_DATA+currentPointer] = pInitParams->defaultCHVUnblockSize;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInitParams->defaultCHVUnblock,
+ pInitParams->defaultCHVUnblockSize);
+
+ currentPointer += pInitParams->defaultCHVUnblockSize;
+
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer],
+ &pInitParams->objectMemory);
+
+ currentPointer += MSC_SIZEOF_OBJECTSIZE;
+
+
+ /* Anyone can create objects */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x00;
+ currentPointer += MSC_SIZEOF_MINIACL;
+ /* Keys only after user pin verified */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x02;
+ currentPointer += MSC_SIZEOF_MINIACL;
+ /* Pins only after admin pin verified */
+ pBuffer[OFFSET_DATA+currentPointer] = 0x01;
+ currentPointer += MSC_SIZEOF_MINIACL;
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCExtendedFeature( MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature, MSCPUChar8 outData,
+ MSCULong32 outLength, MSCPUChar8 inData,
+ MSCPULong32 inLength ) {
+
+ return MSC_UNSUPPORTED_FEATURE;
+}
+
+MSC_RV PL_MSCGenerateKeys( MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum, MSCUChar8 pubKeyNum,
+ MSCLPGenKeyParams pParams ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_MSC_GEN_KEYPAIR;
+ pBuffer[OFFSET_P1] = prvKeyNum;
+ pBuffer[OFFSET_P2] = pubKeyNum;
+ pBuffer[OFFSET_LC] = 16 + pParams->optParamsSize;
+
+ currentPointer = 0;
+
+ /* Algorithm Type */
+ pBuffer[OFFSET_DATA] = pParams->algoType;
+ currentPointer += MSC_SIZEOF_ALGOTYPE;
+
+ /* Key Size */
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &pParams->keySize);
+ currentPointer += MSC_SIZEOF_KEYSIZE;
+
+ /* Private Key ACL */
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pParams->privateKeyACL.readPermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pParams->privateKeyACL.writePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pParams->privateKeyACL.usePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ /* Public Key ACL */
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pParams->publicKeyACL.readPermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pParams->publicKeyACL.writePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pParams->publicKeyACL.usePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ /* Key Generation Options */
+ pBuffer[OFFSET_DATA+currentPointer] = pParams->keyGenOptions;
+ currentPointer += MSC_SIZEOF_GENOPTIONS;
+
+
+ /* Key Generation Options Data */
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pParams->pOptParams,
+ pParams->optParamsSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+MSC_RV PL_MSCImportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL,
+ MSCPUChar8 pKeyBlob, MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ int i; MSCObjectACL acl;
+
+ acl.readPermission = MSC_AUT_PIN_1;
+ acl.writePermission = MSC_AUT_PIN_1;
+ acl.deletePermission = MSC_AUT_PIN_1;
+
+ rv = PL_MSCCreateObject(pConnection, IN_OBJECT_ID,
+ keyBlobSize, &acl);
+ if (rv != MSC_SUCCESS)
+ return rv;
+
+ i=0;
+
+ /* Take the key and write it to the default object */
+ for (i=0; i < keyBlobSize/MSC_SIZEOF_KEYPACKET; i++) {
+ rv = PL_MSCWriteObject( pConnection, IN_OBJECT_ID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pKeyBlob[i*MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+ if ( keyBlobSize%MSC_SIZEOF_KEYPACKET ) {
+ rv = PL_MSCWriteObject( pConnection, IN_OBJECT_ID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pKeyBlob[i*MSC_SIZEOF_KEYPACKET],
+ keyBlobSize%MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) {
+ PL_MSCDeleteObject(pConnection, IN_OBJECT_ID, MSC_ZF_WRITE_ZERO);
+ return rv;
+ }
+ }
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_IMPORT_KEY;
+ pBuffer[OFFSET_P1] = keyNum;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_ACLSTRUCT + addParamsSize;
+
+ currentPointer = 0;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pKeyACL->readPermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pKeyACL->writePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pKeyACL->usePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pAddParams, addParamsSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ PL_MSCDeleteObject(pConnection, IN_OBJECT_ID, MSC_ZF_WRITE_ZERO);
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCExportKey( MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ MSCULong32 blobSize;
+ MSCObjectInfo objInfo;
+ int i;
+
+ i=0; blobSize=0; rv=0; currentPointer=0;
+
+ if ( pConnection == 0 || keyBlobSize == 0 || pKeyBlob == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_EXPORT_KEY;
+ pBuffer[OFFSET_P1] = keyNum;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = addParamsSize + 1;
+
+ pBuffer[OFFSET_DATA] = MSC_BLOB_ENC_PLAIN;
+
+ if ( pAddParams != 0 ) {
+ memcpy(&pBuffer[OFFSET_DATA+1], pAddParams, addParamsSize);
+ }
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize != 2 ) {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+ if ( convertSW(apduResponse) != MSC_SUCCESS ) {
+ return convertSW(apduResponse);
+ }
+
+ do {
+
+ /* Get the objects size */
+ rv = lcMSCGetObjectAttributes( pConnection, OUT_OBJECT_ID, &objInfo );
+
+ if ( rv != MSC_SUCCESS ) { break; }
+
+ if ( objInfo.objectSize > *keyBlobSize ) {
+ *keyBlobSize = objInfo.objectSize;
+ rv = MSC_NO_MEMORY_LEFT;
+ break;
+ }
+
+ *keyBlobSize = objInfo.objectSize;
+ blobSize = objInfo.objectSize;
+
+ /* Read the key from the default object */
+ for (i=0; i < blobSize/MSC_SIZEOF_KEYPACKET; i++) {
+ rv = PL_MSCReadObject( pConnection, OUT_OBJECT_ID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pKeyBlob[i*MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) { break; }
+ }
+
+ if ( blobSize%MSC_SIZEOF_KEYPACKET ) {
+ rv = PL_MSCReadObject( pConnection, OUT_OBJECT_ID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pKeyBlob[i*MSC_SIZEOF_KEYPACKET],
+ blobSize%MSC_SIZEOF_KEYPACKET );
+
+ if ( rv != MSC_SUCCESS ) { break; }
+ }
+
+ } while (0);
+
+ /* Delete the default output object */
+ PL_MSCDeleteObject( pConnection, OUT_OBJECT_ID, MSC_ZF_WRITE_ZERO );
+
+ return rv;
+}
+
+MSC_RV PL_MSCComputeCrypt( MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCUShort16 outSize;
+ MSCUChar8 dataLocation;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 ppRecvBuffer;
+ MSCULong32 currentPointer;
+ MSCObjectACL objACL;
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ /******************************************/
+ /* Do the MSC_CIPHER_INIT portion of the code */
+ /******************************************/
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_COMPUTE_CRYPT;
+ pBuffer[OFFSET_P1] = cryptInit->keyNum;
+ pBuffer[OFFSET_P2] = MSC_CIPHER_INIT;
+
+ /* Store init in object */
+ if ( cryptInit->optParamsSize + MSC_SIZEOF_CIPHERMODE +
+ MSC_SIZEOF_CIPHERDIR + MSC_SIZEOF_DATALOCATION >
+ MSC_MAXSIZEOF_APDU_DATALEN + MSC_SIZEOF_OPTLEN)
+ {
+
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_CIPHERMODE +
+ MSC_SIZEOF_CIPHERDIR + MSC_SIZEOF_DATALOCATION +
+ MSC_SIZEOF_OPTLEN;
+
+ dataLocation = DL_OBJECT;
+
+ /* Store init in apdu */
+ } else {
+ pBuffer[OFFSET_LC] = cryptInit->optParamsSize +
+ MSC_SIZEOF_CIPHERMODE + MSC_SIZEOF_CIPHERDIR +
+ MSC_SIZEOF_DATALOCATION + MSC_SIZEOF_OPTLEN;
+
+ dataLocation = DL_APDU;
+ }
+
+ currentPointer = 0;
+
+ /* Cipher mode */
+ pBuffer[OFFSET_DATA] = cryptInit->cipherMode;
+ currentPointer += MSC_SIZEOF_CIPHERMODE;
+
+ /* Cipher direction */
+ pBuffer[OFFSET_DATA+currentPointer] = cryptInit->cipherDirection;
+
+ /* FIX - Forcing Encrypt Mode */
+ if (cryptInit->cipherDirection == MSC_DIR_SIGN) {
+ pBuffer[OFFSET_DATA+currentPointer] = MSC_DIR_ENCRYPT;
+ }
+
+ currentPointer += MSC_SIZEOF_CIPHERDIR;
+
+ pBuffer[OFFSET_DATA+currentPointer] = dataLocation;
+ currentPointer += MSC_SIZEOF_DATALOCATION;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &cryptInit->optParamsSize);
+ currentPointer += MSC_SIZEOF_OPTLEN;
+
+ /* TODO: memcopy and MSCCreateObject/WriteObject needed here */
+ /* Opt Parameters are not used in this version of the spec */
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize != 2 ) {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+ if ( convertSW(apduResponse) != MSC_SUCCESS ) {
+ return convertSW(apduResponse);
+ }
+
+
+ if ( (inputDataSize + MSC_SIZEOF_CIPHERMODE + MSC_SIZEOF_CIPHERDIR
+ + MSC_SIZEOF_DATALOCATION) > MSC_MAXSIZEOF_APDU_DATALEN ) {
+
+ /*********************************************/
+ /* Do the MSC_CIPHER_PROCESS portion of the code */
+ /*********************************************/
+
+ /* TODO : I don't want to do this now */
+
+ pBuffer[OFFSET_P2] = MSC_CIPHER_PROCESS;
+ pBuffer[OFFSET_LC] = 0; /* TODO */
+
+ currentPointer = 0;
+
+ return MSC_UNSUPPORTED_FEATURE;
+
+ } else {
+
+ /*******************************************/
+ /* Do the MSC_CIPHER_FINAL portion of the code */
+ /*******************************************/
+
+ pBuffer[OFFSET_P2] = MSC_CIPHER_FINAL;
+ currentPointer = 0;
+
+ if ( inputDataSize + MSC_SIZEOF_DATALOCATION >
+ MSC_MAXSIZEOF_APDU_DATALEN )
+ {
+ /* Too big, put in object first */
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_DATALOCATION;
+ pBuffer[OFFSET_DATA] = DL_OBJECT;
+ dataLocation = DL_OBJECT;
+
+ objACL.readPermission = MSC_AUT_PIN_1;
+ objACL.writePermission = MSC_AUT_PIN_1;
+ objACL.deletePermission = MSC_AUT_PIN_1;
+
+ rv = PL_MSCCreateObject(pConnection, IN_OBJECT_ID, inputDataSize,
+ &objACL);
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ rv = PL_MSCWriteLargeObject(pConnection, IN_OBJECT_ID, pInputData,
+ inputDataSize);
+
+ if ( rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ } else {
+ /* Can be placed into an apdu */
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_DATALOCATION + 2 + inputDataSize;
+ pBuffer[OFFSET_DATA] = DL_APDU;
+ dataLocation = DL_APDU;
+ currentPointer += MSC_SIZEOF_DATALOCATION;
+ {
+ // I'm not sure if inputDataSize has the right length for MemCopy16()
+ MSCUShort16 value = inputDataSize;
+ MemCopy16(&pBuffer[OFFSET_DATA + currentPointer], &value);
+ currentPointer += 2;
+ }
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInputData,
+ inputDataSize);
+ }
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ /* Operation must have failed */
+ if ( (transmitBuffer.apduResponseSize == 2)&&
+ (dataLocation == DL_APDU) ) {
+ return convertSW(apduResponse);
+
+ /* Output stored into apdu */
+ } else if ( (transmitBuffer.apduResponseSize > 2)&&
+ (dataLocation == DL_APDU) ) {
+ MemCopyTo16(&outSize, apduResponse);
+ memcpy(pOutputData, &apduResponse[MSC_SIZEOF_CRYPTLEN], outSize);
+ *outputDataSize = outSize;
+ return convertSW(&apduResponse[MSC_SIZEOF_CRYPTLEN+outSize]);
+
+ /* Output stored into an object */
+ } else if ( (transmitBuffer.apduResponseSize == 2)&&
+ (dataLocation == DL_OBJECT) ) {
+ rv = PL_MSCReadAllocateObject( pConnection, OUT_OBJECT_ID,
+ &ppRecvBuffer, outputDataSize );
+ if ( rv == MSC_SUCCESS ) {
+ /* Write Data Chunk Size */
+ setUShort16(ppRecvBuffer, *outputDataSize);
+ /* Write Data */
+ memcpy(pOutputData, &ppRecvBuffer[MSC_SIZEOF_CRYPTLEN],
+ getUShort16(ppRecvBuffer));
+ }
+
+ if ( ppRecvBuffer ) {
+ free(ppRecvBuffer);
+ }
+
+ return rv;
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+ }
+}
+
+MSC_RV PL_MSCExtAuthenticate( MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCUChar8 cipherMode, MSCUChar8 cipherDirection,
+ MSCPUChar8 pData, MSCULong32 dataSize )
+{
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ unsigned char dataLocation;
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_EXT_AUTH;
+ pBuffer[OFFSET_P1] = keyNum;
+ pBuffer[OFFSET_P2] = 0x00;
+
+ if (dataSize + MSC_SIZEOF_CIPHERMODE + MSC_SIZEOF_CIPHERDIR +
+ MSC_SIZEOF_DATALOCATION < MSC_MAXSIZEOF_APDU_DATALEN ) {
+ dataLocation = DL_APDU;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_CIPHERMODE + MSC_SIZEOF_CIPHERDIR +
+ MSC_SIZEOF_DATALOCATION + 2 + dataSize;
+ } else {
+ dataLocation = DL_OBJECT;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_CIPHERMODE + MSC_SIZEOF_CIPHERDIR +
+ MSC_SIZEOF_DATALOCATION;
+ }
+
+ pBuffer[OFFSET_DATA+MSC_SIZEOF_CIPHERMODE] = dataLocation;
+
+ currentPointer = 0;
+
+ pBuffer[OFFSET_DATA+currentPointer] = cipherMode;
+
+ currentPointer += MSC_SIZEOF_CIPHERMODE;
+
+ pBuffer[OFFSET_DATA+currentPointer] = cipherDirection;
+
+ currentPointer += MSC_SIZEOF_CIPHERDIR;
+
+ pBuffer[OFFSET_DATA+currentPointer] = dataLocation;
+
+ currentPointer += MSC_SIZEOF_DATALOCATION;
+
+ {
+ MSCUShort16 ush = dataSize;
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &ush);
+ currentPointer += 2;
+ }
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pData,
+ dataSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ /* dumpBinary(apduResponse, transmitBuffer.apduResponseSize); */
+ return convertSW(&apduResponse[transmitBuffer.apduResponseSize-2]);
+ }
+
+}
+
+MSC_RV PL_MSCListKeys( MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCULong32 currentPointer;
+ MSCTransmitBuffer transmitBuffer;
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_LIST_KEYS;
+ pBuffer[OFFSET_P1] = seqOption;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_KEYINFO;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ if ( convertSW(apduResponse) == MSC_SUCCESS ) {
+ /* Must have finished */
+ return MSC_SEQUENCE_END;
+ } else {
+ return convertSW(apduResponse);
+ }
+ } else if (transmitBuffer.apduResponseSize == MSC_SIZEOF_KEYINFO + 2 ) {
+
+ currentPointer = 0;
+
+ /* Key Number */
+ pKeyInfo->keyNum = apduResponse[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYNUMBER;
+
+ /* Key Type */
+ pKeyInfo->keyType = apduResponse[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYTYPE;
+
+ /* Key Partner */
+ pKeyInfo->keyPartner = apduResponse[currentPointer];
+ currentPointer += MSC_SIZEOF_KEYPARTNER;
+
+ /* Key Size */
+ MemCopyTo16(&pKeyInfo->keySize,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_KEYSIZE;
+
+ /* Key ACL */
+ MemCopyTo16(&pKeyInfo->keyACL.readPermission,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopyTo16(&pKeyInfo->keyACL.writePermission,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopyTo16(&pKeyInfo->keyACL.usePermission,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ switch(pKeyInfo->keyType)
+ {
+ case MSC_KEY_RSA_PUBLIC:
+ case MSC_KEY_RSA_PRIVATE:
+ case MSC_KEY_RSA_PRIVATE_CRT:
+ pKeyInfo->keyPolicy.cipherMode = MSC_KEYPOLICY_MODE_RSA_NOPAD;
+ pKeyInfo->keyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_SIGN | MSC_KEYPOLICY_DIR_VERIFY |
+ MSC_KEYPOLICY_DIR_ENCRYPT | MSC_KEYPOLICY_DIR_DECRYPT;
+ break;
+ case MSC_KEY_DES:
+ case MSC_KEY_3DES:
+ case MSC_KEY_3DES3:
+ pKeyInfo->keyPolicy.cipherMode = MSC_KEYPOLICY_MODE_DES_ECB_NOPAD;
+ pKeyInfo->keyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_ENCRYPT | MSC_KEYPOLICY_DIR_DECRYPT;
+ break;
+
+ default:
+ pKeyInfo->keyPolicy.cipherMode = 0;
+ pKeyInfo->keyPolicy.cipherDirection = 0;
+ break;
+ }
+
+ return convertSW(&apduResponse[currentPointer]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCCreatePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts, MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_CREATE_PIN;
+ pBuffer[OFFSET_P1] = pinNum;
+ pBuffer[OFFSET_P2] = pinAttempts;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_PINSIZE + MSC_SIZEOF_PINSIZE +
+ pinCodeSize + unblockCodeSize;
+
+ currentPointer = 0;
+
+ pBuffer[OFFSET_DATA+currentPointer] = pinCodeSize;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pPinCode,
+ pinCodeSize);
+
+ currentPointer += pinCodeSize;
+
+ pBuffer[OFFSET_DATA+currentPointer] = unblockCodeSize;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pUnblockCode,
+ unblockCodeSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCVerifyPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode, MSCULong32 pinCodeSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+
+ pBuffer = transmitBuffer.pBuffer; apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_VERIFY_PIN;
+ pBuffer[OFFSET_P1] = pinNum;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = pinCodeSize;
+
+ memcpy(&pBuffer[OFFSET_DATA], pPinCode, pinCodeSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCChangePIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_CHANGE_PIN;
+ pBuffer[OFFSET_P1] = pinNum;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_PINSIZE + MSC_SIZEOF_PINSIZE +
+ oldPinCodeSize + newPinCodeSize;
+
+ currentPointer = 0;
+
+ pBuffer[OFFSET_DATA+currentPointer] = oldPinCodeSize;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pOldPinCode,
+ oldPinCodeSize);
+
+ currentPointer += oldPinCodeSize;
+
+ pBuffer[OFFSET_DATA+currentPointer] = newPinCodeSize;
+
+ currentPointer += MSC_SIZEOF_PINSIZE;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pNewPinCode,
+ newPinCodeSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCUnblockPIN( MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode,
+ MSCULong32 unblockCodeSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_UNBLOCK_PIN;
+ pBuffer[OFFSET_P1] = pinNum;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = unblockCodeSize;
+
+ memcpy(&pBuffer[OFFSET_DATA], pUnblockCode, unblockCodeSize);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+MSC_RV PL_MSCListPINs( MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_LIST_PINS;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = 0x02;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else if ( transmitBuffer.apduResponseSize == 4 ) {
+ *pPinBitMask = 0x100 * apduResponse[0];
+ *pPinBitMask += apduResponse[1];
+ return convertSW(&apduResponse[2]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCCreateObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 objectSize,
+ MSCLPObjectACL pObjectACL ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ MSCULong32 _objectID;
+
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_CREATE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_OBJECTID + MSC_SIZEOF_OBJECTSIZE +
+ MSC_SIZEOF_ACLSTRUCT;
+
+ currentPointer = 0;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &_objectID);
+
+ currentPointer += MSC_SIZEOF_OBJECTID;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &objectSize);
+
+ currentPointer += MSC_SIZEOF_OBJECTSIZE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pObjectACL->readPermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pObjectACL->writePermission);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer],
+ &pObjectACL->deletePermission);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCDeleteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCUChar8 zeroFlag ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ MSCULong32 _objectID;
+
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_DELETE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = zeroFlag;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_OBJECTID;
+
+ currentPointer = 0;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &_objectID);
+
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCWriteObject( MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pInputData,
+ MSCUChar8 dataSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ MSCULong32 _objectID;
+
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_WRITE_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_OBJECTID + MSC_SIZEOF_OFFSET +
+ MSC_SIZEOF_RWDATA + dataSize;
+
+ currentPointer = 0;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &_objectID);
+
+ currentPointer = MSC_SIZEOF_OBJECTID;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &offset);
+
+ currentPointer += MSC_SIZEOF_OFFSET;
+
+ pBuffer[OFFSET_DATA+currentPointer] = dataSize;
+ currentPointer += MSC_SIZEOF_RWDATA;
+
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pInputData, dataSize);
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCReadObject( MSCLPTokenConnection pConnection, MSCString objectID,
+ MSCULong32 offset, MSCPUChar8 pOutputData,
+ MSCUChar8 dataSize ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ MSCULong32 _objectID;
+
+ if ( stringToID(&_objectID, objectID) )
+ return MSC_INVALID_PARAMETER;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_READ_OBJ;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_OBJECTID + MSC_SIZEOF_OFFSET +
+ MSC_SIZEOF_RWDATA;
+
+ currentPointer = 0;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &_objectID);
+
+ currentPointer = MSC_SIZEOF_OBJECTID;
+
+ MemCopy32(&pBuffer[OFFSET_DATA+currentPointer], &offset);
+
+ currentPointer += MSC_SIZEOF_OFFSET;
+ pBuffer[OFFSET_DATA+currentPointer] = dataSize;
+ transmitBuffer.bufferSize = pBuffer[OFFSET_LC] + 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else if (transmitBuffer.apduResponseSize == dataSize + 2 ) {
+ memcpy(pOutputData, apduResponse, dataSize);
+ return convertSW(&apduResponse[dataSize]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+}
+
+MSC_RV PL_MSCListObjects( MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCULong32 currentPointer;
+ MSCULong32 _objectID;
+
+ rv=0; currentPointer=0;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_LIST_OBJECTS;
+ pBuffer[OFFSET_P1] = seqOption;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_OBJECTID + MSC_SIZEOF_OBJECTSIZE
+ + MSC_SIZEOF_ACLSTRUCT;
+
+ transmitBuffer.bufferSize = 5;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ if ( convertSW(apduResponse) == MSC_SUCCESS ) {
+ /* Must have finished */
+ return MSC_SEQUENCE_END;
+ } else {
+ return convertSW(apduResponse);
+ }
+ } else if (transmitBuffer.apduResponseSize == pBuffer[OFFSET_LC] + 2 ) {
+ currentPointer = 0;
+ MemCopyTo32(&_objectID, &apduResponse[currentPointer]);
+ idToString(pObjectInfo->objectID, _objectID);
+
+ currentPointer += MSC_SIZEOF_OBJECTID;
+
+ MemCopyTo32(&pObjectInfo->objectSize, &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_OBJECTSIZE;
+
+ MemCopyTo16(&pObjectInfo->objectACL.readPermission,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopyTo16(&pObjectInfo->objectACL.writePermission,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ MemCopyTo16(&pObjectInfo->objectACL.deletePermission,
+ &apduResponse[currentPointer]);
+
+ currentPointer += MSC_SIZEOF_ACLVALUE;
+
+ return convertSW(&apduResponse[currentPointer]);
+
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCLogoutAll( MSCLPTokenConnection pConnection ) {
+
+ MSCLong32 rv;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_LOGOUT_ALL;
+ pBuffer[OFFSET_P1] = 0x00;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = 0x02;
+ pBuffer[OFFSET_DATA] = 0x00;
+ pBuffer[OFFSET_DATA+1] = 0x00;
+
+ transmitBuffer.bufferSize = 7;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(apduResponse);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV PL_MSCGetChallenge( MSCLPTokenConnection pConnection, MSCPUChar8 pSeed,
+ MSCUShort16 seedSize, MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize ) {
+
+ MSCLong32 rv;
+ MSCULong32 currentPointer;
+
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+ MSCTransmitBuffer transmitBuffer;
+ MSCUShort16 chall_size;
+
+ if ( pRandomData == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if ( randomDataSize == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = CardEdge_CLA;
+ pBuffer[OFFSET_INS] = INS_GET_CHALLENGE;
+ pBuffer[OFFSET_P1] = 0x00;
+
+ /* We must dump the random to an object if it is too large */
+ if ( randomDataSize > 255 ) {
+ pBuffer[OFFSET_P2] = DL_OBJECT;
+ } else {
+ pBuffer[OFFSET_P2] = DL_APDU;
+ }
+
+ /* Short + Short + size of seed */
+ pBuffer[OFFSET_LC] = MSC_SIZEOF_RANDOMSIZE +
+ MSC_SIZEOF_SEEDLENGTH + seedSize;
+
+ currentPointer = 0;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &randomDataSize);
+
+ currentPointer = MSC_SIZEOF_RANDOMSIZE;
+
+ MemCopy16(&pBuffer[OFFSET_DATA+currentPointer], &seedSize);
+
+ currentPointer += MSC_SIZEOF_SEEDLENGTH;
+
+ if (seedSize > 0)
+ memcpy(&pBuffer[OFFSET_DATA+currentPointer], pSeed,
+ seedSize);
+
+ transmitBuffer.bufferSize = 5 + MSC_SIZEOF_RANDOMSIZE +
+ MSC_SIZEOF_SEEDLENGTH + seedSize;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ /* dumpBinary(apduResponse, transmitBuffer.apduResponseSize); */
+ MemCopyTo16(&chall_size, apduResponse);
+
+ if (( transmitBuffer.apduResponseSize == randomDataSize + 4 ) &&
+ (chall_size == randomDataSize)) {
+ memcpy(pRandomData, apduResponse + 2, randomDataSize);
+ return convertSW(&apduResponse[transmitBuffer.apduResponseSize-2]);
+ } else if ( transmitBuffer.apduResponseSize == 2 ) {
+ return convertSW(&apduResponse[transmitBuffer.apduResponseSize-2]);
+ } else {
+ return MSC_UNSPECIFIED_ERROR;
+ }
+
+}
+
+MSC_RV lcMSCGetObjectAttributes( MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCLPObjectInfo pObjectInfo ) {
+ MSC_RV rv;
+ MSCString pObjectID;
+ MSCChar8 pStringID[MSC_MAXSIZE_OBJID];
+ MSCObjectInfo objInfo;
+
+ if ( pConnection == NULL ) return MSC_INVALID_PARAMETER;
+
+ rv = PL_MSCListObjects( pConnection, MSC_SEQUENCE_RESET, &objInfo );
+
+ if ( rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS) {
+ return rv;
+ }
+
+ if ( rv == MSC_SEQUENCE_END ) {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ if ( strcmp(objectID, IN_OBJECT_ID) == 0 ) {
+ idToString( pStringID, 0xFFFFFFFE );
+ pObjectID = pStringID;
+ } else if ( strcmp(objectID, OUT_OBJECT_ID) == 0 ) {
+ idToString( pStringID, 0xFFFFFFFF );
+ pObjectID = pStringID;
+ } else {
+ pObjectID = objectID;
+ }
+
+ if (strncmp(pObjectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0 ) {
+ pObjectInfo->objectSize = objInfo.objectSize;
+ pObjectInfo->objectACL.readPermission =
+ objInfo.objectACL.readPermission;
+ pObjectInfo->objectACL.writePermission =
+ objInfo.objectACL.writePermission;
+ pObjectInfo->objectACL.deletePermission =
+ objInfo.objectACL.deletePermission;
+ strncpy(pObjectInfo->objectID, pObjectID, MSC_MAXSIZE_OBJID);
+ return MSC_SUCCESS;
+ }
+
+ do {
+ rv = PL_MSCListObjects( pConnection, MSC_SEQUENCE_NEXT, &objInfo );
+ if (strncmp(pObjectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0 )
+ break;
+ } while ( rv == MSC_SUCCESS );
+
+ if ( rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS ) {
+ return rv;
+ }
+
+ if ( rv == MSC_SEQUENCE_END ) {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ pObjectInfo->objectSize = objInfo.objectSize;
+ pObjectInfo->objectACL.readPermission =
+ objInfo.objectACL.readPermission;
+ pObjectInfo->objectACL.writePermission =
+ objInfo.objectACL.writePermission;
+ pObjectInfo->objectACL.deletePermission =
+ objInfo.objectACL.deletePermission;
+ strncpy(pObjectInfo->objectID, pObjectID, MSC_MAXSIZE_OBJID);
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCReadAllocateObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCPUChar8 *pOutputData,
+ MSCPULong32 dataSize ) {
+
+ MSC_RV rv;
+ MSCObjectInfo objInfo;
+
+ MSCULong32 objectSize;
+
+ if ( pOutputData == 0 ) {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ rv = lcMSCGetObjectAttributes( pConnection, objectID, &objInfo );
+
+ if ( rv != MSC_SUCCESS ) {
+ *dataSize = 0;
+ *pOutputData = 0;
+ return rv;
+ }
+
+ objectSize = objInfo.objectSize;
+ *dataSize = objectSize;
+ *pOutputData = (MSCPUChar8)malloc(sizeof(MSCUChar8)*objectSize);
+
+ return PL_MSCReadLargeObject( pConnection, objectID, *pOutputData,
+ objectSize );
+
+}
+
+MSC_RV PL_MSCReadLargeObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCPUChar8 pOutputData,
+ MSCULong32 dataSize ) {
+
+ MSC_RV rv;
+ MSCULong32 objectSize;
+ int i;
+
+ objectSize = dataSize;
+ rv = MSC_UNSPECIFIED_ERROR;
+
+ /* Read the key from the default object */
+ for (i=0; i < objectSize/MSC_SIZEOF_KEYPACKET; i++) {
+ rv = PL_MSCReadObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pOutputData[i*MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+ if ( objectSize%MSC_SIZEOF_KEYPACKET ) {
+ rv = PL_MSCReadObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pOutputData[i*MSC_SIZEOF_KEYPACKET],
+ objectSize%MSC_SIZEOF_KEYPACKET );
+
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+ return rv;
+}
+
+MSC_RV PL_MSCWriteLargeObject( MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCPUChar8 pInputData,
+ MSCULong32 dataSize ) {
+ MSC_RV rv;
+ MSCULong32 objectSize;
+ int i;
+
+ objectSize = dataSize;
+ rv = MSC_UNSPECIFIED_ERROR;
+
+ /* Read the key from the default object */
+ for (i=0; i < objectSize/MSC_SIZEOF_KEYPACKET; i++) {
+ rv = PL_MSCWriteObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pInputData[i*MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET );
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+
+ if ( objectSize%MSC_SIZEOF_KEYPACKET ) {
+ rv = PL_MSCWriteObject( pConnection, objectID,
+ i*MSC_SIZEOF_KEYPACKET,
+ &pInputData[i*MSC_SIZEOF_KEYPACKET],
+ objectSize%MSC_SIZEOF_KEYPACKET );
+
+ if ( rv != MSC_SUCCESS ) { return rv; }
+ }
+
+ return rv;
+}
+
+int idToString( char *objectString, MSCULong32 objectID ) {
+
+ MSCUChar8 objBytes[MSC_MAXSIZE_OBJID];
+
+ MemCopy32(objBytes, &objectID);
+
+ snprintf(objectString, MSC_MAXSIZE_OBJID, "%c%c%c%c", objBytes[0],
+ objBytes[1], objBytes[2], objBytes[3]);
+ return 0;
+}
+
+int stringToID( MSCPULong32 objectID, char *objectString ) {
+
+ MSCULong32 localID;
+ MSCUChar8 objBytes[MSC_MAXSIZE_OBJID];
+ int i;
+
+ localID = 0;
+
+ if ( strcmp(objectString, IN_OBJECT_ID) == 0 ) {
+ *objectID = 0xFFFFFFFE;
+ return 0;
+ } else if ( strcmp(objectString, OUT_OBJECT_ID) == 0 ) {
+ *objectID = 0xFFFFFFFF;
+ return 0;
+ }
+
+ if (strlen(objectString) > MSC_SIZEOF_OBJECTID) {
+ return -1;
+ }
+
+ objBytes[0] = objectString[0];
+ objBytes[1] = objectString[1];
+ objBytes[2] = objectString[2];
+ objBytes[3] = objectString[3];
+
+ for (i=strlen(objectString); i < 4; i++) {
+ objBytes[i] = 0x00; /* Pad with NULL */
+ }
+
+ MemCopyTo32(&localID, objBytes);
+
+ if ( localID == 0 ) {
+ return -1;
+ }
+
+ *objectID = localID;
+ return 0;
+}
+
+
+/* Some local helper functions */
+
+MSCUShort16 convertSW(MSCPUChar8 pBuffer) {
+ MSCUShort16 retValue;
+
+ retValue = pBuffer[0] * 0x100;
+ retValue += pBuffer[1];
+
+ return retValue;
+}
+
+void MemCopy16(MSCPUChar8 destValue, MSCPUShort16 srcValue) {
+ destValue[0] = (*srcValue & 0xFF00) >> 8;
+ destValue[1] = (*srcValue & 0x00FF);
+}
+
+void MemCopy32(MSCPUChar8 destValue, MSCPULong32 srcValue) {
+ destValue[0] = (*srcValue >> 24);
+ destValue[1] = (*srcValue & 0x00FF0000) >> 16;
+ destValue[2] = (*srcValue & 0x0000FF00) >> 8;
+ destValue[3] = (*srcValue & 0x000000FF);
+}
+
+void MemCopyTo16(MSCPUShort16 destValue, MSCPUChar8 srcValue) {
+
+ *destValue = srcValue[0] * 0x100;
+ *destValue += srcValue[1];
+
+}
+
+void MemCopyTo32(MSCPULong32 destValue, MSCPUChar8 srcValue) {
+
+ *destValue = srcValue[0] * 0x1000000;
+ *destValue += srcValue[1] * 0x10000;
+ *destValue += srcValue[2] * 0x100;
+ *destValue += srcValue[3];
+
+}
+
+MSCUShort16 getUShort16(MSCPUChar8 srcValue) {
+ return ( (((MSCUShort16)srcValue[0]) << 8) || srcValue[1] );
+}
+
+void setUShort16(MSCPUChar8 dstValue, MSCUShort16 srcValue) {
+ MemCopyTo16(&srcValue, dstValue);
+}
+
+
+MSCLong32 SCardExchangeAPDU( MSCLPTokenConnection pConnection,
+ MSCLPTransmitBuffer transmitBuffer ) {
+
+ MSCLong32 rv, ret;
+ MSCULong32 originalLength;
+ MSCUChar8 getResponse[5] = {0x00, 0xC0, 0x00, 0x00, 0x00};
+ MSCULong32 dwActiveProtocol;
+ int i;
+
+ originalLength = transmitBuffer->apduResponseSize;
+
+ while (1) {
+
+#ifdef MSC_DEBUG
+ printf("->: ");
+
+#define DEBUG_INS(a, b) if ((a) == (b)) printf("[" #b "] ");
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_MSC_GEN_KEYPAIR);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_IMPORT_KEY);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_EXPORT_KEY);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_COMPUTE_CRYPT);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_CREATE_PIN);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_VERIFY_PIN);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_CHANGE_PIN);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_UNBLOCK_PIN);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_LOGOUT_ALL);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_GET_CHALLENGE);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_EXT_AUTH);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_CREATE_OBJ);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_DELETE_OBJ);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_READ_OBJ);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_WRITE_OBJ);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_LIST_OBJECTS);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_LIST_PINS);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_LIST_KEYS);
+ DEBUG_INS(transmitBuffer->pBuffer[OFFSET_INS], INS_GET_STATUS);
+
+ for (i=0; i < transmitBuffer->bufferSize; i++) {
+ printf("%02x ", transmitBuffer->pBuffer[i]);
+ } printf("\n");
+#endif
+
+ while(1) {
+ transmitBuffer->apduResponseSize = originalLength;
+
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ transmitBuffer->pBuffer,
+ transmitBuffer->bufferSize, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+ break;
+
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+ /* Must be a BIG, BAD, ERROR */
+#ifdef MSC_DEBUG
+ printf("Transmit error: %x\n", (unsigned int) rv);
+#endif
+ return rv;
+ }
+ }
+
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+
+ if ( transmitBuffer->apduResponseSize == 2 &&
+ transmitBuffer->apduResponse[0] == 0x61 ) {
+#ifdef MSC_DEBUG
+ printf("->: 0x00 0xC0 0x00 0x00 %02x\n",
+ transmitBuffer->apduResponse[1]);
+#endif
+ getResponse[4] = transmitBuffer->apduResponse[1];
+ transmitBuffer->apduResponseSize = originalLength;
+ rv = SCardTransmit(pConnection->hCard, pConnection->ioType,
+ getResponse, 5, 0,
+ transmitBuffer->apduResponse,
+ &transmitBuffer->apduResponseSize );
+
+ if ( rv == SCARD_S_SUCCESS ) {
+#ifdef MSC_DEBUG
+ printf("<-: ");
+
+ for (i=0; i < transmitBuffer->apduResponseSize; i++) {
+ printf("%02x ", transmitBuffer->apduResponse[i]);
+ } printf("\n");
+#endif
+ break;
+ } else if ( rv == SCARD_W_RESET_CARD ) {
+ pConnection->tokenInfo.tokenType |= MSC_TOKEN_TYPE_RESET;
+ ret = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+ PL_MSCIdentifyToken(pConnection);
+
+
+ if ( ret == SCARD_S_SUCCESS ) {
+ continue;
+ }
+
+ } else if ( rv == SCARD_W_REMOVED_CARD ) {
+ /* Push REMOVED_TOKEN back to the application */
+ pConnection->tokenInfo.tokenType = MSC_TOKEN_TYPE_REMOVED;
+ return rv;
+ } else {
+#ifdef MSC_DEBUG
+ printf("Transmit error: %x\n", (unsigned int) rv);
+#endif
+ return rv;
+ }
+
+ } /* if needs get response */
+
+ break;
+ } /* End of while */
+
+
+ return rv;
+}
+
+MSC_RV PL_MSCIdentifyToken( MSCLPTokenConnection pConnection ) {
+
+ MSCLong32 rv;
+ MSCTransmitBuffer transmitBuffer;
+ MSCPUChar8 apduResponse; MSCPUChar8 pBuffer;
+
+ pBuffer = transmitBuffer.pBuffer;
+ apduResponse = transmitBuffer.apduResponse;
+
+ pBuffer[OFFSET_CLA] = 0x00;
+ pBuffer[OFFSET_INS] = 0xA4;
+ pBuffer[OFFSET_P1] = 0x04;
+ pBuffer[OFFSET_P2] = 0x00;
+ pBuffer[OFFSET_LC] = pConnection->tokenInfo.tokenAppLen;
+
+ memcpy(&pBuffer[OFFSET_DATA], pConnection->tokenInfo.tokenApp,
+ pConnection->tokenInfo.tokenAppLen);
+
+ transmitBuffer.bufferSize = 5 + pConnection->tokenInfo.tokenAppLen;
+
+ /* Set up the APDU exchange */
+ transmitBuffer.apduResponseSize = MSC_MAXSIZE_BUFFER;
+ rv = SCardExchangeAPDU( pConnection, &transmitBuffer );
+
+ if ( rv != SCARD_S_SUCCESS ) {
+ return convertPCSC(rv);
+ }
+
+ if ( transmitBuffer.apduResponseSize == 2 && apduResponse[0] == 0x90 ) {
+ return MSC_SUCCESS;
+ } else {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+}
+
+MSC_RV PL_MSCInitializePlugin( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV PL_MSCFinalizePlugin( MSCLPTokenConnection pConnection ) {
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV convertPCSC( MSCLong32 pcscCode ) {
+
+ switch(pcscCode) {
+ case SCARD_S_SUCCESS:
+ return MSC_SUCCESS;
+ case SCARD_E_INVALID_HANDLE:
+ return MSC_INVALID_HANDLE;
+ case SCARD_E_SHARING_VIOLATION:
+ return MSC_SHARING_VIOLATION;
+ case SCARD_W_REMOVED_CARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_E_NO_SMARTCARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_W_RESET_CARD:
+ return MSC_TOKEN_RESET;
+ case SCARD_W_INSERTED_CARD:
+ return MSC_TOKEN_INSERTED;
+ case SCARD_E_NO_SERVICE:
+ return MSC_SERVICE_UNRESPONSIVE;
+ case SCARD_E_UNKNOWN_CARD:
+ case SCARD_W_UNSUPPORTED_CARD:
+ case SCARD_E_CARD_UNSUPPORTED:
+ return MSC_UNRECOGNIZED_TOKEN;
+ case SCARD_E_INVALID_PARAMETER:
+ case SCARD_E_INVALID_VALUE:
+ case SCARD_E_UNKNOWN_READER:
+ case SCARD_E_PROTO_MISMATCH:
+ case SCARD_E_READER_UNAVAILABLE:
+ return MSC_INVALID_PARAMETER;
+ case SCARD_E_CANCELLED:
+ return MSC_CANCELLED;
+ case SCARD_E_TIMEOUT:
+ return MSC_TIMEOUT_OCCURRED;
+
+ default:
+ return MSC_INTERNAL_ERROR;
+ }
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/MCardPlugin/musclecardApplet.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : musclecardApplet.h
+ Package: Musclecard Plugin
+ Author : David Corcoran
+ Date : 10/02/01
+ License: Copyright (C) 2001 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts the MUSCLE Card Edge Inteface
+
+
+********************************************************************/
+
+#ifndef __musclecardApplet_h__
+#define __musclecardApplet_h__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+// Data Locations admitted in ComputeCrypt()
+#define DL_APDU 0x01
+#define DL_OBJECT 0x02
+
+/* Some useful offsets in the buffer */
+#define OFFSET_CLA 0x00
+#define OFFSET_INS 0x01
+#define OFFSET_P1 0x02
+#define OFFSET_P2 0x03
+#define OFFSET_P3 0x04
+#define OFFSET_LC 0x04
+#define OFFSET_DATA 0x05
+
+ // Import/Export Object ID
+#define IN_OBJECT_ID "0xFFFFFFFE"
+#define OUT_OBJECT_ID "0xFFFFFFFF"
+
+ // code of CLA byte in the command APDU header
+#define CardEdge_CLA 0xB0
+
+ /****************************************
+ * Instruction codes *
+ ****************************************/
+
+#define INS_WRITE_FRAMEWORK 0x2A
+ // Keys' use and management
+#define INS_MSC_GEN_KEYPAIR 0x30
+#define INS_IMPORT_KEY 0x32
+#define INS_EXPORT_KEY 0x34
+#define INS_COMPUTE_CRYPT 0x36
+
+ // External authentication
+#define INS_CREATE_PIN 0x40
+#define INS_VERIFY_PIN 0x42
+#define INS_CHANGE_PIN 0x44
+#define INS_UNBLOCK_PIN 0x46
+#define INS_LOGOUT_ALL 0x60
+#define INS_GET_CHALLENGE 0x62
+#define INS_EXT_AUTH 0x38
+
+ // Objects' use and management
+#define INS_CREATE_OBJ 0x5A
+#define INS_DELETE_OBJ 0x52
+#define INS_READ_OBJ 0x56
+#define INS_WRITE_OBJ 0x54
+
+ // Status information
+#define INS_LIST_OBJECTS 0x58
+#define INS_LIST_PINS 0x48
+#define INS_LIST_KEYS 0x3A
+#define INS_GET_STATUS 0x3C
+
+ /* Sizes of particular objects */
+#define MSC_SIZEOF_OBJECTID 4
+#define MSC_SIZEOF_OBJECTSIZE 4
+#define MSC_SIZEOF_KEYINFO 11
+#define MSC_SIZEOF_STATUS 16
+#define MSC_SIZEOF_VERSION 2
+#define MSC_SIZEOF_FREEMEM 4
+#define MSC_SIZEOF_LOGIDS 2
+#define MSC_SIZEOF_ADDINFO 8
+#define MSC_SIZEOF_OPTLEN 2
+#define MSC_SIZEOF_GENOPTIONS 1
+#define MSC_SIZEOF_KEYSIZE 2
+#define MSC_SIZEOF_KEYNUMBER 1
+#define MSC_SIZEOF_KEYTYPE 1
+#define MSC_SIZEOF_KEYPARTNER 1
+#define MSC_SIZEOF_CIPHERMODE 1
+#define MSC_SIZEOF_CIPHERDIR 1
+#define MSC_SIZEOF_CRYPTLEN 2
+#define MSC_SIZEOF_ALGOTYPE 1
+#define MSC_SIZEOF_IDUSED 1
+#define MSC_SIZEOF_OFFSET 4
+#define MSC_SIZEOF_ACLSTRUCT 6
+#define MSC_SIZEOF_RWDATA 1
+#define MSC_SIZEOF_PINSIZE 1
+#define MSC_SIZEOF_PINTRIES 1
+#define MSC_SIZEOF_CIPHERMODE 1
+#define MSC_SIZEOF_CIPHERDIR 1
+#define MSC_SIZEOF_DATALOCATION 1
+#define MSC_SIZEOF_ACLVALUE 2
+#define MSC_SIZEOF_SEEDLENGTH 2
+#define MSC_SIZEOF_RANDOMSIZE 2
+#define MSC_SIZEOF_MINIACL 1
+
+ /* Selects applet - Not to be used by applications */
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCInitializePlugin(
+ MSCLPTokenConnection pConnection
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCFinalizePlugin(
+ MSCLPTokenConnection pConnection
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCIdentifyToken(
+ MSCLPTokenConnection pConnection
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteFramework(
+ MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams
+);
+
+ /*****************************************************************/
+ /* Core Musclecard functions */
+ /* These functions coorespond directly to internal library */
+ /* functions. */
+ /*****************************************************************/
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCGetStatus(
+ MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCGetCapabilities(
+ MSCLPTokenConnection pConnection,
+ MSCULong32 Tag,
+ MSCPUChar8 Value,
+ MSCPULong32 Length
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCExtendedFeature(
+ MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature,
+ MSCPUChar8 outData,
+ MSCULong32 outLength,
+ MSCPUChar8 inData,
+ MSCPULong32 inLength
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCGenerateKeys(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum,
+ MSCUChar8 pubKeyNum,
+ MSCLPGenKeyParams pParams
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCImportKey(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL,
+ MSCPUChar8 pKeyBlob,
+ MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCExportKey(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob,
+ MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCComputeCrypt(
+ MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit,
+ MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize,
+ MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCExtAuthenticate(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData,
+ MSCULong32 dataSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCListKeys(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCCreatePIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize,
+ MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCVerifyPIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCChangePIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode,
+ MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode,
+ MSCUChar8 newPinCodeSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCUnblockPIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode,
+ MSCULong32 unblockCodeSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCListPINs(
+ MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCCreateObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 objectSize,
+ MSCLPObjectACL pObjectACL
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCDeleteObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCUChar8 zeroFlag
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCWriteObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset,
+ MSCPUChar8 pInputData,
+ MSCUChar8 dataSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCReadObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset,
+ MSCPUChar8 pOutputData,
+ MSCUChar8 dataSize
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCListObjects(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCLogoutAll(
+ MSCLPTokenConnection pConnection
+);
+
+#ifdef WIN32
+MCARDPLUGIN_API
+#endif
+MSC_RV PL_MSCGetChallenge(
+ MSCLPTokenConnection pConnection,
+ MSCPUChar8 pSeed,
+ MSCUShort16 seedSize,
+ MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize
+);
+
+ /*****************************************************************/
+ /* Extended Musclecard functions */
+ /* These functions do not coorespond to internal library funcions */
+ /* but rather use them to provide some extended functionality. */
+ /*****************************************************************/
+
+MSC_RV PL_MSCGetKeyAttributes(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNumber,
+ MSCLPKeyInfo pKeyInfo
+);
+
+MSC_RV PL_MSCGetObjectAttributes(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCLPObjectInfo pObjectInfo
+);
+
+MSC_RV PL_MSCWriteLargeObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCPUChar8 pInputData,
+ MSCULong32 dataSize
+);
+
+MSC_RV PL_MSCReadLargeObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCPUChar8 pOutputData,
+ MSCULong32 dataSize
+);
+
+MSC_RV PL_MSCReadAllocateObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCPUChar8* pOutputData,
+ MSCPULong32 dataSize
+);
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __musclecardApplet_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSC.exp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSC.exp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSC.exp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,71 @@
+_DebugLogSetLevel
+_DebugLogSetLogType
+_MSCBeginTransaction
+_MSCCancelEventWait
+_MSCChangePIN
+_MSCClearReset
+_MSCComputeCrypt
+_MSCCreateObject
+_MSCCreatePIN
+_MSCDeleteObject
+_MSCEndTransaction
+_MSCEstablishConnection
+_MSCExportKey
+_MSCExtAuthenticate
+_MSCExtendedFeature
+_MSCGenerateKeys
+_MSCGetCapabilities
+_MSCGetChallenge
+_MSCGetKeyAttributes
+_MSCGetObjectAttributes
+_MSCGetStatus
+_MSCImportKey
+_MSCIsTokenChanged
+_MSCIsTokenKnown
+_MSCIsTokenMoved
+_MSCIsTokenReset
+_MSCListKeys
+_MSCListObjects
+_MSCListPINs
+_MSCListTokens
+_MSCLogoutAll
+_MSCReEstablishConnection
+_MSCReadAllocateObject
+_MSCReadObject
+_MSCReleaseConnection
+_MSCUnblockPIN
+_MSCVerifyPIN
+_MSCWaitForTokenEvent
+_MSCWriteFramework
+_MSCWriteObject
+_PCSCVersionNumber
+_PCSCVersionString
+_SCardBeginTransaction
+_SCardCancel
+_SCardCancelTransaction
+_SCardConnect
+_SCardControl
+_SCardControl132
+_SCardDisconnect
+_SCardEndTransaction
+_SCardEstablishContext
+_SCardGetAttrib
+_SCardGetStatusChange
+_SCardIsValidContext
+_SCardListReaderGroups
+_SCardListReaders
+_SCardReconnect
+_SCardReleaseContext
+_SCardSetAttrib
+_SCardSetTimeout
+_SCardStatus
+_SCardTransmit
+_SCardUnload
+_TPSvcDropdir
+_mscLockThread
+_mscUnLockThread
+_msc_error
+_pcsc_stringify_error
+_g_rgSCardT0Pci
+_g_rgSCardT1Pci
+_g_rgSCardRawPci
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * PCSCDevice.cpp
+ * SmartCardServices
+ *
+ */
+
+#include "PCSCDevice.h"
+#include <security_utilities/debugging.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/usb/IOUSBLib.h>
+
+namespace PCSCD {
+
+Device::~Device() throw()
+{
+}
+
+void Device::dump()
+{
+ //, serial: %s", // always empty for known readers, mSerialNumber.c_str());
+ secdebug("device", " Service: 0x%04X, Address: 0x%08X, vendor/product: 0x%04X/0x%04X, vendor/product: %s/%s",
+ ioObject(), mAddress, mVendorid, mProductid, mVendorName.c_str(), mProductName.c_str());
+ secdebug("device", " path: %s", path().c_str());
+}
+
+/*
+Device::Device(const Device& x) throw() // copy constructor
+{
+ *this = x;
+}
+
+Device& Device::operator= (const Device& x) throw() // assignment operator
+{
+ mAddress = x.mAddress;
+ mName = x.mName;
+ mLibPath = x.mLibPath;
+ return *this;
+}
+*/
+
+} // end namespace PCSCD
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDevice.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * PCSCDevice.h
+ * SmartCardServices
+ *
+ */
+
+#ifndef _H_PCSCDEVICE
+#define _H_PCSCDEVICE
+
+#include <security_utilities/iodevices.h>
+#include <security_utilities/refcount.h>
+
+#if defined(__cplusplus)
+
+namespace PCSCD {
+
+class Device : public IOKit::Device, public RefCount
+{
+public:
+// Device() : { }
+ Device(io_service_t d) : IOKit::Device(d) { }
+
+ virtual ~Device() throw();
+
+ bool operator < (const Device &other) const { return this->address() < other.address(); }
+
+ void setAddress(uint32_t address) { mAddress = address; }
+ void setInterfaceClass(uint32_t interfaceClass) { mInterfaceClass = interfaceClass; }
+ void setDeviceClass(uint32_t deviceClass) { mDeviceClass = deviceClass; }
+ void setVendorid(uint32_t vendorid) { mVendorid = vendorid; }
+ void setProductid(uint32_t productid) { mProductid = productid; }
+ void setPath(const std::string path) { mLibPath = path; }
+ void setName(const std::string name) { mName = name; }
+ void setIsPCCard(bool isPCCard) { mIsPCCard = isPCCard; }
+
+ uint32_t address() const { return mAddress; }
+ uint32_t interfaceClass() const { return mInterfaceClass; }
+ uint32_t deviceClass() const { return mDeviceClass; }
+ uint32_t vendorid() const { return mVendorid; }
+ uint32_t productid() const { return mProductid; }
+ std::string path() const { return mLibPath; }
+ std::string name() const { return mName; }
+ bool isPCCard() const { return mIsPCCard; }
+
+ std::string vendorName() const { return mVendorName; }
+ std::string productName() const { return mProductName; }
+ std::string serialNumber() const { return mSerialNumber; }
+
+ void setDebugParams(const std::string vendorName, const std::string productName,
+ const std::string serialNumber)
+ { mVendorName = vendorName; mProductName = productName; mSerialNumber = serialNumber;}
+
+ void dump();
+
+private:
+
+ uint32_t mAddress;
+
+ std::string mName; // Manufacturer's name for device
+ std::string mLibPath; // path to driver bundle from PCSCDriverBundle
+
+ uint32_t mInterfaceClass; // If present, one of kUSBChipSmartCardInterfaceClass/kUSBVendorSpecificInterfaceClass
+ uint32_t mDeviceClass; // If == kUSBVendorSpecificClass, check vendor/product
+ uint32_t mVendorid;
+ uint32_t mProductid;
+
+ bool mIsPCCard;
+
+ // Mainly for debugging
+ std::string mVendorName, mProductName, mSerialNumber;
+};
+
+} // end namespace PCSCD
+
+#endif /* __cplusplus__ */
+
+#endif // _H_PCSCDEVICE
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,261 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * PCSCDriverBundle.cpp
+ * SmartCardServices
+ */
+
+/*
+ A driver bundle is a standard Mac OS X bundle that usually lives in the directory:
+
+ /usr/libexec/SmartCardServices/drivers/
+
+ The two major components of this bundle are the executable and the Info.plist. A single
+ driver bundle may provide support for multiple readers. See
+
+ <rdar://problem/4432039> pcscd crash for multiple VID/PIDs
+ and
+ <http://pcsclite.alioth.debian.org/ifdhandler-3/node7.html>
+
+ The key that determines if a driver supports only one reader or multiple readers is
+ "ifdVendorID", sometimes referred to as the manufacturer name. If this is a
+ CFStringRef, then only one reader is supported; if it is a CFArrayRef, then
+ multiple readers are supports. There are three fields for each reader:
+
+ VendorID uint32_t
+ ProductID uint32_t
+ Friendly name string
+
+ See e.g. http://pcsclite.alioth.debian.org/ccid.html for a working driver with multiple IDs.
+
+*/
+
+#include "PCSCDriverBundle.h"
+#include <CoreFoundation/CoreFoundation.h>
+#include <security_utilities/cfutilities.h>
+#include <security_utilities/debugging.h>
+#include <security_utilities/errors.h>
+#include <IOKit/usb/USBSpec.h>
+#include <IOKit/usb/USB.h>
+
+#define DEBUG_BUNDLE_MATCHES 1
+
+namespace PCSCD {
+
+// Keys in CFDictionary for bundle's Info.plist
+static const CFStringRef kManufacturerName = CFSTR("ifdVendorID");
+static const CFStringRef kProductName = CFSTR("ifdProductID");
+static const CFStringRef kFriendlyName = CFSTR("ifdFriendlyName");
+static const CFStringRef kInterfaceClass = CFSTR("ifdInterfaceClass");
+static const CFStringRef kInterfaceSubClass = CFSTR("ifdInterfaceSubClass");
+static const CFStringRef kInterfaceProtocol = CFSTR("ifdInterfaceProtocol");
+
+DriverBundle::DriverBundle(CFBundleRef bundle) : LoadableBundle(bundle)
+{
+ initialize(CFBundleGetInfoDictionary(bundle));
+}
+
+void DriverBundle::initialize(CFDictionaryRef dict)
+{
+ const int radix = 16;
+
+ try
+ {
+ CFTypeRef vend = CFDictionaryGetValue(dict, kManufacturerName);
+ if (!vend)
+ {
+ // Must be a class driver
+ secdebug("pcscd", "Class Driver: %s", path().c_str());
+ std::string istr(getStringAttr(dict,kInterfaceClass));
+ uint8_t dclass = strtoul(istr.c_str(), NULL, radix);
+ std::string sstr(getStringAttr(dict,kInterfaceSubClass));
+ uint8_t dsubclass = strtoul(sstr.c_str(), NULL, radix);
+ std::string pstr(getStringAttr(dict,kInterfaceProtocol));
+ uint8_t dprotocol = strtoul(pstr.c_str(), NULL, radix);
+ std::string name(getStringAttr(dict,kFriendlyName));
+ DeviceDescription *dev = new DeviceDescription(dclass, dsubclass, dprotocol, name);
+ addProduct(dev);
+ }
+ else
+ if (CFGetTypeID(vend) == CFArrayGetTypeID())
+ {
+ secdebug("pcscd", "Driver with aliases: %s", path().c_str());
+ CFTypeRef xprod = CFDictionaryGetValue(dict, kProductName);
+ CFTypeRef xname = CFDictionaryGetValue(dict, kFriendlyName);
+ if (!xprod || !xname ||
+ (CFGetTypeID(xprod) != CFArrayGetTypeID()) || (CFGetTypeID(xname) != CFArrayGetTypeID()))
+ CFError::throwMe();
+ CFRef<CFArrayRef> products(reinterpret_cast<CFArrayRef>(xprod));
+ CFRef<CFArrayRef> names (reinterpret_cast<CFArrayRef>(xname));
+ const int productCount = CFArrayGetCount(reinterpret_cast<CFArrayRef>(vend));
+ // Make sure parallel arrays vendor, product, name are same size
+ if ((productCount != CFArrayGetCount(products)) ||
+ (productCount != CFArrayGetCount(names)))
+ CFError::throwMe();
+
+ for (int ix=0;ix<productCount;++ix)
+ {
+ std::string vstr(getStringAttr(reinterpret_cast<CFArrayRef>(vend), ix));
+ uint16_t vendor = strtoul(vstr.c_str(), NULL, radix);
+ std::string pstr(getStringAttr(products, ix));
+ uint16_t product = strtoul(pstr.c_str(), NULL, radix);
+ std::string name(getStringAttr(names, ix));
+ DeviceDescription *dev = new DeviceDescription(vendor, product, name);
+ addProduct(dev);
+ }
+ }
+ else
+ if (CFGetTypeID(vend) == CFStringGetTypeID())
+ {
+ secdebug("pcscd", "Driver for single product: %s", path().c_str());
+ std::string vstr(cfString(reinterpret_cast<CFStringRef>(vend)));
+ uint16_t vendor = strtoul(vstr.c_str(), NULL, radix);
+ std::string pstr(getStringAttr(dict,kProductName));
+ uint16_t product = strtoul(pstr.c_str(), NULL, radix);
+ std::string name(getStringAttr(dict,kFriendlyName));
+ DeviceDescription *dev = new DeviceDescription(vendor, product, name);
+ addProduct(dev);
+ }
+ else
+ CFError::throwMe();
+ }
+ catch (...)
+ {
+ secdebug("pcscd", "Malformed Info.plist for: %s", path().c_str());
+ secdebug("pcscd", "error getting plugin directory bundles");
+ return;
+ }
+
+ dump();
+}
+
+std::string DriverBundle::getStringAttr(CFDictionaryRef dict, CFStringRef key)
+{
+ // Do some sanity checking on potential string values in the plist
+ CFTypeRef attr = CFDictionaryGetValue(dict, key);
+ if (!attr)
+ return std::string();
+ if (CFGetTypeID(attr) != CFStringGetTypeID())
+ CFError::throwMe();
+
+ return std::string(cfString(static_cast<CFStringRef>(attr)));
+}
+
+std::string DriverBundle::getStringAttr(CFArrayRef arr, CFIndex idx)
+{
+ // Do some sanity checking on potential string values in the plist
+ CFTypeRef attr = CFArrayGetValueAtIndex(arr, idx);
+ if (!attr)
+ return std::string();
+ if (CFGetTypeID(attr) != CFStringGetTypeID())
+ CFError::throwMe();
+
+ return std::string(cfString(static_cast<CFStringRef>(attr)));
+}
+
+DriverBundle::~DriverBundle() throw()
+{
+ // delete supported devices objects
+}
+
+uint32_t DriverBundle::matches(const PCSCD::Device &device, std::string &name) const
+{
+ // Searches for a driver bundle that matches device. If found,
+ // it sets the libpath for the device and returns true.
+
+#ifdef DEBUG_BUNDLE_MATCHES
+ secdebug("device", " DEVICE: vendor/product: 0x%04X/0x%04X, interfaceClass: 0x%04X, vendor/product: %s/%s",
+ device.vendorid(), device.productid(), device.interfaceClass(),
+ device.vendorName().c_str(), device.productName().c_str());
+#endif
+
+ // Look for a manufacturer-specific driver first
+ for (ConstDeviceDescriptionIterator it=mDeviceDescriptions.begin();it!=mDeviceDescriptions.end();++it)
+ {
+ const DeviceDescription *desc = static_cast<DeviceDescription *>(*it);
+#ifdef DEBUG_BUNDLE_MATCHES
+ secdebug("device", " DESC: vendor/product: 0x%04X/0x%04X, interfaceClass: 0x%04X, path: %s",
+ desc->vendorid(), desc->productid(), desc->interfaceClass(), path().c_str());
+#endif
+ if (desc->vendorid() && (desc->vendorid()==device.vendorid()) &&
+ desc->productid() && (desc->productid()==device.productid()))
+ {
+ name = desc->name();
+ return eMatchVendorSpecific;
+ }
+ }
+
+ if (device.interfaceClass())
+ for (ConstDeviceDescriptionIterator it=mDeviceDescriptions.begin();it!=mDeviceDescriptions.end();++it)
+ {
+ const DeviceDescription *desc = static_cast<DeviceDescription *>(*it);
+ if (desc->interfaceClass() && (desc->interfaceClass()==device.interfaceClass()))
+ {
+ name = desc->name();
+ return eMatchInterfaceClass;
+ }
+ }
+
+ return eMatchNone;
+}
+
+#pragma mark -------------------- Operators --------------------
+
+bool DriverBundle::operator < (const DriverBundle &other) const throw()
+{
+ return this->path() < other.path();
+}
+
+bool DeviceDescription::operator < (const DeviceDescription &other) const throw()
+{
+ if (this->mVendor >= other.mVendor)
+ return false;
+
+ return (this->mProduct < other.mProduct);
+}
+
+#pragma mark -------------------- Debugging Routines --------------------
+
+void DriverBundle::dump()
+{
+#ifndef NDEBUG
+ secdebug("pcscd", "Driver at path: %s", path().c_str());
+ for (DeviceDescriptionIterator it = mDeviceDescriptions.begin(); it != mDeviceDescriptions.end();++it)
+ (*it)->dump();
+#endif
+}
+
+void DeviceDescription::dump()
+{
+#ifndef NDEBUG
+ secdebug("pcscd", " Friendly name: %s", mFriendlyName.c_str());
+ if (interfaceClass())
+ secdebug("pcscd", " Class: 0x%02X SubClass: 0x%02X Protocol: 0x%02X",
+ mDeviceClass,mDeviceSubClass,mDeviceProtocol);
+ else
+ secdebug("pcscd", " VendorID: 0x%04X ProductID: 0x%04X", mVendor, mProduct);
+#endif
+}
+
+} // end namespace PCSCD
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundle.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * PCSCDriverBundle.h
+ * SmartCardServices
+ */
+
+#ifndef _H_XPCSCDRIVERBUNDLE
+#define _H_XPCSCDRIVERBUNDLE
+
+#include <string>
+#include <vector>
+#include <security_utilities/refcount.h>
+#include <security_utilities/osxcode.h>
+#include "PCSCDevice.h"
+
+#if defined(__cplusplus)
+
+namespace PCSCD {
+
+class DeviceDescription
+{
+public:
+
+ DeviceDescription() { }
+ DeviceDescription(uint16_t vendor, uint16_t product, std::string name) :
+ mVendor(vendor), mProduct(product),
+ mDeviceClass(0), mDeviceSubClass(0), mDeviceProtocol(0),
+ mFriendlyName(name) {}
+ DeviceDescription(uint8_t deviceClass, uint8_t deviceSubClass, uint8_t protocol, std::string name) :
+ mVendor(0), mProduct(0),
+ mDeviceClass(deviceClass), mDeviceSubClass(deviceSubClass), mDeviceProtocol(protocol),
+ mFriendlyName(name) {}
+
+ bool operator < (const DeviceDescription &other) const throw();
+
+ uint8_t interfaceClass() const { return mDeviceClass; }
+ uint16_t vendorid() const { return mVendor; }
+ uint16_t productid() const { return mProduct; }
+ std::string name() const { return mFriendlyName; }
+
+ void dump();
+
+protected:
+ // Match types from <IOKit/USB.h> for IOUSBDeviceDescriptor
+
+ uint16_t mVendor; // Unique vendor's manufacturer code assigned by the USB-IF
+ uint16_t mProduct; // Manufacturer's unique product code
+
+ uint8_t mDeviceClass;
+ uint8_t mDeviceSubClass;
+ uint8_t mDeviceProtocol;
+
+ std::string mFriendlyName; // Manufacturer's name for device
+};
+
+/*
+ * An aggregation of useful information on a driver bundle in the
+ * drop directory.
+ */
+
+class DriverBundle : public LoadableBundle
+{
+private:
+ DriverBundle(const char *pathname) : LoadableBundle(pathname) { }
+
+public:
+ DriverBundle(CFBundleRef bundle);
+
+ virtual ~DriverBundle() throw();
+
+ bool operator < (const DriverBundle &other) const throw();
+
+ void addProduct(DeviceDescription *dev) { mDeviceDescriptions.push_back(dev); }
+
+ uint32_t matches(const Device &device, std::string &name) const;
+
+ enum
+ {
+ eMatchNone = 0,
+ eMatchInterfaceClass, // must be less than eMatchVendorSpecific
+ eMatchVendorSpecific
+ };
+
+protected:
+ void initialize(CFDictionaryRef dict);
+
+private:
+
+ typedef std::vector<DeviceDescription *> DeviceDescriptions;
+ typedef DeviceDescriptions::iterator DeviceDescriptionIterator;
+ typedef DeviceDescriptions::const_iterator ConstDeviceDescriptionIterator;
+ DeviceDescriptions mDeviceDescriptions;
+
+ std::string getStringAttr(CFDictionaryRef dict, CFStringRef key);
+ std::string getStringAttr(CFArrayRef arr, CFIndex idx);
+ void dump();
+};
+
+} // end namespace PCSCD
+
+#endif /* __cplusplus__ */
+
+#endif /* _H_XPCSCDRIVERBUNDLE */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/*
+ * PCSCDriverBundles.cpp
+ * SmartCardServices
+ */
+
+/*
+ Creates a vector of driver bundle info structures from the hot-plug driver
+ directory.
+
+ Returns NULL on error and a pointer to an allocated HPDriver vector on
+ success. The caller must free the HPDriver with a call to HPDriversRelease().
+
+ See http://developer.apple.com/documentation/CoreFoundation/Reference/CFArrayRef/index.html#//apple_ref/doc/uid/20001192
+ for information about CFArrayApplyFunction
+*/
+
+#include "PCSCDriverBundles.h"
+#include <security_utilities/debugging.h>
+#include <security_utilities/cfutilities.h>
+#include <security_utilities/errors.h>
+#include <map>
+
+namespace PCSCD {
+
+static const char *kPCSCLITE_HP_DROPDIR = "/usr/libexec/SmartCardServices/drivers/";
+static const char *kENV_PCSC_DEBUG_DRIVER = "PCSC_DEBUG_DRIVER_DIR"; // environment var
+
+DriverBundles::DriverBundles()
+{
+ // If debugging, look in build directory
+#if !defined(NDEBUG)
+ const char *envar = kENV_PCSC_DEBUG_DRIVER;
+ if (envar)
+ if (const char *envPath = getenv(envar))
+ {
+ // treat envPath as a classic colon-separated list of directories
+ secdebug("pathlist", "%p configuring from env(\"%s\")", this, envar);
+ while (const char *p = strchr(envPath, ':'))
+ {
+ addDirectory(string(envPath, p - envPath));
+ envPath = p + 1;
+ }
+ addDirectory(envPath);
+ }
+#endif
+ addDirectory(kPCSCLITE_HP_DROPDIR);
+}
+
+bool DriverBundles::find(PCSCD::Device &device) const
+{
+ // Searches for a driver bundle that matches device. If found,
+ // it sets the libpath for the device and returns true.
+
+ ProductMatchMap matchingProducts;
+
+ for (DriverBundles::const_iterator it=this->begin();it!=this->end();++it)
+ {
+ std::string name;
+ const DriverBundle *bndl = static_cast<DriverBundle *>((*it).get());
+ if (int32_t score = bndl->matches(device, name))
+ {
+ ProductMatchInfo *mi = new ProductMatchInfo(bndl->path(),name);
+ matchingProducts.push_back(make_pair(score, mi));
+ }
+ }
+
+ if (matchingProducts.empty())
+ return false;
+
+ sort(matchingProducts.begin(), matchingProducts.end());
+ const ProductMatchInfo *mi = (*matchingProducts.rbegin()).second;
+ device.setName(mi->name());
+ device.setPath(mi->path());
+ // clean up
+ for (ProductMatchMap::iterator it = matchingProducts.begin();it!=matchingProducts.end();++it)
+ delete (*it).second;
+ return true;
+}
+
+} // end namespace PCSCD
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/PCSCDriverBundles.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * PCSCDriverBundles.h
+ * SmartCardServices
+ */
+
+#ifndef _H_XPCSCDRIVERBUNDLES
+#define _H_XPCSCDRIVERBUNDLES
+
+#include "PCSCDriverBundle.h"
+#include "PCSCDevice.h"
+#include <security_utilities/threading.h>
+#include <security_utilities/coderepository.h>
+#include <security_utilities/osxcode.h>
+#include <set>
+
+#if defined(__cplusplus)
+
+namespace PCSCD {
+
+class DriverBundles : public CodeRepository<DriverBundle>
+{
+ friend class DriverBundle;
+
+public:
+ DriverBundles();
+ ~DriverBundles() {}
+
+ bool find(Device &device) const;
+
+ // These are the things we need to know about which part of
+ // bundle we are matched up with
+
+ class ProductMatchInfo
+ {
+ public:
+ ProductMatchInfo(std::string path, std::string name) : mPath(path), mName(name) {}
+
+ std::string path() const { return mPath; }
+ std::string name() const { return mName; }
+
+ private:
+ std::string mPath;
+ std::string mName;
+ };
+
+ typedef std::vector< pair<int32_t, ProductMatchInfo * > > ProductMatchMap;
+};
+
+} // end namespace PCSCD
+
+#endif /* __cplusplus__ */
+
+#endif /* _H_XPCSCDRIVERBUNDLE */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : atrhandler.c
+ Author : David Corcoran
+ Date : 7/27/99
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This keeps track of smartcard protocols,
+ timing issues, and atr handling.
+
+********************************************************************/
+
+#include <syslog.h>
+#include <string.h>
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "atrhandler.h"
+
+/*
+ * Uncomment the following for ATR debugging
+ */
+/*
+ * #define ATR_DEBUG 1
+ */
+
+short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
+ const unsigned char *pucAtr, DWORD dwLength)
+{
+
+ USHORT p;
+ UCHAR K, TCK; /* MSN of T0/Check Sum */
+ UCHAR Y1i, T; /* MSN/LSN of TDi */
+ short TAi, TBi, TCi, TDi; /* Interface characters */
+
+ /*
+ * Zero out everything
+ */
+ p = K = TCK = Y1i = T = TAi = TBi = TCi = TDi = 0;
+
+ if (dwLength < 2)
+ {
+ return 0; /* Atr must have TS and T0 */
+ }
+
+ /*
+ * Zero out the bitmasks
+ */
+
+ psExtension->CardCapabilities.AvailableProtocols = 0x00;
+ psExtension->CardCapabilities.CurrentProtocol = 0x00;
+
+ /*
+ * Decode the TS byte
+ */
+
+ if (pucAtr[0] == 0x3F)
+ { /* Inverse convention used */
+ psExtension->CardCapabilities.Convention =
+ SCARD_CONVENTION_INVERSE;
+ } else if (pucAtr[0] == 0x3B)
+ { /* Direct convention used */
+ psExtension->CardCapabilities.Convention = SCARD_CONVENTION_DIRECT;
+ } else
+ {
+ memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
+ return 0;
+ }
+
+ /*
+ * Here comes the platform dependant stuff
+ */
+
+ /*
+ * Decode the T0 byte
+ */
+ Y1i = pucAtr[1] >> 4; /* Get the MSN in Y1 */
+ K = pucAtr[1] & 0x0F; /* Get the LSN in K */
+
+ p = 2;
+
+#ifdef ATR_DEBUG
+ debug_msg("Conv %02X, Y1 %02X, K %02X",
+ psExtension->CardCapabilities.Convention, Y1i, K);
+#endif
+
+ /*
+ * Examine Y1
+ */
+
+ do
+ {
+
+ TAi = (Y1i & 0x01) ? pucAtr[p++] : -1;
+ TBi = (Y1i & 0x02) ? pucAtr[p++] : -1;
+ TCi = (Y1i & 0x04) ? pucAtr[p++] : -1;
+ TDi = (Y1i & 0x08) ? pucAtr[p++] : -1;
+
+#ifdef ATR_DEBUG
+ debug_msg("T's %02X %02X %02X %02X", TAi, TBi, TCi, TDi);
+ debug_msg("P %02X", p);
+#endif
+
+ /*
+ * Examine TDi to determine protocol and more
+ */
+ if (TDi >= 0)
+ {
+ Y1i = TDi >> 4; /* Get the MSN in Y1 */
+ T = TDi & 0x0F; /* Get the LSN in K */
+
+ /*
+ * Set the current protocol TD1
+ */
+ if (psExtension->CardCapabilities.CurrentProtocol == 0x00)
+ {
+ switch (T)
+ {
+ case 0:
+ psExtension->CardCapabilities.CurrentProtocol =
+ SCARD_PROTOCOL_T0;
+ break;
+ case 1:
+ psExtension->CardCapabilities.CurrentProtocol =
+ SCARD_PROTOCOL_T1;
+ break;
+ default:
+ return 0;
+ }
+ }
+
+ if (T == 0)
+ {
+#ifdef ATR_DEBUG
+ debug_msg("T=0 Protocol Found");
+#endif
+ psExtension->CardCapabilities.AvailableProtocols |=
+ SCARD_PROTOCOL_T0;
+ psExtension->CardCapabilities.T0.BGT = 0;
+ psExtension->CardCapabilities.T0.BWT = 0;
+ psExtension->CardCapabilities.T0.CWT = 0;
+ psExtension->CardCapabilities.T0.CGT = 0;
+ psExtension->CardCapabilities.T0.WT = 0;
+ } else if (T == 1)
+ {
+#ifdef ATR_DEBUG
+ debug_msg("T=1 Protocol Found");
+#endif
+ psExtension->CardCapabilities.AvailableProtocols |=
+ SCARD_PROTOCOL_T1;
+ psExtension->CardCapabilities.T1.BGT = 0;
+ psExtension->CardCapabilities.T1.BWT = 0;
+ psExtension->CardCapabilities.T1.CWT = 0;
+ psExtension->CardCapabilities.T1.CGT = 0;
+ psExtension->CardCapabilities.T1.WT = 0;
+ } else
+ {
+ psExtension->CardCapabilities.AvailableProtocols |= T;
+ /*
+ * Do nothing for now since other protocols are not
+ * supported at this time
+ */
+ }
+
+ } else
+ {
+ Y1i = 0;
+ }
+
+ if (p > MAX_ATR_SIZE)
+ {
+ memset(psExtension, 0x00, sizeof(SMARTCARD_EXTENSION));
+ return 0;
+ }
+
+ }
+ while (Y1i != 0);
+
+ /*
+ * If TDx is not set then the current must be T0
+ */
+ if (psExtension->CardCapabilities.CurrentProtocol == 0x00)
+ {
+ psExtension->CardCapabilities.CurrentProtocol = SCARD_PROTOCOL_T0;
+ psExtension->CardCapabilities.AvailableProtocols |=
+ SCARD_PROTOCOL_T0;
+ }
+
+ /*
+ * Take care of the historical characters
+ */
+
+ psExtension->ATR.HistoryLength = K;
+ memcpy(psExtension->ATR.HistoryValue, &pucAtr[p], K);
+
+ p = p + K;
+
+ /*
+ * Check to see if TCK character is included It will be included if
+ * more than T=0 is supported
+ */
+
+ if (psExtension->CardCapabilities.AvailableProtocols &
+ SCARD_PROTOCOL_T1)
+ {
+ TCK = pucAtr[p++];
+ }
+
+ memcpy(psExtension->ATR.Value, pucAtr, p);
+ psExtension->ATR.Length = p; /* modified from p-1 */
+
+ return 1;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/atrhandler.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : atrhandler.h
+ Author : David Corcoran
+ Date : 7/27/99
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This keeps track of smartcard protocols,
+ timing issues, and atr handling.
+
+********************************************************************/
+
+#ifndef __atrhandler_h__
+#define __atrhandler_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define SCARD_CONVENTION_DIRECT 0x0001
+#define SCARD_CONVENTION_INVERSE 0x0002
+
+ typedef struct _SMARTCARD_EXTENSION
+ {
+
+ struct _ATR
+ {
+ DWORD Length;
+ UCHAR Value[MAX_ATR_SIZE];
+ DWORD HistoryLength;
+ UCHAR HistoryValue[MAX_ATR_SIZE];
+ }
+ ATR;
+
+ DWORD ReadTimeout;
+
+ struct _CardCapabilities
+ {
+ UCHAR AvailableProtocols;
+ UCHAR CurrentProtocol;
+ UCHAR Convention;
+ USHORT ETU;
+
+ struct _PtsData
+ {
+ UCHAR F1;
+ UCHAR D1;
+ UCHAR I1;
+ UCHAR P1;
+ UCHAR N1;
+ }
+ PtsData;
+
+ struct _T1
+ {
+ USHORT BGT;
+ USHORT BWT;
+ USHORT CWT;
+ USHORT CGT;
+ USHORT WT;
+ }
+ T1;
+
+ struct _T0
+ {
+ USHORT BGT;
+ USHORT BWT;
+ USHORT CWT;
+ USHORT CGT;
+ USHORT WT;
+ }
+ T0;
+
+ }
+ CardCapabilities;
+
+ /*
+ * PREADER_CONNECTION psReaderConnection;
+ */
+
+ }
+ SMARTCARD_EXTENSION, *PSMARTCARD_EXTENSION;
+
+ /*
+ * Decodes the ATR and fills the structure
+ */
+
+ short ATRDecodeAtr(PSMARTCARD_EXTENSION psExtension,
+ const unsigned char *pucAtr, DWORD dwLength);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __smclib_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/config.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/config.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/config.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * config.h
+ * SmartCardServices
+ */
+
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* display ATR parsing debug messages. */
+/* #undef ATR_DEBUG */
+
+/* Define to 1 if you have the `daemon' function. */
+#define HAVE_DAEMON 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <dl.h> header file. */
+/* #undef HAVE_DL_H */
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `flock' function. */
+#define HAVE_FLOCK 1
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#define HAVE_GETOPT_H 1
+
+/* Define to 1 if you have the `getopt_long' function. */
+#define HAVE_GETOPT_LONG 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Libusb is available */
+/* #undef HAVE_LIBUSB */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `nanosleep' function. */
+#define HAVE_NANOSLEEP 1
+
+/* Define if you have POSIX threads libraries and header files. */
+#define HAVE_PTHREAD 1
+
+/* Define to 1 if `stat' has the bug that it succeeds when given the
+ zero-length file name argument. */
+/* #undef HAVE_STAT_EMPTY_STRING_BUG */
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+#define HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#define HAVE_SYSLOG_H 1
+
+/* Define to 1 if you have the <sys/filio.h> header file. */
+#define HAVE_SYS_FILIO_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the <usb.h> header file. */
+/* #undef HAVE_USB_H */
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
+ slash. */
+/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
+
+/* Name of package */
+#define PACKAGE "PCSC Framework"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "pcsc-lite"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "pcsc-lite 1.4.0"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "pcsc-lite"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.4.0"
+
+/* directory containing USB drivers */
+//#define PCSCLITE_HP_DROPDIR "/usr/local/pcsc/drivers"
+
+/* PC/SC target architecture */
+#define PCSC_ARCH "MacOS"
+
+/* Define to the necessary symbol if this constant uses a non-standard name on
+ your system. */
+/* #undef PTHREAD_CREATE_JOINABLE */
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* directory containing IPC files (default /var/run) */
+/* #undef USE_IPCDIR */
+
+/* file containing pcscd pid */
+#define USE_RUN_PID "/var/run/pcscd"
+
+/* Version number of package */
+#define VERSION "1.4.0"
+
+/* Define to 1 if your processor stores words with the most significant byte
+ first (like Motorola and SPARC, unlike Intel and VAX). */
+/* #undef WORDS_BIGENDIAN */
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+ `char[]'. */
+#define YYTEXT_POINTER 1
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+/* #undef inline */
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
+
+/* enable full musclecard debug messaging. */
+ #define MSC_DEBUG 1
+
Property changes on: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/config.h
___________________________________________________________________
Added: svn:executable
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1781 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/*
+ * A lexical scanner generated by flex
+ */
+
+/*
+ * Scanner skeleton version: $Header:
+ * /home/cvsroot/muscle/PCSC/src/configfile.c,v 1.3 2002/03/31 07:05:07
+ * corcoran Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+/*
+ * cfront 1.2 defines "c_plusplus" instead of "__cplusplus"
+ */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Use prototypes in function declarations.
+ */
+#define YY_USE_PROTOS
+
+/*
+ * The "const" storage-class-modifier is valid.
+ */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+#pragma warn -rch
+#pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/*
+ * Returned upon end-of-file.
+ */
+#define YY_NULL 0
+
+/*
+ * Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative, we
+ * want to instead treat it as an 8-bit unsigned char, hence the double
+ * cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/*
+ * Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/*
+ * Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/*
+ * Action number for EOF rule of a given start state.
+ */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/*
+ * Special action meaning "start processing a new file".
+ */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/*
+ * Size of default input buffer.
+ */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/*
+ * The funky do-while in the following #define is used to turn the
+ * definition int a single C statement (which needs a semi-colon
+ * terminator). This avoids problems with code like: if (
+ * condition_holds ) yyless( 5 ); else do_something_else(); Prior to
+ * using the do-while the compiler would get upset at the "else" because
+ * it interpreted the "if" statement as being all done when it reached the
+ * ';' after the yyless() call.
+ */
+
+/*
+ * Return all but the first 'n' matched characters back to the input
+ * stream.
+ */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/*
+ * The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+struct yy_buffer_state
+{
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /*
+ * Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /*
+ * Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /*
+ * Whether we "own" the buffer - i.e., we know we created it, and can
+ * realloc() it to grow it, and should free() it to delete it.
+ */
+ int yy_is_our_buffer;
+
+ /*
+ * Whether this is an "interactive" input source; if so, and if we're
+ * using stdio for input, then we want to use getc() instead of
+ * fread(), to make sure we stop fetching input after each newline.
+ */
+ int yy_is_interactive;
+
+ /*
+ * Whether we're considered to be at the beginning of a line. If so,
+ * '^' rules will be active on the next match, otherwise not.
+ */
+ int yy_at_bol;
+
+ /*
+ * Whether to try to fill the input buffer when we reach the end of
+ * it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /*
+ * When an EOF's been seen but there's still some text to process then
+ * we mark the buffer as YY_EOF_PENDING, to indicate that we shouldn't
+ * try reading from the input source any more. We might still have a
+ * bunch of tokens to match, though, because of possible backing-up.
+ * When we actually see the EOF, we change the status to "new" (via
+ * yyrestart()), so that the user can continue scanning by just
+ * pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/*
+ * We provide macros for accessing buffer states in case in the future we
+ * want to put the buffer states in a more general "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+/*
+ * yy_hold_char holds the character lost when yytext is formed.
+ */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into
+ * yy_ch_buf */
+
+int yyleng;
+
+/*
+ * Points to current character in buffer.
+ */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/*
+ * Flag which is used to allow yywrap()'s to do buffer switches instead of
+ * setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO((FILE * input_file));
+
+void yy_switch_to_buffer YY_PROTO((YY_BUFFER_STATE new_buffer));
+void yy_load_buffer_state YY_PROTO((void));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO((FILE * file, int size));
+void yy_delete_buffer YY_PROTO((YY_BUFFER_STATE b));
+void yy_init_buffer YY_PROTO((YY_BUFFER_STATE b, FILE * file));
+void yy_flush_buffer YY_PROTO((YY_BUFFER_STATE b));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO((char *base, yy_size_t size));
+YY_BUFFER_STATE yy_scan_string YY_PROTO((yyconst char *yy_str));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO((yyconst char *bytes, int len));
+
+static void *yy_flex_alloc YY_PROTO((yy_size_t));
+static void *yy_flex_realloc YY_PROTO((void *, yy_size_t));
+static void yy_flex_free YY_PROTO((void *));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO((void));
+static yy_state_type yy_try_NUL_trans YY_PROTO((yy_state_type
+ current_state));
+static int yy_get_next_buffer YY_PROTO((void));
+static void yy_fatal_error YY_PROTO((yyconst char msg[]));
+
+/*
+ * Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 7
+#define YY_END_OF_BUFFER 8
+static yyconst short int yy_accept[17] = { 0,
+ 0, 0, 8, 6, 4, 2, 6, 1, 6, 5,
+ 0, 3, 1, 0, 5, 0
+};
+
+static yyconst int yy_ec[256] = { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 4, 5, 1, 1, 1, 6, 1,
+ 1, 1, 1, 1, 7, 7, 7, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 1, 1, 1,
+ 1, 1, 1, 7, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 1, 7, 1, 1, 7, 1, 10, 10, 10, 10,
+
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+static yyconst int yy_meta[11] = { 0,
+ 1, 1, 2, 1, 1, 1, 1, 1, 1, 1
+};
+
+static yyconst short int yy_base[20] = { 0,
+ 0, 0, 15, 31, 31, 31, 8, 0, 10, 10,
+ 18, 31, 0, 20, 0, 31, 26, 13, 28
+};
+
+static yyconst short int yy_def[20] = { 0,
+ 16, 1, 16, 16, 16, 16, 17, 18, 19, 16,
+ 17, 16, 18, 19, 10, 0, 16, 16, 16
+};
+
+static yyconst short int yy_nxt[42] = { 0,
+ 4, 5, 6, 7, 8, 9, 10, 10, 10, 10,
+ 12, 12, 12, 13, 16, 12, 15, 15, 15, 15,
+ 12, 12, 12, 16, 16, 12, 11, 11, 14, 14,
+ 3, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16
+};
+
+static yyconst short int yy_chk[42] = { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 7, 7, 9, 18, 3, 9, 10, 10, 10, 10,
+ 11, 11, 14, 0, 0, 14, 17, 17, 19, 19,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16
+};
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/*
+ * The intent behind this definition is that it'll catch any uses of
+ * REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "configfile.l"
+#define INITIAL 0
+/*****************************************************************
+
+ File : configfile.ll
+ Author : David Corcoran
+ Date : February 12, 1999 modified 7/28/99
+ Purpose: Reads lexical config files and updates database.
+ See http://www.linuxnet.com for more information.
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+
+******************************************************************/
+#line 14 "configfile.l"
+int evaluatetoken(char *pcToken);
+
+static int iLinenumber = 1;
+static char *pcPrevious = 0;
+static char *pcCurrent = 0;
+static char *pcFriendlyname = 0;
+static char *pcDevicename = 0;
+static char *pcLibpath = 0;
+static char *pcChannelid = 0;
+static int badError = 0;
+
+void tok_error(char *pcToken_error);
+
+#line 399 "lex.yy.c"
+
+/*
+ * Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO((void));
+#else
+extern int yywrap YY_PROTO((void));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO((int c, char *buf_ptr));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO((char *, yyconst char *, int));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO((yyconst char *));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO((void));
+#else
+static int input YY_PROTO((void));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO((int new_state));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO((void));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO((void));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/*
+ * Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/*
+ * Amount of stuff to slurp up with each read.
+ */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/*
+ * Copy whatever the last rule matched to the standard output.
+ */
+
+#ifndef ECHO
+/*
+ * This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/*
+ * Gets input and stuffs it into "buf". number of characters read, or
+ * YY_NULL, is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/*
+ * No semi-colon after return; correct usage is to write "yyterminate();"
+ * - we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/*
+ * Number of entries by which start-condition stack grows.
+ */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/*
+ * Report a fatal error.
+ */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/*
+ * Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/*
+ * Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/*
+ * Code executed at the end of each rule.
+ */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 29 "configfile.l"
+
+#line 553 "lex.yy.c"
+
+ if (yy_init)
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yy_start)
+ yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_load_buffer_state();
+ }
+
+ while (1) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /*
+ * Support of yytext.
+ */
+ *yy_cp = yy_hold_char;
+
+ /*
+ * yy_bp points to the position in yy_ch_buf of the start of the
+ * current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] !=
+ yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 17)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while (yy_base[yy_current_state] != 31);
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if (yy_act == 0)
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+ do_action: /* This label is used only to access EOF actions. */
+
+ switch (yy_act)
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /*
+ * undo the effects of YY_DO_BEFORE_ACTION
+ */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+#line 31 "configfile.l"
+ {
+ }
+ YY_BREAK case 2:
+ YY_RULE_SETUP
+#line 32 "configfile.l"
+ {
+ iLinenumber++;
+ }
+ YY_BREAK case 3:
+ YY_RULE_SETUP
+#line 33 "configfile.l"
+ {
+ evaluatetoken(yytext);
+ }
+ YY_BREAK case 4:
+ YY_RULE_SETUP
+#line 34 "configfile.l"
+ {
+ }
+ YY_BREAK case 5:
+ YY_RULE_SETUP
+#line 35 "configfile.l"
+ {
+ evaluatetoken(yytext);
+ }
+ YY_BREAK case 6:
+ YY_RULE_SETUP
+#line 36 "configfile.l"
+ {
+ tok_error(yytext);
+ }
+ YY_BREAK case 7:
+ YY_RULE_SETUP
+#line 37 "configfile.l"
+ ECHO;
+ YY_BREAK
+#line 671 "lex.yy.c"
+ case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /*
+ * Amount of text matched not including the EOB char.
+ */
+ int yy_amount_of_matched_text =
+ (int) (yy_cp - yytext_ptr) - 1;
+
+ /*
+ * Undo the effects of YY_DO_BEFORE_ACTION.
+ */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+ if (yy_current_buffer->yy_buffer_status ==
+ YY_BUFFER_NEW)
+ {
+ /*
+ * We're scanning a new file or input source. It's
+ * possible that this happened because the user just
+ * pointed yyin at a new source and called yylex().
+ * If so, then we have to assure consistency between
+ * yy_current_buffer and our globals. Here is the
+ * right place to do so, because this is the first
+ * action (other than possibly a back-up) that will
+ * match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /*
+ * Note that here we test for yy_c_buf_p "<=" to the
+ * position of the first EOB in the buffer, since
+ * yy_c_buf_p will already have been incremented past the
+ * NUL character (since all states make transitions on EOB
+ * to the end-of-buffer state). Contrast this with the
+ * test in input().
+ */
+ if (yy_c_buf_p <=
+ &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /*
+ * Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it for us
+ * because it doesn't know how to deal with the
+ * possibility of jamming (and we don't want to build
+ * jamming into it because then it will run more
+ * slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state);
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state)
+ {
+ /*
+ * Consume the NUL.
+ */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer())
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap())
+ {
+ /*
+ * Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up yy_c_buf_p so
+ * that if some total hoser (like flex
+ * itself) wants to call the scanner after
+ * we return the YY_NULL, it'll still work
+ * - another YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR
+ ("fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/*
+ * yy_get_next_buffer - try to read in a new buffer Returns a code
+ * representing an action: EOB_ACT_LAST_MATCH - EOB_ACT_CONTINUE_SCAN -
+ * continue scanning from current position EOB_ACT_END_OF_FILE - end of
+ * file
+ */
+
+static int yy_get_next_buffer()
+{
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if (yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1])
+ YY_FATAL_ERROR
+ ("fatal flex scanner internal error--end of buffer missed");
+
+ if (yy_current_buffer->yy_fill_buffer == 0)
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1)
+ {
+ /*
+ * We matched a single character, the EOB, so treat this as a
+ * final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /*
+ * We matched some text prior to the EOB, first process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /*
+ * Try to read more data.
+ */
+
+ /*
+ * First move last chars to start of buffer.
+ */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /*
+ * don't do the read, it's not guaranteed to return an EOF, just
+ * force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0)
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR
+ ("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+#else
+
+ /*
+ * just a shorter name for the current buffer
+ */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset = (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer)
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /*
+ * Include room in for 2 EOB chars.
+ */
+ yy_flex_realloc((void *) b->yy_ch_buf,
+ b->yy_buf_size + 2);
+ } else
+ /*
+ * Can't grow it, we don't own it.
+ */
+ b->yy_ch_buf = 0;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR
+ ("fatal error - scanner input buffer overflow");
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /*
+ * Read in more data.
+ */
+ YY_INPUT((&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read);
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if (yy_n_chars == 0)
+ {
+ if (number_to_move == YY_MORE_ADJ)
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/*
+ * yy_get_previous_state - get the state just before the EOB char was
+ * reached
+ */
+
+static yy_state_type yy_get_previous_state()
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for (yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp)
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] !=
+ yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 17)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/*
+ * yy_try_NUL_trans - try to make a transition on the NUL character
+ * synopsis next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state)
+#else
+static yy_state_type yy_try_NUL_trans(yy_current_state)
+ yy_state_type yy_current_state;
+#endif
+{
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 17)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 16);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput(int c, register char *yy_bp)
+#else
+static void yyunput(c, yy_bp)
+ int c;
+ register char *yy_bp;
+#endif
+{
+ register char *yy_cp = yy_c_buf_p;
+
+ /*
+ * undo effects of setting up yytext
+ */
+ *yy_cp = yy_hold_char;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ { /* need to shift things up to make room */
+ /*
+ * +2 for EOB chars.
+ */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest =
+ &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size +
+ 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while (source > yy_current_buffer->yy_ch_buf)
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ YY_FATAL_ERROR("flex scanner push-back overflow");
+ }
+
+ *--yy_cp = (char) c;
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+{
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if (*yy_c_buf_p == YY_END_OF_BUFFER_CHAR)
+ {
+ /*
+ * yy_c_buf_p now points to the character we want to return. If
+ * this occurs *before* the EOB characters, then it's a valid NUL;
+ * if not, then we've hit the end of the buffer.
+ */
+ if (yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ /*
+ * This was really a NUL.
+ */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch (yy_get_next_buffer())
+ {
+ case EOB_ACT_LAST_MATCH:
+ /*
+ * This happens because yy_g_n_b() sees that we've
+ * accumulated a token and flags that we need to try
+ * matching the token before proceeding. But for input(),
+ * there's no matching to consider. So convert the
+ * EOB_ACT_LAST_MATCH to EOB_ACT_END_OF_FILE.
+ */
+
+ /*
+ * Reset buffer status.
+ */
+ yyrestart(yyin);
+
+ /*
+ * fall through
+ */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if (yywrap())
+ return EOF;
+
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ return c;
+}
+
+#ifdef YY_USE_PROTOS
+void yyrestart(FILE * input_file)
+#else
+void yyrestart(input_file)
+ FILE *input_file;
+#endif
+{
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_init_buffer(yy_current_buffer, input_file);
+ yy_load_buffer_state();
+}
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer)
+#else
+void yy_switch_to_buffer(new_buffer)
+ YY_BUFFER_STATE new_buffer;
+#endif
+{
+ if (yy_current_buffer == new_buffer)
+ return;
+
+ if (yy_current_buffer)
+ {
+ /*
+ * Flush out information for old buffer.
+ */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /*
+ * We don't actually know whether we did this switch during EOF
+ * (yywrap()) processing, but the only time this flag is looked at is
+ * after yywrap() is called, so it's safe to go ahead and always set
+ * it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+}
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state(void)
+#else
+void yy_load_buffer_state()
+#endif
+{
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+}
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer(FILE * file, int size)
+#else
+YY_BUFFER_STATE yy_create_buffer(file, size)
+ FILE *file;
+ int size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = size;
+
+ /*
+ * yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc(b->yy_buf_size + 2);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file);
+
+ return b;
+}
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer(YY_BUFFER_STATE b)
+#else
+void yy_delete_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+{
+ if (!b)
+ return;
+
+ if (b == yy_current_buffer)
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if (b->yy_is_our_buffer)
+ yy_flex_free((void *) b->yy_ch_buf);
+
+ yy_flex_free((void *) b);
+}
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO((int));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer(YY_BUFFER_STATE b, FILE * file)
+#else
+void yy_init_buffer(b, file)
+ YY_BUFFER_STATE b;
+ FILE *file;
+#endif
+
+{
+ yy_flush_buffer(b);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0;
+#endif
+#endif
+}
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer(YY_BUFFER_STATE b)
+#else
+void yy_flush_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+
+{
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /*
+ * We always need two end-of-buffer characters. The first causes a
+ * transition to the end-of-buffer state. The second causes a jam in
+ * that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == yy_current_buffer)
+ yy_load_buffer_state();
+}
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size)
+#else
+YY_BUFFER_STATE yy_scan_buffer(base, size)
+ char *base;
+ yy_size_t size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 ||
+ base[size - 2] != YY_END_OF_BUFFER_CHAR ||
+ base[size - 1] != YY_END_OF_BUFFER_CHAR)
+ /*
+ * They forgot to leave room for the EOB's.
+ */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b);
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string(yyconst char *yy_str)
+#else
+YY_BUFFER_STATE yy_scan_string(yy_str)
+ yyconst char *yy_str;
+#endif
+{
+ int len;
+ for (len = 0; yy_str[len]; ++len)
+ ;
+
+ return yy_scan_bytes(yy_str, len);
+}
+#endif
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes(yyconst char *bytes, int len)
+#else
+YY_BUFFER_STATE yy_scan_bytes(bytes, len)
+ yyconst char *bytes;
+ int len;
+#endif
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /*
+ * Get memory for full buffer, including space for trailing EOB's.
+ */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc(n);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < len; ++i)
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /*
+ * It's okay to grow etc. this buffer, and we should throw it away
+ * when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state(int new_state)
+#else
+static void yy_push_state(new_state)
+ int new_state;
+#endif
+{
+ if (yy_start_stack_ptr >= yy_start_stack_depth)
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof(int);
+
+ if (!yy_start_stack)
+ yy_start_stack = (int *) yy_flex_alloc(new_size);
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size);
+
+ if (!yy_start_stack)
+ YY_FATAL_ERROR
+ ("out of memory expanding start-condition stack");
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+#endif
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+{
+ if (--yy_start_stack_ptr < 0)
+ YY_FATAL_ERROR("start-condition stack underflow");
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+}
+#endif
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+{
+ return yy_start_stack[yy_start_stack_ptr - 1];
+}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error(yyconst char msg[])
+#else
+static void yy_fatal_error(msg)
+ char msg[];
+#endif
+{
+ (void) fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/*
+ * Redefine yyless() so it works in section 3 code.
+ */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy(char *s1, yyconst char *s2, int n)
+#else
+static void yy_flex_strncpy(s1, s2, n)
+ char *s1;
+ yyconst char *s2;
+ int n;
+#endif
+{
+ register int i;
+ for (i = 0; i < n; ++i)
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen(yyconst char *s)
+#else
+static int yy_flex_strlen(s)
+ yyconst char *s;
+#endif
+{
+ register int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc(yy_size_t size)
+#else
+static void *yy_flex_alloc(size)
+ yy_size_t size;
+#endif
+{
+ return (void *) malloc(size);
+}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc(void *ptr, yy_size_t size)
+#else
+static void *yy_flex_realloc(ptr, size)
+ void *ptr;
+ yy_size_t size;
+#endif
+{
+ /*
+ * The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those that use
+ * void* generic pointers. It works with the latter because both ANSI
+ * C and C++ allow castless assignment from any pointer type to void*,
+ * and deal with argument conversions as though doing an assignment.
+ */
+ return (void *) realloc((char *) ptr, size);
+}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free(void *ptr)
+#else
+static void yy_flex_free(ptr)
+ void *ptr;
+#endif
+{
+ free(ptr);
+}
+
+#if YY_MAIN
+int main()
+{
+ yylex();
+ return 0;
+}
+#endif
+#line 37 "configfile.l"
+
+#include <stdio.h>
+#include <string.h>
+#include <wintypes.h>
+
+#include "pcsclite.h"
+#include "sys_generic.h"
+#include "readerfactory.h"
+#include "debuglog.h"
+
+int evaluatetoken(char *pcToken)
+{
+
+ DWORD dwChannelId = 0;
+ int p = 0;
+ int n = 0;
+
+ if (pcPrevious == 0)
+ { /* This is the key */
+ pcPrevious = strdup(pcToken);
+ } else
+ {
+ pcCurrent = pcToken;
+ if (strcmp(pcPrevious, "FRIENDLYNAME") == 0)
+ {
+ if (pcFriendlyname == 0)
+ {
+ pcFriendlyname = (char *) malloc(strlen(pcCurrent) - 1);
+ for (n = 0; n < strlen(pcCurrent); n++)
+ {
+ if (pcCurrent[n] != '"')
+ { /* Strip off the quotes */
+ pcFriendlyname[p++] = pcCurrent[n];
+ }
+ }
+ pcFriendlyname[p++] = 0;
+ } else
+ {
+ tok_error(pcPrevious);
+ return 1;
+ }
+ } else if (strcmp(pcPrevious, "DEVICENAME") == 0)
+ {
+ if (pcDevicename == 0)
+ {
+ pcDevicename = strdup(pcCurrent);
+ } else
+ {
+ tok_error(pcPrevious);
+ return 1;
+ }
+ } else if (strcmp(pcPrevious, "LIBPATH") == 0)
+ {
+ if (pcLibpath == 0)
+ {
+ pcLibpath = strdup(pcCurrent);
+ } else
+ {
+ tok_error(pcPrevious);
+ return 1;
+ }
+ } else if (strcmp(pcPrevious, "CHANNELID") == 0)
+ {
+ if (pcChannelid == 0)
+ {
+ pcChannelid = strdup(pcCurrent);
+ } else
+ {
+ tok_error(pcPrevious);
+ return 1;
+ }
+ } else
+ {
+ tok_error(pcPrevious);
+ return 1;
+ }
+
+ free(pcPrevious);
+ pcPrevious = 0;
+ }
+
+ if (pcFriendlyname != 0 && pcDevicename != 0 &&
+ pcLibpath != 0 && pcChannelid != 0)
+ {
+
+ dwChannelId = strtoul(pcChannelid, 0, 16);
+ RFAddReader(pcFriendlyname, dwChannelId, pcLibpath, pcDevicename);
+
+ free(pcFriendlyname);
+ free(pcDevicename);
+ free(pcLibpath);
+ free(pcChannelid);
+ pcFriendlyname = 0;
+ pcDevicename = 0;
+ pcLibpath = 0;
+ pcChannelid = 0;
+ }
+
+ return 0;
+}
+
+void tok_error(char *token_error)
+{
+ log_msg(PCSC_LOG_ERROR, "%s:%d tok_error: invalid value in reader.conf",
+ __FILE__, __LINE__);
+ badError = 1;
+}
+
+int DBUpdateReaders(char *readerconf)
+{
+
+ FILE *configFile;
+ configFile = 0;
+
+ configFile = fopen(readerconf, "r");
+
+ if (configFile == 0)
+ {
+ return 1;
+ }
+
+ yyin = configFile;
+
+ do
+ {
+ yylex();
+ }
+ while (!feof(configFile));
+
+ fclose(configFile);
+
+ if (badError == 1)
+ {
+ return -1;
+ } else
+ {
+ return 0;
+ }
+} /* End of configfile.c */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/*****************************************************************
+/
+/ File : configfile.h
+/ Author : David Corcoran
+/ Date : February 12, 1999 modified 7/28/99
+/ License: Copyright (C) 1999 David Corcoran
+/ <corcoran at linuxnet.com>
+/ Purpose: Header file for reading lexical config files.
+/ See http://www.linuxnet.com for more information.
+/
+******************************************************************/
+
+#ifndef __configfile_h__
+#define __configfile_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ int DBUpdateReaders(char *readerconf);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __configfile_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.l
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.l (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/configfile.l 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,142 @@
+/*****************************************************************
+
+ File : configfile.ll
+ Author : David Corcoran
+ Date : February 12, 1999 modified 7/28/99
+ Purpose: Reads lexical config files and updates database.
+ See http://www.linuxnet.com for more information.
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+
+******************************************************************/
+
+%{
+int evaluatetoken( char *pcToken );
+
+static int iLinenumber = 1;
+static char *pcPrevious = 0;
+static char *pcCurrent = 0;
+static char *pcFriendlyname = 0;
+static char *pcDevicename = 0;
+static char *pcLibpath = 0;
+static char *pcChannelid = 0;
+static int badError = 0;
+
+void tok_error ( char *pcToken_error );
+
+%}
+
+%%
+
+#.* {}
+"\n" { iLinenumber++; }
+(\"[^"\n]*["\n])|(\'[^'\n]*['\n]) { evaluatetoken( yytext); }
+[ \t] {}
+([A-Z]|[a-z]|[0-9]|[\\\/\-\.\_\@])+ { evaluatetoken( yytext ); }
+. { tok_error( yytext ); }
+%%
+
+#include <stdio.h>
+#include <string.h>
+#include <wintypes.h>
+
+#include "pcsclite.h"
+#include "sys_generic.h"
+#include "readerfactory.h"
+#include "debuglog.h"
+
+int evaluatetoken( char *pcToken ) {
+
+ DWORD dwChannelId = 0;
+ int p = 0;
+ int n = 0;
+
+ if ( pcPrevious == 0 ) { /* This is the key */
+ pcPrevious = strdup( pcToken );
+ } else {
+ pcCurrent = pcToken;
+ if ( strcmp( pcPrevious, "FRIENDLYNAME" ) == 0 ) {
+ if ( pcFriendlyname == 0 ) {
+ pcFriendlyname = (char *)malloc(strlen(pcCurrent)-1);
+ for ( n = 0; n < strlen(pcCurrent); n++ ) {
+ if ( pcCurrent[n] != '"' ) { /* Strip off the quotes */
+ pcFriendlyname[p++] = pcCurrent[n];
+ }
+ }
+ pcFriendlyname[p++] = 0;
+ } else {
+ tok_error( pcPrevious ); return 1;
+ }
+ } else if ( strcmp( pcPrevious, "DEVICENAME" ) == 0 ) {
+ if ( pcDevicename == 0 ) {
+ pcDevicename = strdup( pcCurrent );
+ } else {
+ tok_error( pcPrevious ); return 1;
+ }
+ } else if ( strcmp( pcPrevious, "LIBPATH" ) == 0 ) {
+ if ( pcLibpath == 0 ) {
+ pcLibpath = strdup( pcCurrent );
+ } else {
+ tok_error( pcPrevious ); return 1;
+ }
+ } else if ( strcmp( pcPrevious, "CHANNELID" ) == 0 ) {
+ if ( pcChannelid == 0 ) {
+ pcChannelid = strdup( pcCurrent );
+ } else {
+ tok_error( pcPrevious ); return 1;
+ }
+ } else {
+ tok_error( pcPrevious ); return 1;
+ }
+
+ free( pcPrevious ); pcPrevious = 0;
+ }
+
+ if ( pcFriendlyname != 0 && pcDevicename != 0 &&
+ pcLibpath != 0 && pcChannelid != 0 ) {
+
+ dwChannelId = strtoul( pcChannelid, 0, 16 );
+ RFAddReader( pcFriendlyname, dwChannelId, pcLibpath, pcDevicename );
+
+ free( pcFriendlyname ); free( pcDevicename );
+ free( pcLibpath); free( pcChannelid );
+ pcFriendlyname = 0; pcDevicename = 0;
+ pcLibpath = 0; pcChannelid = 0;
+ }
+
+ return 0;
+}
+
+void tok_error ( char *token_error ) {
+ debug_msg("%s:%d tok_error: invalid value in reader.conf",
+ __FILE__, __LINE__);
+ badError = 1;
+}
+
+int DBUpdateReaders ( char *readerconf ) {
+
+ FILE *configFile;
+ configFile = 0;
+
+ configFile = fopen( readerconf, "r");
+
+ if (configFile == 0) {
+ return 1;
+ }
+
+ yyin = configFile;
+
+ do {
+ yylex();
+ }
+ while (!feof(configFile));
+
+ fclose(configFile);
+
+ if (badError == 1) {
+ return -1;
+ } else {
+ return 0;
+ }
+} /* End of configfile.c */
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,160 @@
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2002
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 1999-2005
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: debuglog.c 1953 2006-03-21 13:46:28Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles debugging for libpcsclite.
+ */
+
+#include "config.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "debug.h"
+//#include "strlcpycat.h"
+
+#define DEBUG_BUF_SIZE 2048
+
+/* default level is a bit verbose to be backward compatible */
+static char LogLevel = PCSC_LOG_ERROR;
+
+static signed char LogDoColor = 0; /* no color by default */
+void log_init(void);
+
+void log_init(void)
+{
+ char *e;
+
+#ifdef LIBPCSCLITE
+ e = getenv("PCSCLITE_DEBUG");
+#else
+ e = getenv("MUSCLECARD_DEBUG");
+#endif
+ if (e)
+ LogLevel = atoi(e);
+
+ /* no color under Windows */
+#ifndef WIN32
+ /* log to stderr and stderr is a tty? */
+ if (isatty(fileno(stderr)))
+ {
+ const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
+ char *term;
+
+ term = getenv("TERM");
+ if (term)
+ {
+ unsigned int i;
+
+ /* for each known color terminal */
+ for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
+ {
+ /* we found a supported term? */
+ if (0 == strcmp(terms[i], term))
+ {
+ LogDoColor = 1;
+ break;
+ }
+ }
+ }
+ }
+#endif
+} /* log_init */
+
+void log_msg(const int priority, const char *fmt, ...)
+{
+ char DebugBuffer[DEBUG_BUF_SIZE];
+ va_list argptr;
+ static int is_initialized = 0;
+
+ if (!is_initialized)
+ {
+ log_init();
+ is_initialized = 1;
+ }
+
+ if (priority < LogLevel) /* log priority lower than threshold? */
+ return;
+
+ va_start(argptr, fmt);
+#ifndef WIN32
+ vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
+#else
+#if HAVE_VSNPRINTF
+ vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
+#else
+ vsprintf(DebugBuffer, fmt, argptr);
+#endif
+#endif
+ va_end(argptr);
+
+#ifndef WIN32
+ {
+ if (LogDoColor)
+ {
+ const char *color_pfx = "", *color_sfx = "\33[0m";
+
+ switch (priority)
+ {
+ case PCSC_LOG_CRITICAL:
+ color_pfx = "\33[01;31m"; /* bright + Red */
+ break;
+
+ case PCSC_LOG_ERROR:
+ color_pfx = "\33[35m"; /* Magenta */
+ break;
+
+ case PCSC_LOG_INFO:
+ color_pfx = "\33[34m"; /* Blue */
+ break;
+
+ case PCSC_LOG_DEBUG:
+ color_pfx = ""; /* normal (black) */
+ color_sfx = "";
+ break;
+ }
+ fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx);
+ }
+ else
+ fprintf(stderr, "%s\n", DebugBuffer);
+ }
+#else
+ fprintf(stderr, "%s\n", DebugBuffer);
+#endif
+} /* log_msg */
+
+void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
+ const int len)
+{
+ char DebugBuffer[DEBUG_BUF_SIZE];
+ int i;
+ char *c;
+ char *debug_buf_end;
+
+ if (priority < LogLevel) /* log priority lower than threshold? */
+ return;
+
+ debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
+
+ strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
+ c = DebugBuffer + strlen(DebugBuffer);
+
+ for (i = 0; (i < len) && (c < debug_buf_end); ++i)
+ {
+ sprintf(c, "%02X ", buffer[i]);
+ c += strlen(c);
+ }
+
+ fprintf(stderr, "%s\n", DebugBuffer);
+} /* log_xxd */
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debug.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,78 @@
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 1999-2005
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: debuglog.h 1835 2006-01-25 10:42:23Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles debugging.
+ *
+ * @note log message is sent to syslog or stderr depending on --foreground
+ * command line argument
+ *
+ * @test
+ * @code
+ * Log1(priority, "text");
+ * log "text" with priority level priority
+ * Log2(priority, "text: %d", 1234);
+ * log "text: 1234"
+ * the format string can be anything printf() can understand
+ * Log3(priority, "text: %d %d", 1234, 5678);
+ * log "text: 1234 5678"
+ * the format string can be anything printf() can understand
+ * LogXxd(priority, msg, buffer, size);
+ * log "msg" + a hex dump of size bytes of buffer[]
+ * @endcode
+ */
+
+#ifndef __debug_h__
+#define __debug_h__
+
+#ifdef PCSC
+/* use syslog, etc. if we are included from a file for pcscd */
+#include "debuglog.h"
+#else
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+enum {
+ PCSC_LOG_DEBUG = 0,
+ PCSC_LOG_INFO,
+ PCSC_LOG_ERROR,
+ PCSC_LOG_CRITICAL
+};
+
+#include <stdio.h>
+
+/* You can't do #ifndef __FUNCTION__ */
+#if !defined(__GNUC__) && !defined(__IBMC__)
+#define __FUNCTION__ ""
+#endif
+
+#define Log0(priority) log_msg(priority, "%s:%d:%s()", __FILE__, __LINE__, __FUNCTION__)
+#define Log1(priority, fmt) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__)
+#define Log2(priority, fmt, data) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data)
+#define Log3(priority, fmt, data1, data2) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2)
+#define LogXxd(priority, msg, buffer, size) log_xxd(priority, msg, buffer, size)
+
+void log_msg(const int priority, const char *fmt, ...);
+void log_xxd(const int priority, const char *msg,
+ const unsigned char *buffer, const int size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif /* __debug_h__ */
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * debuglog.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2002
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 1999-2005
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: debuglog.c 2302 2007-01-06 17:57:58Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles debugging for pcscd.
+ */
+
+#include "config.h"
+
+#ifndef WIN32
+#include <syslog.h>
+#endif
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <sys/types.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "debuglog.h"
+#include "sys_generic.h"
+//#include "strlcpy.h"
+
+/**
+ * Max string size when dumping a 256 bytes longs APDU
+ * Should be bigger than 256*3+30
+ */
+#define DEBUG_BUF_SIZE 2048
+
+static char LogSuppress = DEBUGLOG_LOG_ENTRIES;
+static char LogMsgType = DEBUGLOG_NO_DEBUG;
+static char LogCategory = DEBUG_CATEGORY_NOTHING;
+
+/* default level is a bit verbose to be backward compatible */
+static char LogLevel = PCSC_LOG_INFO;
+
+static signed char LogDoColor = 0; /* no color by default */
+
+void log_msg(const int priority, const char *fmt, ...)
+{
+ char DebugBuffer[DEBUG_BUF_SIZE];
+ va_list argptr;
+
+ if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
+ || (priority < LogLevel) /* log priority lower than threshold? */
+ || (DEBUGLOG_NO_DEBUG == LogMsgType))
+ return;
+
+ va_start(argptr, fmt);
+#ifndef WIN32
+ vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
+#else
+#if HAVE_VSNPRINTF
+ vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
+#else
+ vsprintf(DebugBuffer, fmt, argptr);
+#endif
+#endif
+ va_end(argptr);
+
+#ifndef WIN32
+ if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
+ syslog(LOG_INFO, "%s", DebugBuffer);
+ else
+ {
+ if (LogDoColor)
+ {
+ const char *color_pfx = "", *color_sfx = "\33[0m";
+
+ switch (priority)
+ {
+ case PCSC_LOG_CRITICAL:
+ color_pfx = "\33[01;31m"; /* bright + Red */
+ break;
+
+ case PCSC_LOG_ERROR:
+ color_pfx = "\33[35m"; /* Magenta */
+ break;
+
+ case PCSC_LOG_INFO:
+ color_pfx = "\33[34m"; /* Blue */
+ break;
+
+ case PCSC_LOG_DEBUG:
+ color_pfx = ""; /* normal (black) */
+ color_sfx = "";
+ break;
+ }
+ fprintf(stderr, "%s%s%s\n", color_pfx, DebugBuffer, color_sfx);
+ }
+ else
+ fprintf(stderr, "%s\n", DebugBuffer);
+ }
+#else
+ fprintf(stderr, "%s\n", DebugBuffer);
+#endif
+} /* log_msg */
+
+void log_xxd(const int priority, const char *msg, const unsigned char *buffer,
+ const int len)
+{
+ char DebugBuffer[DEBUG_BUF_SIZE];
+ int i;
+ char *c;
+ char *debug_buf_end;
+
+ if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
+ || (priority < LogLevel) /* log priority lower than threshold? */
+ || (DEBUGLOG_NO_DEBUG == LogMsgType))
+ return;
+
+ debug_buf_end = DebugBuffer + DEBUG_BUF_SIZE - 5;
+
+ strlcpy(DebugBuffer, msg, sizeof(DebugBuffer));
+ c = DebugBuffer + strlen(DebugBuffer);
+
+ for (i = 0; (i < len) && (c < debug_buf_end); ++i)
+ {
+ sprintf(c, "%02X ", buffer[i]);
+ c += 3;
+ }
+
+ /* the buffer is too small so end it with "..." */
+ if ((c >= debug_buf_end) && (i < len))
+ c[-3] = c[-2] = c[-1] = '.';
+
+#ifndef WIN32
+ if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
+ syslog(LOG_INFO, "%s", DebugBuffer);
+ else
+#endif
+ fprintf(stderr, "%s\n", DebugBuffer);
+} /* log_xxd */
+
+#ifdef PCSCD
+void DebugLogSuppress(const int lSType)
+{
+ LogSuppress = lSType;
+}
+#endif
+
+void DebugLogSetLogType(const int dbgtype)
+{
+ switch (dbgtype)
+ {
+ case DEBUGLOG_NO_DEBUG:
+ case DEBUGLOG_SYSLOG_DEBUG:
+ case DEBUGLOG_STDERR_DEBUG:
+ LogMsgType = dbgtype;
+ break;
+ default:
+ Log2(PCSC_LOG_CRITICAL, "unknown log type (%d), using stderr",
+ dbgtype);
+ LogMsgType = DEBUGLOG_STDERR_DEBUG;
+ }
+
+ /* no color under Windows */
+#ifndef WIN32
+ /* log to stderr and stderr is a tty? */
+ if (DEBUGLOG_STDERR_DEBUG == LogMsgType && isatty(fileno(stderr)))
+ {
+ const char *terms[] = { "linux", "xterm", "xterm-color", "Eterm", "rxvt", "rxvt-unicode" };
+ char *term;
+
+ term = getenv("TERM");
+ if (term)
+ {
+ unsigned int i;
+
+ /* for each known color terminal */
+ for (i = 0; i < sizeof(terms) / sizeof(terms[0]); i++)
+ {
+ /* we found a supported term? */
+ if (0 == strcmp(terms[i], term))
+ {
+ LogDoColor = 1;
+ break;
+ }
+ }
+ }
+ }
+#endif
+}
+
+void DebugLogSetLevel(const int level)
+{
+ LogLevel = level;
+ switch (level)
+ {
+ case PCSC_LOG_CRITICAL:
+ case PCSC_LOG_ERROR:
+ /* do not log anything */
+ break;
+
+ case PCSC_LOG_INFO:
+ Log1(PCSC_LOG_INFO, "debug level=notice");
+ break;
+
+ case PCSC_LOG_DEBUG:
+ Log1(PCSC_LOG_DEBUG, "debug level=debug");
+ break;
+
+ default:
+ LogLevel = PCSC_LOG_INFO;
+ Log2(PCSC_LOG_CRITICAL, "unknown level (%d), using level=notice",
+ level);
+ }
+}
+
+INTERNAL int DebugLogSetCategory(const int dbginfo)
+{
+#define DEBUG_INFO_LENGTH 80
+ char text[DEBUG_INFO_LENGTH];
+
+ /* use a negative number to UNset
+ * typically use ~DEBUG_CATEGORY_APDU
+ */
+ if (dbginfo < 0)
+ LogCategory &= dbginfo;
+ else
+ LogCategory |= dbginfo;
+
+ /* set to empty string */
+ text[0] = '\0';
+
+ if (LogCategory & DEBUG_CATEGORY_APDU)
+ strlcat(text, " APDU", sizeof(text));
+
+ Log2(PCSC_LOG_INFO, "Debug options:%s", text);
+
+ return LogCategory;
+}
+
+INTERNAL void DebugLogCategory(const int category, const unsigned char *buffer,
+ const int len)
+{
+ if ((category & DEBUG_CATEGORY_APDU)
+ && (LogCategory & DEBUG_CATEGORY_APDU))
+ log_xxd(PCSC_LOG_INFO, "APDU: ", (const unsigned char *)buffer, len);
+
+ if ((category & DEBUG_CATEGORY_SW)
+ && (LogCategory & DEBUG_CATEGORY_APDU))
+ log_xxd(PCSC_LOG_INFO, "SW: ", (const unsigned char *)buffer, len);
+}
+
+/*
+ * old function supported for backward object code compatibility
+ * defined only for pcscd
+ */
+#ifdef PCSCD
+void debug_msg(const char *fmt, ...)
+{
+ char DebugBuffer[DEBUG_BUF_SIZE];
+ va_list argptr;
+
+ if ((LogSuppress != DEBUGLOG_LOG_ENTRIES)
+ || (DEBUGLOG_NO_DEBUG == LogMsgType))
+ return;
+
+ va_start(argptr, fmt);
+#ifndef WIN32
+ vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
+#else
+#if HAVE_VSNPRINTF
+ vsnprintf(DebugBuffer, DEBUG_BUF_SIZE, fmt, argptr);
+#else
+ vsprintf(DebugBuffer, fmt, argptr);
+#endif
+#endif
+ va_end(argptr);
+
+#ifndef WIN32
+ if (DEBUGLOG_SYSLOG_DEBUG == LogMsgType)
+ syslog(LOG_INFO, "%s", DebugBuffer);
+ else
+#endif
+ fprintf(stderr, "%s\n", DebugBuffer);
+} /* debug_msg */
+
+void debug_xxd(const char *msg, const unsigned char *buffer, const int len)
+{
+ log_xxd(PCSC_LOG_ERROR, msg, buffer, len);
+} /* debug_xxd */
+#endif
+
+char *pcsc_stringify_error(const int32_t Error)
+{
+
+ static char strError[75];
+
+ switch (Error)
+ {
+ case SCARD_S_SUCCESS:
+ strcpy(strError, "Command successful.");
+ break;
+ case SCARD_E_CANCELLED:
+ strcpy(strError, "Command cancelled.");
+ break;
+ case SCARD_E_CANT_DISPOSE:
+ strcpy(strError, "Cannot dispose handle.");
+ break;
+ case SCARD_E_INSUFFICIENT_BUFFER:
+ strcpy(strError, "Insufficient buffer.");
+ break;
+ case SCARD_E_INVALID_ATR:
+ strcpy(strError, "Invalid ATR.");
+ break;
+ case SCARD_E_INVALID_HANDLE:
+ strcpy(strError, "Invalid handle.");
+ break;
+ case SCARD_E_INVALID_PARAMETER:
+ strcpy(strError, "Invalid parameter given.");
+ break;
+ case SCARD_E_INVALID_TARGET:
+ strcpy(strError, "Invalid target given.");
+ break;
+ case SCARD_E_INVALID_VALUE:
+ strcpy(strError, "Invalid value given.");
+ break;
+ case SCARD_E_NO_MEMORY:
+ strcpy(strError, "Not enough memory.");
+ break;
+ case SCARD_F_COMM_ERROR:
+ strcpy(strError, "RPC transport error.");
+ break;
+ case SCARD_F_INTERNAL_ERROR:
+ strcpy(strError, "Unknown internal error.");
+ break;
+ case SCARD_F_UNKNOWN_ERROR:
+ strcpy(strError, "Unknown internal error.");
+ break;
+ case SCARD_F_WAITED_TOO_LONG:
+ strcpy(strError, "Waited too long.");
+ break;
+ case SCARD_E_UNKNOWN_READER:
+ strcpy(strError, "Unknown reader specified.");
+ break;
+ case SCARD_E_TIMEOUT:
+ strcpy(strError, "Command timeout.");
+ break;
+ case SCARD_E_SHARING_VIOLATION:
+ strcpy(strError, "Sharing violation.");
+ break;
+ case SCARD_E_NO_SMARTCARD:
+ strcpy(strError, "No smartcard inserted.");
+ break;
+ case SCARD_E_UNKNOWN_CARD:
+ strcpy(strError, "Unknown card.");
+ break;
+ case SCARD_E_PROTO_MISMATCH:
+ strcpy(strError, "Card protocol mismatch.");
+ break;
+ case SCARD_E_NOT_READY:
+ strcpy(strError, "Subsystem not ready.");
+ break;
+ case SCARD_E_SYSTEM_CANCELLED:
+ strcpy(strError, "System cancelled.");
+ break;
+ case SCARD_E_NOT_TRANSACTED:
+ strcpy(strError, "Transaction failed.");
+ break;
+ case SCARD_E_READER_UNAVAILABLE:
+ strcpy(strError, "Reader/s is unavailable.");
+ break;
+ case SCARD_W_UNSUPPORTED_CARD:
+ strcpy(strError, "Card is not supported.");
+ break;
+ case SCARD_W_UNRESPONSIVE_CARD:
+ strcpy(strError, "Card is unresponsive.");
+ break;
+ case SCARD_W_UNPOWERED_CARD:
+ strcpy(strError, "Card is unpowered.");
+ break;
+ case SCARD_W_RESET_CARD:
+ strcpy(strError, "Card was reset.");
+ break;
+ case SCARD_W_REMOVED_CARD:
+ strcpy(strError, "Card was removed.");
+ break;
+ case SCARD_W_INSERTED_CARD:
+ strcpy(strError, "Card was inserted.");
+ break;
+ case SCARD_E_UNSUPPORTED_FEATURE:
+ strcpy(strError, "Feature not supported.");
+ break;
+ case SCARD_E_PCI_TOO_SMALL:
+ strcpy(strError, "PCI struct too small.");
+ break;
+ case SCARD_E_READER_UNSUPPORTED:
+ strcpy(strError, "Reader is unsupported.");
+ break;
+ case SCARD_E_DUPLICATE_READER:
+ strcpy(strError, "Reader already exists.");
+ break;
+ case SCARD_E_CARD_UNSUPPORTED:
+ strcpy(strError, "Card is unsupported.");
+ break;
+ case SCARD_E_NO_SERVICE:
+ strcpy(strError, "Service not available.");
+ break;
+ case SCARD_E_SERVICE_STOPPED:
+ strcpy(strError, "Service was stopped.");
+ break;
+ default:
+ sprintf(strError, "Unknown PCSC error: %d [0x%08X]", Error, Error);
+ break;
+
+ };
+
+ return strError;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/debuglog.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * debuglog.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 1999-2005
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: debuglog.h 2151 2006-09-06 20:02:47Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles debugging.
+ *
+ * @note log message is sent to syslog or stderr depending on --foreground
+ * command line argument
+ *
+ * @test
+ * @code
+ * Log1(priority, "text");
+ * log "text" with priority level priority
+ * Log2(priority, "text: %d", 1234);
+ * log "text: 1234"
+ * the format string can be anything printf() can understand
+ * Log3(priority, "text: %d %d", 1234, 5678);
+ * log "text: 1234 5678"
+ * the format string can be anything printf() can understand
+ * LogXxd(priority, msg, buffer, size);
+ * log "msg" + a hex dump of size bytes of buffer[]
+ * @endcode
+ */
+
+#ifndef __debuglog_h__
+#define __debuglog_h__
+
+#include "pcscexport.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define DEBUGLOG_LOG_ENTRIES 1
+#define DEBUGLOG_IGNORE_ENTRIES 2
+
+enum {
+ DEBUGLOG_NO_DEBUG = 0,
+ DEBUGLOG_SYSLOG_DEBUG,
+ DEBUGLOG_STDERR_DEBUG
+};
+
+#define DEBUG_CATEGORY_NOTHING 0
+#define DEBUG_CATEGORY_APDU 1
+#define DEBUG_CATEGORY_SW 2
+
+enum {
+ PCSC_LOG_DEBUG = 0,
+ PCSC_LOG_INFO,
+ PCSC_LOG_ERROR,
+ PCSC_LOG_CRITICAL
+};
+
+/* You can't do #ifndef __FUNCTION__ */
+#if !defined(__GNUC__) && !defined(__IBMC__)
+#define __FUNCTION__ ""
+#endif
+
+#define Log0(priority) log_msg(priority, "%s:%d:%s()", __FILE__, __LINE__, __FUNCTION__)
+#define Log1(priority, fmt) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__)
+#define Log2(priority, fmt, data) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data)
+#define Log3(priority, fmt, data1, data2) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2)
+#define Log4(priority, fmt, data1, data2, data3) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3)
+#define Log9(priority, fmt, data1, data2, data3, data4, data5, data6, data7, data8) log_msg(priority, "%s:%d:%s() " fmt, __FILE__, __LINE__, __FUNCTION__, data1, data2, data3, data4, data5, data6, data7, data8)
+#define LogXxd(priority, msg, buffer, size) log_xxd(priority, msg, buffer, size)
+
+#define DebugLogA(a) Log1(PCSC_LOG_INFO, a)
+#define DebugLogB(a, b) Log2(PCSC_LOG_INFO, a, b)
+#define DebugLogC(a, b,c) Log3(PCSC_LOG_INFO, a, b, c)
+
+PCSC_API void log_msg(const int priority, const char *fmt, ...);
+PCSC_API void log_xxd(const int priority, const char *msg,
+ const unsigned char *buffer, const int size);
+
+void DebugLogSuppress(const int);
+void DebugLogSetLogType(const int);
+int DebugLogSetCategory(const int);
+void DebugLogCategory(const int, const unsigned char *, const int);
+PCSC_API void DebugLogSetLevel(const int level);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __debuglog_h__ */
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1735 @@
+#define yy_create_buffer bp_create_buffer
+#define yy_delete_buffer bp_delete_buffer
+#define yy_scan_buffer bp_scan_buffer
+#define yy_scan_string bp_scan_string
+#define yy_scan_bytes bp_scan_bytes
+#define yy_flex_debug bp_flex_debug
+#define yy_init_buffer bp_init_buffer
+#define yy_flush_buffer bp_flush_buffer
+#define yy_load_buffer_state bp_load_buffer_state
+#define yy_switch_to_buffer bp_switch_to_buffer
+#define yyin bpin
+#define yyleng bpleng
+#define yylex bplex
+#define yyout bpout
+#define yyrestart bprestart
+#define yytext bptext
+#define yywrap bpwrap
+
+/*
+ * A lexical scanner generated by flex
+ */
+
+/*
+ * Scanner skeleton version: $Header:
+ * /home/cvsroot/muscle/PCSC/src/driverparser.c,v 1.1.1.1 2002/03/30
+ * 18:15:03 corcoran Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+/*
+ * cfront 1.2 defines "c_plusplus" instead of "__cplusplus"
+ */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Use prototypes in function declarations.
+ */
+#define YY_USE_PROTOS
+
+/*
+ * The "const" storage-class-modifier is valid.
+ */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+#pragma warn -rch
+#pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/*
+ * Returned upon end-of-file.
+ */
+#define YY_NULL 0
+
+/*
+ * Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative, we
+ * want to instead treat it as an 8-bit unsigned char, hence the double
+ * cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/*
+ * Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/*
+ * Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/*
+ * Action number for EOF rule of a given start state.
+ */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/*
+ * Special action meaning "start processing a new file".
+ */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/*
+ * Size of default input buffer.
+ */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/*
+ * The funky do-while in the following #define is used to turn the
+ * definition int a single C statement (which needs a semi-colon
+ * terminator). This avoids problems with code like: if (
+ * condition_holds ) yyless( 5 ); else do_something_else(); Prior to
+ * using the do-while the compiler would get upset at the "else" because
+ * it interpreted the "if" statement as being all done when it reached the
+ * ';' after the yyless() call.
+ */
+
+/*
+ * Return all but the first 'n' matched characters back to the input
+ * stream.
+ */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/*
+ * The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+struct yy_buffer_state
+{
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /*
+ * Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /*
+ * Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /*
+ * Whether we "own" the buffer - i.e., we know we created it, and can
+ * realloc() it to grow it, and should free() it to delete it.
+ */
+ int yy_is_our_buffer;
+
+ /*
+ * Whether this is an "interactive" input source; if so, and if we're
+ * using stdio for input, then we want to use getc() instead of
+ * fread(), to make sure we stop fetching input after each newline.
+ */
+ int yy_is_interactive;
+
+ /*
+ * Whether we're considered to be at the beginning of a line. If so,
+ * '^' rules will be active on the next match, otherwise not.
+ */
+ int yy_at_bol;
+
+ /*
+ * Whether to try to fill the input buffer when we reach the end of
+ * it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /*
+ * When an EOF's been seen but there's still some text to process then
+ * we mark the buffer as YY_EOF_PENDING, to indicate that we shouldn't
+ * try reading from the input source any more. We might still have a
+ * bunch of tokens to match, though, because of possible backing-up.
+ * When we actually see the EOF, we change the status to "new" (via
+ * yyrestart()), so that the user can continue scanning by just
+ * pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/*
+ * We provide macros for accessing buffer states in case in the future we
+ * want to put the buffer states in a more general "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+/*
+ * yy_hold_char holds the character lost when yytext is formed.
+ */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into
+ * yy_ch_buf */
+
+int yyleng;
+
+/*
+ * Points to current character in buffer.
+ */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/*
+ * Flag which is used to allow yywrap()'s to do buffer switches instead of
+ * setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO((FILE * input_file));
+
+void yy_switch_to_buffer YY_PROTO((YY_BUFFER_STATE new_buffer));
+void yy_load_buffer_state YY_PROTO((void));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO((FILE * file, int size));
+void yy_delete_buffer YY_PROTO((YY_BUFFER_STATE b));
+void yy_init_buffer YY_PROTO((YY_BUFFER_STATE b, FILE * file));
+void yy_flush_buffer YY_PROTO((YY_BUFFER_STATE b));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO((char *base, yy_size_t size));
+YY_BUFFER_STATE yy_scan_string YY_PROTO((yyconst char *yy_str));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO((yyconst char *bytes, int len));
+
+static void *yy_flex_alloc YY_PROTO((yy_size_t));
+static void *yy_flex_realloc YY_PROTO((void *, yy_size_t));
+static void yy_flex_free YY_PROTO((void *));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO((void));
+static yy_state_type yy_try_NUL_trans YY_PROTO((yy_state_type
+ current_state));
+static int yy_get_next_buffer YY_PROTO((void));
+static void yy_fatal_error YY_PROTO((yyconst char msg[]));
+
+/*
+ * Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 7
+#define YY_END_OF_BUFFER 8
+static yyconst short int yy_accept[39] = { 0,
+ 0, 0, 8, 6, 4, 2, 1, 6, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 5, 0
+};
+
+static yyconst int yy_ec[256] = { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 4, 5, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 6, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 4, 1, 8,
+ 4, 9, 4, 4, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 1, 1, 1, 4, 4, 1, 11, 11, 11, 11,
+
+ 12, 11, 13, 11, 14, 11, 15, 11, 11, 16,
+ 11, 11, 11, 17, 18, 19, 11, 11, 11, 11,
+ 20, 11, 1, 1, 1, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+static yyconst int yy_meta[21] = { 0,
+ 1, 2, 3, 4, 4, 4, 2, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+static yyconst short int yy_base[43] = { 0,
+ 0, 7, 49, 50, 50, 50, 0, 1, 0, 36,
+ 28, 26, 28, 35, 29, 0, 26, 33, 27, 33,
+ 29, 22, 0, 24, 27, 14, 27, 23, 13, 50,
+ 10, 9, 4, 1, 0, 2, 50, 50, 19, 23,
+ 2, 26
+};
+
+static yyconst short int yy_def[43] = { 0,
+ 39, 39, 38, 38, 38, 38, 40, 38, 40, 38,
+ 38, 38, 38, 38, 38, 41, 38, 41, 38, 38,
+ 38, 38, 42, 38, 42, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 0, 38, 38,
+ 38, 38
+};
+
+static yyconst short int yy_nxt[71] = { 0,
+ 38, 5, 6, 18, 7, 38, 38, 8, 5, 6,
+ 37, 7, 36, 38, 8, 10, 35, 34, 11, 4,
+ 4, 4, 4, 9, 9, 33, 9, 25, 32, 25,
+ 31, 30, 29, 28, 27, 26, 24, 23, 22, 21,
+ 20, 19, 17, 16, 15, 14, 13, 12, 38, 3,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38
+};
+
+static yyconst short int yy_chk[71] = { 0,
+ 0, 1, 1, 41, 1, 0, 0, 1, 2, 2,
+ 36, 2, 35, 0, 2, 8, 34, 33, 8, 39,
+ 39, 39, 39, 40, 40, 32, 40, 42, 31, 42,
+ 29, 28, 27, 26, 25, 24, 22, 21, 20, 19,
+ 18, 17, 15, 14, 13, 12, 11, 10, 3, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38
+};
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/*
+ * The intent behind this definition is that it'll catch any uses of
+ * REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "bundleparser.l"
+#define INITIAL 0
+/*****************************************************************
+
+ File : configfile.ll
+ Author : David Corcoran
+ Date : February 12, 1999 modified 7/28/99
+ Purpose: Reads lexical config files and updates database.
+ See http://www.linuxnet.com for more information.
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+
+******************************************************************/
+#line 14 "bundleparser.l"
+
+void evalToken(char *pcToken, int tokType);
+
+static char *pcDesiredKey = 0;
+static char pcKey[200];
+static char pcValue[200];
+static char pcFinValue[200];
+
+void errorCheck(char *pcToken_error);
+
+#line 427 "lex.bp.c"
+
+/*
+ * Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO((void));
+#else
+extern int yywrap YY_PROTO((void));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO((int c, char *buf_ptr));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO((char *, yyconst char *, int));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO((yyconst char *));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO((void));
+#else
+static int input YY_PROTO((void));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO((int new_state));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO((void));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO((void));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/*
+ * Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/*
+ * Amount of stuff to slurp up with each read.
+ */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/*
+ * Copy whatever the last rule matched to the standard output.
+ */
+
+#ifndef ECHO
+/*
+ * This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/*
+ * Gets input and stuffs it into "buf". number of characters read, or
+ * YY_NULL, is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/*
+ * No semi-colon after return; correct usage is to write "yyterminate();"
+ * - we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/*
+ * Number of entries by which start-condition stack grows.
+ */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/*
+ * Report a fatal error.
+ */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/*
+ * Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/*
+ * Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/*
+ * Code executed at the end of each rule.
+ */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 26 "bundleparser.l"
+
+#line 581 "lex.bp.c"
+
+ if (yy_init)
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yy_start)
+ yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_load_buffer_state();
+ }
+
+ while (1) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /*
+ * Support of yytext.
+ */
+ *yy_cp = yy_hold_char;
+
+ /*
+ * yy_bp points to the position in yy_ch_buf of the start of the
+ * current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] !=
+ yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 39)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while (yy_base[yy_current_state] != 50);
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if (yy_act == 0)
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+ do_action: /* This label is used only to access EOF actions. */
+
+ switch (yy_act)
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /*
+ * undo the effects of YY_DO_BEFORE_ACTION
+ */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+#line 28 "bundleparser.l"
+ {
+ }
+ YY_BREAK case 2:
+ YY_RULE_SETUP
+#line 29 "bundleparser.l"
+ {
+ }
+ YY_BREAK case 3:
+ YY_RULE_SETUP
+#line 30 "bundleparser.l"
+ {
+ evalToken(bptext, 1);
+ }
+ YY_BREAK case 4:
+ YY_RULE_SETUP
+#line 31 "bundleparser.l"
+ {
+ }
+ YY_BREAK case 5:
+ YY_RULE_SETUP
+#line 32 "bundleparser.l"
+ {
+ evalToken(bptext, 2);
+ }
+ YY_BREAK case 6:
+ YY_RULE_SETUP
+#line 33 "bundleparser.l"
+ {
+ errorCheck(bptext);
+ }
+ YY_BREAK case 7:
+ YY_RULE_SETUP
+#line 34 "bundleparser.l"
+ ECHO;
+ YY_BREAK
+#line 699 "lex.bp.c"
+ case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /*
+ * Amount of text matched not including the EOB char.
+ */
+ int yy_amount_of_matched_text =
+ (int) (yy_cp - yytext_ptr) - 1;
+
+ /*
+ * Undo the effects of YY_DO_BEFORE_ACTION.
+ */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+ if (yy_current_buffer->yy_buffer_status ==
+ YY_BUFFER_NEW)
+ {
+ /*
+ * We're scanning a new file or input source. It's
+ * possible that this happened because the user just
+ * pointed yyin at a new source and called yylex().
+ * If so, then we have to assure consistency between
+ * yy_current_buffer and our globals. Here is the
+ * right place to do so, because this is the first
+ * action (other than possibly a back-up) that will
+ * match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /*
+ * Note that here we test for yy_c_buf_p "<=" to the
+ * position of the first EOB in the buffer, since
+ * yy_c_buf_p will already have been incremented past the
+ * NUL character (since all states make transitions on EOB
+ * to the end-of-buffer state). Contrast this with the
+ * test in input().
+ */
+ if (yy_c_buf_p <=
+ &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /*
+ * Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it for us
+ * because it doesn't know how to deal with the
+ * possibility of jamming (and we don't want to build
+ * jamming into it because then it will run more
+ * slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state);
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state)
+ {
+ /*
+ * Consume the NUL.
+ */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer())
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap())
+ {
+ /*
+ * Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up yy_c_buf_p so
+ * that if some total hoser (like flex
+ * itself) wants to call the scanner after
+ * we return the YY_NULL, it'll still work
+ * - another YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR
+ ("fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/*
+ * yy_get_next_buffer - try to read in a new buffer Returns a code
+ * representing an action: EOB_ACT_LAST_MATCH - EOB_ACT_CONTINUE_SCAN -
+ * continue scanning from current position EOB_ACT_END_OF_FILE - end of
+ * file
+ */
+
+static int yy_get_next_buffer()
+{
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if (yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1])
+ YY_FATAL_ERROR
+ ("fatal flex scanner internal error--end of buffer missed");
+
+ if (yy_current_buffer->yy_fill_buffer == 0)
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1)
+ {
+ /*
+ * We matched a single character, the EOB, so treat this as a
+ * final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /*
+ * We matched some text prior to the EOB, first process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /*
+ * Try to read more data.
+ */
+
+ /*
+ * First move last chars to start of buffer.
+ */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /*
+ * don't do the read, it's not guaranteed to return an EOF, just
+ * force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0)
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR
+ ("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+#else
+
+ /*
+ * just a shorter name for the current buffer
+ */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset = (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer)
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /*
+ * Include room in for 2 EOB chars.
+ */
+ yy_flex_realloc((void *) b->yy_ch_buf,
+ b->yy_buf_size + 2);
+ } else
+ /*
+ * Can't grow it, we don't own it.
+ */
+ b->yy_ch_buf = 0;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR
+ ("fatal error - scanner input buffer overflow");
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /*
+ * Read in more data.
+ */
+ YY_INPUT((&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read);
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if (yy_n_chars == 0)
+ {
+ if (number_to_move == YY_MORE_ADJ)
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/*
+ * yy_get_previous_state - get the state just before the EOB char was
+ * reached
+ */
+
+static yy_state_type yy_get_previous_state()
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for (yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp)
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] !=
+ yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 39)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/*
+ * yy_try_NUL_trans - try to make a transition on the NUL character
+ * synopsis next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state)
+#else
+static yy_state_type yy_try_NUL_trans(yy_current_state)
+ yy_state_type yy_current_state;
+#endif
+{
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 39)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 38);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput(int c, register char *yy_bp)
+#else
+static void yyunput(c, yy_bp)
+ int c;
+ register char *yy_bp;
+#endif
+{
+ register char *yy_cp = yy_c_buf_p;
+
+ /*
+ * undo effects of setting up yytext
+ */
+ *yy_cp = yy_hold_char;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ { /* need to shift things up to make room */
+ /*
+ * +2 for EOB chars.
+ */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest =
+ &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size +
+ 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while (source > yy_current_buffer->yy_ch_buf)
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ YY_FATAL_ERROR("flex scanner push-back overflow");
+ }
+
+ *--yy_cp = (char) c;
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+{
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if (*yy_c_buf_p == YY_END_OF_BUFFER_CHAR)
+ {
+ /*
+ * yy_c_buf_p now points to the character we want to return. If
+ * this occurs *before* the EOB characters, then it's a valid NUL;
+ * if not, then we've hit the end of the buffer.
+ */
+ if (yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ /*
+ * This was really a NUL.
+ */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch (yy_get_next_buffer())
+ {
+ case EOB_ACT_LAST_MATCH:
+ /*
+ * This happens because yy_g_n_b() sees that we've
+ * accumulated a token and flags that we need to try
+ * matching the token before proceeding. But for input(),
+ * there's no matching to consider. So convert the
+ * EOB_ACT_LAST_MATCH to EOB_ACT_END_OF_FILE.
+ */
+
+ /*
+ * Reset buffer status.
+ */
+ yyrestart(yyin);
+
+ /*
+ * fall through
+ */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if (yywrap())
+ return EOF;
+
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ return c;
+}
+
+#ifdef YY_USE_PROTOS
+void yyrestart(FILE * input_file)
+#else
+void yyrestart(input_file)
+ FILE *input_file;
+#endif
+{
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_init_buffer(yy_current_buffer, input_file);
+ yy_load_buffer_state();
+}
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer)
+#else
+void yy_switch_to_buffer(new_buffer)
+ YY_BUFFER_STATE new_buffer;
+#endif
+{
+ if (yy_current_buffer == new_buffer)
+ return;
+
+ if (yy_current_buffer)
+ {
+ /*
+ * Flush out information for old buffer.
+ */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /*
+ * We don't actually know whether we did this switch during EOF
+ * (yywrap()) processing, but the only time this flag is looked at is
+ * after yywrap() is called, so it's safe to go ahead and always set
+ * it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+}
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state(void)
+#else
+void yy_load_buffer_state()
+#endif
+{
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+}
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer(FILE * file, int size)
+#else
+YY_BUFFER_STATE yy_create_buffer(file, size)
+ FILE *file;
+ int size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = size;
+
+ /*
+ * yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc(b->yy_buf_size + 2);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file);
+
+ return b;
+}
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer(YY_BUFFER_STATE b)
+#else
+void yy_delete_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+{
+ if (!b)
+ return;
+
+ if (b == yy_current_buffer)
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if (b->yy_is_our_buffer)
+ yy_flex_free((void *) b->yy_ch_buf);
+
+ yy_flex_free((void *) b);
+}
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO((int));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer(YY_BUFFER_STATE b, FILE * file)
+#else
+void yy_init_buffer(b, file)
+ YY_BUFFER_STATE b;
+ FILE *file;
+#endif
+
+{
+ yy_flush_buffer(b);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0;
+#endif
+#endif
+}
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer(YY_BUFFER_STATE b)
+#else
+void yy_flush_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+
+{
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /*
+ * We always need two end-of-buffer characters. The first causes a
+ * transition to the end-of-buffer state. The second causes a jam in
+ * that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == yy_current_buffer)
+ yy_load_buffer_state();
+}
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size)
+#else
+YY_BUFFER_STATE yy_scan_buffer(base, size)
+ char *base;
+ yy_size_t size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 ||
+ base[size - 2] != YY_END_OF_BUFFER_CHAR ||
+ base[size - 1] != YY_END_OF_BUFFER_CHAR)
+ /*
+ * They forgot to leave room for the EOB's.
+ */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b);
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string(yyconst char *yy_str)
+#else
+YY_BUFFER_STATE yy_scan_string(yy_str)
+ yyconst char *yy_str;
+#endif
+{
+ int len;
+ for (len = 0; yy_str[len]; ++len)
+ ;
+
+ return yy_scan_bytes(yy_str, len);
+}
+#endif
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes(yyconst char *bytes, int len)
+#else
+YY_BUFFER_STATE yy_scan_bytes(bytes, len)
+ yyconst char *bytes;
+ int len;
+#endif
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /*
+ * Get memory for full buffer, including space for trailing EOB's.
+ */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc(n);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < len; ++i)
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /*
+ * It's okay to grow etc. this buffer, and we should throw it away
+ * when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state(int new_state)
+#else
+static void yy_push_state(new_state)
+ int new_state;
+#endif
+{
+ if (yy_start_stack_ptr >= yy_start_stack_depth)
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof(int);
+
+ if (!yy_start_stack)
+ yy_start_stack = (int *) yy_flex_alloc(new_size);
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size);
+
+ if (!yy_start_stack)
+ YY_FATAL_ERROR
+ ("out of memory expanding start-condition stack");
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+#endif
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+{
+ if (--yy_start_stack_ptr < 0)
+ YY_FATAL_ERROR("start-condition stack underflow");
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+}
+#endif
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+{
+ return yy_start_stack[yy_start_stack_ptr - 1];
+}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error(yyconst char msg[])
+#else
+static void yy_fatal_error(msg)
+ char msg[];
+#endif
+{
+ (void) fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/*
+ * Redefine yyless() so it works in section 3 code.
+ */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy(char *s1, yyconst char *s2, int n)
+#else
+static void yy_flex_strncpy(s1, s2, n)
+ char *s1;
+ yyconst char *s2;
+ int n;
+#endif
+{
+ register int i;
+ for (i = 0; i < n; ++i)
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen(yyconst char *s)
+#else
+static int yy_flex_strlen(s)
+ yyconst char *s;
+#endif
+{
+ register int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc(yy_size_t size)
+#else
+static void *yy_flex_alloc(size)
+ yy_size_t size;
+#endif
+{
+ return (void *) malloc(size);
+}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc(void *ptr, yy_size_t size)
+#else
+static void *yy_flex_realloc(ptr, size)
+ void *ptr;
+ yy_size_t size;
+#endif
+{
+ /*
+ * The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those that use
+ * void* generic pointers. It works with the latter because both ANSI
+ * C and C++ allow castless assignment from any pointer type to void*,
+ * and deal with argument conversions as though doing an assignment.
+ */
+ return (void *) realloc((char *) ptr, size);
+}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free(void *ptr)
+#else
+static void yy_flex_free(ptr)
+ void *ptr;
+#endif
+{
+ free(ptr);
+}
+
+#if YY_MAIN
+int main()
+{
+ yylex();
+ return 0;
+}
+#endif
+#line 34 "bundleparser.l"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wintypes.h"
+#include "debuglog.h"
+
+int bpwrap()
+{
+ return 1;
+}
+
+void evalToken(char *pcToken, int tokType)
+{
+
+ int len;
+ len = 0;
+
+ if (tokType == 1)
+ {
+ for (len = 5; pcToken[len] != '<'; len++) ;
+ strncpy(pcKey, &pcToken[5], len - 5);
+ pcKey[len - 5] = 0;
+ }
+
+ if (tokType == 2)
+ {
+ for (len = 8; pcToken[len] != '<'; len++) ;
+ strncpy(pcValue, &pcToken[8], len - 8);
+ pcValue[len - 8] = 0;
+ if (strcmp(pcKey, pcDesiredKey) == 0)
+ {
+ strcpy(pcFinValue, pcValue);
+ }
+ }
+
+}
+
+void errorCheck(char *token_error)
+{
+}
+
+int LCFBundleFindValueWithKey(char *fileName, char *tokenKey,
+ char *tokenValue)
+{
+
+ FILE *file;
+ file = 0;
+
+ pcDesiredKey = tokenKey;
+ pcFinValue[0] = 0;
+
+ file = fopen(fileName, "r");
+
+ if (!file)
+ {
+ DebugLogB("Could not open bundle file : %s", fileName);
+ return 1;
+ }
+
+ bpin = file;
+
+ do
+ {
+ bplex();
+ }
+ while (!feof(file));
+
+ if (pcFinValue[0] == 0)
+ {
+ DebugLogB("Value/Key not defined for: %s", tokenKey);
+ fclose(file);
+ return -1;
+ } else
+ {
+ strcpy(tokenValue, pcFinValue);
+ fclose(file);
+ return 0;
+ }
+
+ fclose(file);
+ return 0;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.l
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.l (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/driverparser.l 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,108 @@
+/*****************************************************************
+
+ File : configfile.ll
+ Author : David Corcoran
+ Date : February 12, 1999 modified 7/28/99
+ Purpose: Reads lexical config files and updates database.
+ See http://www.linuxnet.com for more information.
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+
+******************************************************************/
+
+%{
+
+void evalToken( char *pcToken, int tokType );
+
+static char *pcDesiredKey = 0;
+static char pcKey[200];
+static char pcValue[200];
+static char pcFinValue[200];
+
+void errorCheck ( char *pcToken_error );
+
+%}
+
+%%
+
+#.* {}
+"\n" {}
+\<key\>([A-Z]|[a-z]|[0-9]|[ \t])+\<\/key\> { evalToken(bptext, 1); }
+[ \t] {}
+\<string\>([A-Z]|[a-z]|[0-9]|[ \t]|[!@#$%^&*()\-+/_\:?.,=~'"])+\<\/string\> { evalToken(bptext, 2); }
+. { errorCheck( bptext ); }
+%%
+
+#include <stdio.h>
+#include <string.h>
+
+#include "wintypes.h"
+#include "debuglog.h"
+
+int bpwrap() {
+ return 1;
+}
+
+
+void evalToken( char *pcToken, int tokType ) {
+
+ int len;
+ len = 0;
+
+ if ( tokType == 1 ) {
+ for (len=5; pcToken[len] != '<'; len++);
+ strncpy(pcKey, &pcToken[5], len - 5);
+ pcKey[len-5] = 0;
+ }
+
+ if ( tokType == 2 ) {
+ for (len=8; pcToken[len] != '<'; len++);
+ strncpy(pcValue, &pcToken[8], len - 8);
+ pcValue[len-8] = 0;
+ if ( strcmp(pcKey, pcDesiredKey) == 0 ) {
+ strcpy(pcFinValue, pcValue);
+ }
+ }
+
+
+}
+
+void errorCheck ( char *token_error ) { }
+
+int LCFBundleFindValueWithKey(char *fileName, char *tokenKey,
+ char *tokenValue ) {
+
+ FILE *file;
+ file = 0;
+
+ pcDesiredKey = tokenKey;
+ pcFinValue[0] = 0;
+
+ file = fopen(fileName, "r");
+
+ if (!file) {
+ DebugLogB( "Could not open bundle file : %s", fileName );
+ return 1;
+ }
+
+ bpin = file;
+
+ do {
+ bplex();
+ }
+ while (!feof(file));
+
+ if ( pcFinValue[0] == 0 ) {
+ DebugLogB( "Value/Key not defined for: %s", tokenKey );
+ fclose(file);
+ return -1;
+ } else {
+ strcpy(tokenValue, pcFinValue);
+ fclose(file);
+ return 0;
+ }
+
+ fclose(file);
+ return 0;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_generic.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_generic.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_generic.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : dyn_generic.h
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 8/12/99
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts dynamic library loading
+ functions.
+
+********************************************************************/
+
+#ifndef __dyn_generic_h__
+#define __dyn_generic_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ int DYN_LoadLibrary(void **, char *);
+ int DYN_CloseLibrary(void **);
+ int DYN_GetAddress(void *, void **, char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_macosx.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_macosx.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/dyn_macosx.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : dyn_macosx.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 3/15/00
+ License: Copyright (C) 2000 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts dynamic library loading
+ functions and timing.
+
+********************************************************************/
+
+#include <CoreFoundation/CFBundle.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFURL.h>
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "dyn_generic.h"
+#include "debuglog.h"
+
+/*
+ * / Load a module (if needed)
+ */
+int DYN_LoadLibrary(void **pvLHandle, char *pcLibrary)
+{
+
+ CFStringRef bundlePath;
+ CFURLRef bundleURL;
+ CFBundleRef bundle;
+
+ *pvLHandle = 0;
+
+ /*
+ * @@@ kCFStringEncodingMacRoman might be wrong on non US systems.
+ */
+
+ bundlePath = CFStringCreateWithCString(NULL, pcLibrary,
+ kCFStringEncodingMacRoman);
+ if (bundlePath == NULL)
+ {
+ return SCARD_E_NO_MEMORY;
+
+ } else
+ {
+ }
+
+ bundleURL = CFURLCreateWithFileSystemPath(NULL, bundlePath,
+ kCFURLPOSIXPathStyle, TRUE);
+ CFRelease(bundlePath);
+ if (bundleURL == NULL)
+ {
+ return SCARD_E_NO_MEMORY;
+ } else
+ {
+ }
+
+ bundle = CFBundleCreate(NULL, bundleURL);
+ CFRelease(bundleURL);
+ if (bundle == NULL)
+ {
+ return SCARD_F_UNKNOWN_ERROR;
+ } else
+ {
+ }
+
+ if (!CFBundleLoadExecutable(bundle))
+ {
+ CFRelease(bundle);
+ return SCARD_F_UNKNOWN_ERROR;
+ } else
+ {
+ }
+
+ *pvLHandle = (void *) bundle;
+
+ return SCARD_S_SUCCESS;
+}
+
+int DYN_CloseLibrary(void **pvLHandle)
+{
+
+ CFBundleRef bundle = (CFBundleRef) * pvLHandle;
+
+ if (CFBundleIsExecutableLoaded(bundle) == TRUE)
+ {
+ CFBundleUnloadExecutable(bundle);
+ CFRelease(bundle);
+ } else
+ {
+ DebugLogA("DYN_CloseLibrary: Cannot unload library.");
+ }
+
+ *pvLHandle = 0;
+ return SCARD_S_SUCCESS;
+}
+
+int DYN_GetAddress(void *pvLHandle, void **pvFHandle, char *pcFunction)
+{
+
+ CFBundleRef bundle = (CFBundleRef) pvLHandle;
+ CFStringRef cfName = CFStringCreateWithCString(NULL, pcFunction,
+ kCFStringEncodingMacRoman);
+ if (cfName == NULL)
+ return SCARD_E_NO_MEMORY;
+
+ *pvFHandle = CFBundleGetFunctionPointerForName(bundle, cfName);
+ CFRelease(cfName);
+ if (*pvFHandle == NULL)
+ return SCARD_F_UNKNOWN_ERROR;
+
+ return SCARD_S_SUCCESS;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : eventhandler.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 3/13/00
+ License: Copyright (C) 2000 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This keeps track of card insertion/removal events
+ and updates ATR, protocol, and status information.
+
+********************************************************************/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "thread_generic.h"
+#include "readerfactory.h"
+#include "eventhandler.h"
+#include "dyn_generic.h"
+#include "sys_generic.h"
+#include "ifdhandler.h"
+#include "ifdwrapper.h"
+#include "debuglog.h"
+#include "prothandler.h"
+
+#include <security_utilities/debugging.h>
+
+static PREADER_STATES readerStates[PCSCLITE_MAX_CONTEXTS];
+
+void EHStatusHandlerThread(PREADER_CONTEXT);
+
+LONG EHInitializeEventStructures()
+{
+
+ int fd, i, pageSize;
+
+ fd = 0;
+ i = 0;
+ pageSize = 0;
+
+ SYS_RemoveFile(PCSCLITE_PUBSHM_FILE);
+
+ fd = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT, 00644);
+ if (fd < 0)
+ {
+ DebugLogA("Error: Cannot open public shared file");
+ exit(1);
+ }
+
+ SYS_Chmod(PCSCLITE_PUBSHM_FILE,
+ S_IRGRP | S_IREAD | S_IWRITE | S_IROTH);
+
+ pageSize = SYS_GetPageSize();
+
+ /*
+ * Jump to end of file space and allocate zero's
+ */
+ SYS_SeekFile(fd, pageSize * PCSCLITE_MAX_CONTEXTS);
+ SYS_WriteFile(fd, "", 1);
+
+ /*
+ * Allocate each reader structure
+ */
+ for (i = 0; i < PCSCLITE_MAX_CONTEXTS; i++)
+ {
+ readerStates[i] = (PREADER_STATES)
+ SYS_MemoryMap(sizeof(READER_STATES), fd, (i * pageSize));
+ if (readerStates[i] == 0)
+ {
+ DebugLogA("Error: Cannot public memory map");
+ exit(1);
+ }
+
+ /*
+ * Zero out each value in the struct
+ */
+ memset((readerStates[i])->readerName, 0, MAX_READERNAME);
+ memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
+ (readerStates[i])->readerID = 0;
+ (readerStates[i])->readerState = 0;
+ (readerStates[i])->lockState = 0;
+ (readerStates[i])->readerSharing = 0;
+ (readerStates[i])->cardAtrLength = 0;
+ (readerStates[i])->cardProtocol = 0;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG EHDestroyEventHandler(PREADER_CONTEXT rContext)
+{
+
+ LONG rv;
+ int i;
+
+ i = 0;
+ rv = 0;
+
+
+ i = rContext->dwPublicID;
+ if ((readerStates[i])->readerName[0] == 0)
+ {
+ DebugLogA("EHDestroyEventHandler: Thread already stomped.");
+ return SCARD_S_SUCCESS;
+ }
+
+ /*
+ * Set the thread to 0 to exit thread
+ */
+ rContext->dwLockId = 0xFFFF;
+
+ DebugLogA("EHDestroyEventHandler: Stomping thread.");
+
+ do
+ {
+ /*
+ * Wait 0.05 seconds for the child to respond
+ */
+ SYS_USleep(50000);
+ }
+ while (rContext->dwLockId == 0xFFFF);
+
+ /*
+ * Zero out the public status struct to allow it to be recycled and
+ * used again
+ */
+
+ memset((readerStates[i])->readerName, 0, MAX_READERNAME);
+ memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
+ (readerStates[i])->readerID = 0;
+ (readerStates[i])->readerState = 0;
+ (readerStates[i])->lockState = 0;
+ (readerStates[i])->readerSharing = 0;
+ (readerStates[i])->cardAtrLength = 0;
+ (readerStates[i])->cardProtocol = 0;
+
+ SYS_MMapSynchronize((void *) readerStates[i], SYS_GetPageSize());
+
+ /* Zero the thread */
+ rContext->pthThread = 0;
+
+ DebugLogA("EHDestroyEventHandler: Thread stomped.");
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG EHSpawnEventHandler(PREADER_CONTEXT rContext)
+{
+ LONG rv;
+ LPCSTR lpcReader;
+ DWORD dwStatus, dwProtocol;
+ int i;
+
+ /*
+ * Zero out everything
+ */
+ rv = 0;
+ lpcReader = 0;
+ dwStatus = 0;
+ dwProtocol = 0;
+ i = 0;
+
+ lpcReader = rContext->lpcReader;
+
+ rv = IFDStatusICC(rContext, &dwStatus,
+ &dwProtocol, rContext->ucAtr, &rContext->dwAtrLen);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DebugLogB("EHSpawnEventHandler: Initial Check Failed on %s",
+ lpcReader);
+ return SCARD_F_UNKNOWN_ERROR;
+ }
+
+ /*
+ * Find an empty reader slot and insert the new reader
+ */
+ for (i = 0; i < PCSCLITE_MAX_CONTEXTS; i++)
+ {
+ if ((readerStates[i])->readerID == 0)
+ {
+ break;
+ }
+ }
+
+ if (i == PCSCLITE_MAX_CONTEXTS)
+ {
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ /*
+ * Set all the attributes to this reader
+ */
+ strcpy((readerStates[i])->readerName, rContext->lpcReader);
+ memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
+ rContext->dwAtrLen);
+ (readerStates[i])->readerID = htonl(i + 100);
+ (readerStates[i])->readerState = htonl(rContext->dwStatus);
+ (readerStates[i])->readerSharing = htonl(rContext->dwContexts);
+ (readerStates[i])->cardAtrLength = htonl(rContext->dwAtrLen);
+ (readerStates[i])->cardProtocol = htonl(rContext->dwProtocol);
+ /*
+ * So the thread can access this array indice
+ */
+ rContext->dwPublicID = i;
+
+ rv = SYS_ThreadCreate(&rContext->pthThread, NULL,
+ (LPVOID) EHStatusHandlerThread, (LPVOID) rContext);
+ secdebug("pcscd", "EHSpawnEventHandler after thread create: %d [%04X]", rv, rv);
+ if (rv == 1)
+ {
+ return SCARD_S_SUCCESS;
+ } else
+ {
+ return SCARD_E_NO_MEMORY;
+ }
+
+}
+
+void EHStatusHandlerThread(PREADER_CONTEXT rContext)
+{
+
+ LONG rv;
+ LPCSTR lpcReader;
+ DWORD dwStatus, dwProtocol, dwReaderSharing;
+ DWORD dwErrorCount, dwCurrentState;
+ int i, pageSize;
+
+ /*
+ * Zero out everything
+ */
+ rv = 0;
+ lpcReader = 0;
+ dwStatus = 0;
+ dwProtocol = 0;
+ dwReaderSharing = 0;
+ dwCurrentState = 0;
+ dwErrorCount = 0;
+ i = 0;
+ pageSize = 0;
+
+ lpcReader = rContext->lpcReader;
+ i = rContext->dwPublicID;
+
+ pageSize = SYS_GetPageSize();
+
+ rv = IFDStatusICC(rContext, &dwStatus,
+ &dwProtocol, rContext->ucAtr, &rContext->dwAtrLen);
+ secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDStatusICC: %d [%04X]", rv, rv);
+
+ if (dwStatus & SCARD_PRESENT)
+ {
+ rv = IFDPowerICC(rContext, IFD_POWER_UP,
+ rContext->ucAtr, &rContext->dwAtrLen);
+ secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDPowerICC: %d [%04X]", rv, rv);
+
+ if (rv == IFD_SUCCESS)
+ {
+ rContext->dwProtocol = PHGetDefaultProtocol(rContext->ucAtr,
+ rContext->dwAtrLen);
+ rContext->dwStatus |= SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_ABSENT;
+ rContext->dwStatus |= SCARD_POWERED;
+ rContext->dwStatus |= SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ rContext->dwStatus &= ~SCARD_SWALLOWED;
+ rContext->dwStatus &= ~SCARD_UNKNOWN;
+ } else
+ {
+ rContext->dwStatus |= SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_ABSENT;
+ rContext->dwStatus |= SCARD_SWALLOWED;
+ rContext->dwStatus &= ~SCARD_POWERED;
+ rContext->dwStatus &= ~SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ rContext->dwStatus &= ~SCARD_UNKNOWN;
+ rContext->dwProtocol = 0;
+ rContext->dwAtrLen = 0;
+ }
+
+ dwCurrentState = SCARD_PRESENT;
+
+ } else
+ {
+ dwCurrentState = SCARD_ABSENT;
+ rContext->dwStatus |= SCARD_ABSENT;
+ rContext->dwStatus &= ~SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_POWERED;
+ rContext->dwStatus &= ~SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ rContext->dwStatus &= ~SCARD_SWALLOWED;
+ rContext->dwStatus &= ~SCARD_UNKNOWN;
+ rContext->dwAtrLen = 0;
+ rContext->dwProtocol = 0;
+ }
+
+ /*
+ * Set all the public attributes to this reader
+ */
+ (readerStates[i])->readerState = htonl(rContext->dwStatus);
+ (readerStates[i])->cardAtrLength = htonl(rContext->dwAtrLen);
+ (readerStates[i])->cardProtocol = htonl(rContext->dwProtocol);
+ dwReaderSharing = rContext->dwContexts;
+ (readerStates[i])->readerSharing = htonl(dwReaderSharing);
+ memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
+ rContext->dwAtrLen);
+
+ SYS_MMapSynchronize((void *) readerStates[i], pageSize);
+
+ while (1)
+ {
+
+ dwStatus = 0;
+
+ rv = IFDStatusICC(rContext, &dwStatus,
+ &dwProtocol, rContext->ucAtr, &rContext->dwAtrLen);
+// secdebug("pcscd", "EHStatusHandlerThread: loop call to IFDStatusICC: %d [%04X]", rv, rv);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DebugLogB("EHSpawnEventHandler: Error communicating to: %s",
+ lpcReader);
+
+ /*
+ * Set error status on this reader while errors occur
+ */
+
+ rContext->dwStatus &= ~SCARD_ABSENT;
+ rContext->dwStatus &= ~SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_POWERED;
+ rContext->dwStatus &= ~SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ rContext->dwStatus &= ~SCARD_SWALLOWED;
+ rContext->dwStatus |= SCARD_UNKNOWN;
+ rContext->dwAtrLen = 0;
+ rContext->dwProtocol = 0;
+
+ dwCurrentState = SCARD_UNKNOWN;
+
+ /*
+ * Set all the public attributes to this reader
+ */
+ (readerStates[i])->readerState = htonl(rContext->dwStatus);
+ (readerStates[i])->cardAtrLength = htonl(rContext->dwAtrLen);
+ (readerStates[i])->cardProtocol = htonl(rContext->dwProtocol);
+ memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
+ rContext->dwAtrLen);
+ SYS_MMapSynchronize((void *) readerStates[i], pageSize);
+
+ /*
+ * This code causes race conditions on G4's with USB
+ * insertion
+ */
+ /*
+ * dwErrorCount += 1; SYS_Sleep(1);
+ */
+ /*
+ * After 10 seconds of errors, try to reinitialize the reader
+ * This sometimes helps bring readers out of *crazy* states.
+ */
+ /*
+ * if ( dwErrorCount == 10 ) { RFUnInitializeReader( rContext
+ * ); RFInitializeReader( rContext ); dwErrorCount = 0; }
+ */
+
+ /*
+ * End of race condition code block
+ */
+
+ }
+
+ if (dwStatus & SCARD_ABSENT)
+ {
+ if (dwCurrentState == SCARD_PRESENT ||
+ dwCurrentState == SCARD_UNKNOWN)
+ {
+
+ /*
+ * Change the status structure
+ */
+ DebugLogB("EHSpawnEventHandler: Card Removed From %s",
+ lpcReader);
+ /*
+ * Notify the card has been removed
+ */
+ RFSetReaderEventState(rContext, SCARD_REMOVED);
+
+ rContext->dwAtrLen = 0;
+ rContext->dwProtocol = 0;
+ rContext->dwStatus |= SCARD_ABSENT;
+ rContext->dwStatus &= ~SCARD_UNKNOWN;
+ rContext->dwStatus &= ~SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_POWERED;
+ rContext->dwStatus &= ~SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SWALLOWED;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ dwCurrentState = SCARD_ABSENT;
+
+ /*
+ * Set all the public attributes to this reader
+ */
+ (readerStates[i])->readerState = htonl(rContext->dwStatus);
+ (readerStates[i])->cardAtrLength = htonl(rContext->dwAtrLen);
+ (readerStates[i])->cardProtocol = htonl(rContext->dwProtocol);
+ memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
+ rContext->dwAtrLen);
+
+ SYS_MMapSynchronize((void *) readerStates[i], pageSize);
+ }
+
+ } else if (dwStatus & SCARD_PRESENT)
+ {
+ if (dwCurrentState == SCARD_ABSENT ||
+ dwCurrentState == SCARD_UNKNOWN)
+ {
+
+ /*
+ * Power and reset the card
+ */
+ SYS_USleep(PCSCLITE_STATUS_WAIT);
+ rv = IFDPowerICC(rContext, IFD_POWER_UP,
+ rContext->ucAtr, &rContext->dwAtrLen);
+ secdebug("pcscd", "EHStatusHandlerThread: power-and-reset call to IFDPowerICC: %d [%04X]", rv, rv);
+
+ if (rv == IFD_SUCCESS)
+ {
+ rContext->dwProtocol =
+ PHGetDefaultProtocol(rContext->ucAtr,
+ rContext->dwAtrLen);
+ rContext->dwStatus |= SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_ABSENT;
+ rContext->dwStatus |= SCARD_POWERED;
+ rContext->dwStatus |= SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ rContext->dwStatus &= ~SCARD_UNKNOWN;
+ rContext->dwStatus &= ~SCARD_SWALLOWED;
+
+ /*
+ * Notify the card has been reset
+ */
+ /*
+ * RFSetReaderEventState( rContext, SCARD_RESET );
+ */
+ } else
+ {
+ rContext->dwStatus |= SCARD_PRESENT;
+ rContext->dwStatus &= ~SCARD_ABSENT;
+ rContext->dwStatus |= SCARD_SWALLOWED;
+ rContext->dwStatus &= ~SCARD_POWERED;
+ rContext->dwStatus &= ~SCARD_NEGOTIABLE;
+ rContext->dwStatus &= ~SCARD_SPECIFIC;
+ rContext->dwStatus &= ~SCARD_UNKNOWN;
+ rContext->dwAtrLen = 0;
+ rContext->dwProtocol = 0;
+ }
+
+ dwCurrentState = SCARD_PRESENT;
+
+ /*
+ * Set all the public attributes to this reader
+ */
+ (readerStates[i])->readerState = htonl(rContext->dwStatus);
+ (readerStates[i])->cardAtrLength = htonl(rContext->dwAtrLen);
+ (readerStates[i])->cardProtocol = htonl(rContext->dwProtocol);
+ memcpy((readerStates[i])->cardAtr, rContext->ucAtr,
+ rContext->dwAtrLen);
+
+ SYS_MMapSynchronize((void *) readerStates[i], pageSize);
+
+ DebugLogB("EHSpawnEventHandler: Card inserted into %s",
+ lpcReader);
+
+ if (rv == IFD_SUCCESS)
+ {
+ if (rContext->dwAtrLen > 0)
+ {
+ DebugXxd("EHSpawnEventHandler: Card ATR: ",
+ rContext->ucAtr, rContext->dwAtrLen);
+ } else
+ {
+ DebugLogA("EHSpawnEventHandler: Card ATR: (NULL)");
+ }
+
+ } else
+ {
+ DebugLogA
+ ("EHSpawnEventHandler: Error powering up card.");
+ }
+ }
+ }
+
+ if (rContext->dwLockId == 0xFFFF)
+ {
+ /*
+ * Exit and notify the caller
+ */
+ secdebug("pcscd", "EHStatusHandlerThread: lockid is -1?? - exiting");
+ rContext->dwLockId = 0;
+ SYS_ThreadDetach(rContext->pthThread);
+ SYS_ThreadExit(0);
+ }
+
+ /*
+ * Sharing may change w/o an event pass it on
+ */
+
+ if (dwReaderSharing != rContext->dwContexts)
+ {
+ dwReaderSharing = rContext->dwContexts;
+ (readerStates[i])->readerSharing = htonl(dwReaderSharing);
+ SYS_MMapSynchronize((void *) readerStates[i], pageSize);
+ }
+
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
+ }
+}
+
+void EHSetSharingEvent(PREADER_CONTEXT rContext, DWORD dwValue)
+{
+
+ (readerStates[rContext->dwPublicID])->lockState = htonl(dwValue);
+
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,533 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * eventhandler.cpp
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2000
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 2004
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: eventhandler.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps track of card insertion/removal events
+ * and updates ATR, protocol, and status information.
+ */
+
+#include "config.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "ifdhandler.h"
+#include "debuglog.h"
+#include "thread_generic.h"
+#include "readerfactory.h"
+#include "eventhandler.h"
+#include "dyn_generic.h"
+#include "sys_generic.h"
+#include "ifdwrapper.h"
+#include "prothandler.h"
+#include "readerstate.h"
+
+#include <security_utilities/debugging.h>
+
+static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
+
+void EHStatusHandlerThread(PREADER_CONTEXT);
+
+LONG EHInitializeEventStructures(void)
+{
+ int fd, i, pageSize;
+
+ fd = 0;
+ i = 0;
+ pageSize = 0;
+
+ /*
+ Do not truncate to avoid possible SIGSEG on clients
+ Do not remove the file to allow long-term clients such as securityd to
+ stay connected to the same file
+ */
+ fd = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDWR | O_CREAT , 00644);
+ if (fd < 0)
+ {
+ Log3(PCSC_LOG_CRITICAL, "Cannot create public shared file %s: %s",
+ PCSCLITE_PUBSHM_FILE, strerror(errno));
+ exit(1);
+ }
+
+ SYS_Chmod(PCSCLITE_PUBSHM_FILE,
+ S_IRGRP | S_IREAD | S_IWRITE | S_IROTH);
+
+ pageSize = SYS_GetPageSize();
+
+ int rx = ftruncate(fd, pageSize * PCSCLITE_MAX_READERS_CONTEXTS);
+ if (rx)
+ Log3(PCSC_LOG_CRITICAL, "Cannot truncate public shared file %d: %s",
+ errno, strerror(errno));
+ /*
+ * Jump to end of file space and allocate zero's
+ */
+ SYS_SeekFile(fd, pageSize * PCSCLITE_MAX_READERS_CONTEXTS);
+ SYS_WriteFile(fd, "", 1);
+
+ /*
+ * Allocate each reader structure
+ */
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ readerStates[i] = (PREADER_STATE)
+ SYS_MemoryMap(sizeof(READER_STATE), fd, (i * pageSize));
+ if (readerStates[i] == MAP_FAILED)
+ {
+ Log3(PCSC_LOG_CRITICAL, "Cannot memory map public shared file %s: %s",
+ PCSCLITE_PUBSHM_FILE, strerror(errno));
+ exit(1);
+ }
+
+ /*
+ * Zero out each value in the struct
+ */
+ memset((readerStates[i])->readerName, 0, MAX_READERNAME);
+ memset((readerStates[i])->cardAtr, 0, MAX_ATR_SIZE);
+ (readerStates[i])->readerID = 0;
+ (readerStates[i])->readerState = 0;
+ (readerStates[i])->lockState = 0;
+ (readerStates[i])->readerSharing = 0;
+ (readerStates[i])->cardAtrLength = 0;
+ (readerStates[i])->cardProtocol = SCARD_PROTOCOL_UNSET; // ok since this is 0
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG EHDestroyEventHandler(PREADER_CONTEXT rContext)
+{
+ if (NULL == rContext->readerState)
+ {
+ Log1(PCSC_LOG_ERROR, "Thread never started (reader init failed?)");
+ return SCARD_S_SUCCESS;
+ }
+
+ PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState);
+ if ((rContext->pthThread == 0) || !rs || (rs->readerNameLength() == 0))
+ {
+ Log1(PCSC_LOG_INFO, "Thread already stomped.");
+ return SCARD_S_SUCCESS;
+ }
+
+ secdebug("pcscd", "EHDestroyEventHandler: pthThread: %p, reader name len: %ld",
+ rContext->pthThread, rs->readerNameLength());
+
+ /*
+ * Zero out the public status struct to allow it to be recycled and
+ * used again
+ */
+
+ rs->xreaderNameClear();
+ rs->xcardAtrClear();
+ rs->xreaderID(0);
+ rs->xreaderState(0);
+ rs->xlockState(0);
+ rs->sharing(0);
+ rs->xcardAtrLength(0);
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET); // we only set this one to write to memory cache
+
+ /*
+ * Set the thread to 0 to exit thread
+ */
+ ReaderContextLock(rContext);
+
+ Log1(PCSC_LOG_INFO, "Stomping thread.");
+
+ int ix;
+ for (ix = 0; (ix < 100) && ReaderContextIsLocked(rContext); ++ix)
+ {
+ /*
+ * Wait 0.05 seconds for the child to respond
+ */
+ SYS_USleep(50000);
+ }
+
+ secdebug("pcscd", "EHDestroyEventHandler: post-stop dwLockId: %d", rContext->dwLockId);
+
+
+ /* Zero the thread */
+ rContext->pthThread = 0;
+
+ Log1(PCSC_LOG_INFO, "Thread stomped.");
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG EHSpawnEventHandler(PREADER_CONTEXT rContext)
+{
+ LONG rv;
+ DWORD dwStatus = 0;
+ int i;
+ UCHAR ucAtr[MAX_ATR_SIZE];
+ DWORD dwAtrLen = 0;
+
+ secdebug("pcscd", "EHSpawnEventHandler: rContext: 0x%08X", rContext);
+ rv = IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log2(PCSC_LOG_ERROR, "Initial Check Failed on %s", rContext->lpcReader);
+ return SCARD_F_UNKNOWN_ERROR;
+ }
+
+ /*
+ * Find an empty reader slot and insert the new reader
+ */
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ PCSCD::SharedReaderState *rstmp = PCSCD::SharedReaderState::overlay(readerStates[i]);
+ if (rstmp->xreaderID() == 0)
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ return SCARD_F_INTERNAL_ERROR;
+
+ /*
+ * Set all the attributes to this reader
+ */
+ PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(readerStates[i]);
+ rContext->readerState = readerStates[i];
+ rs->xreaderName(rContext->lpcReader);
+ rs->xcardAtr(ucAtr, dwAtrLen); // also sets cardAtrLength
+
+ rs->xreaderID(i + 100);
+ rs->xreaderState(dwStatus);
+ rs->sharing(rContext->dwContexts);
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
+
+ rv = SYS_ThreadCreate(&rContext->pthThread, THREAD_ATTR_DETACHED,
+ (PCSCLITE_THREAD_FUNCTION( ))EHStatusHandlerThread, (LPVOID) rContext);
+ secdebug("pcscd", "EHSpawnEventHandler after thread create: %d [%04X]", rv, rv);
+ if (rv == 1)
+ return SCARD_S_SUCCESS;
+ else
+ return SCARD_E_NO_MEMORY;
+}
+
+void EHStatusHandlerThread(PREADER_CONTEXT rContext)
+{
+ LONG rv;
+ LPCSTR lpcReader;
+ DWORD dwStatus, dwReaderSharing;
+ DWORD dwCurrentState;
+ int pageSize = SYS_GetPageSize();
+
+ /*
+ * Zero out everything
+ */
+ dwStatus = 0;
+ dwReaderSharing = 0;
+ dwCurrentState = 0;
+
+ secdebug("pcscd", "EHStatusHandlerThread: rContext: 0x%08X", rContext);
+ lpcReader = rContext->lpcReader;
+
+ PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState);
+
+ DWORD tmpCardAtrLength = MAX_ATR_SIZE;
+ rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength);
+ secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDStatusICC: %d [%04X]", rv, rv);
+
+ if (dwStatus & SCARD_PRESENT)
+ {
+ tmpCardAtrLength = MAX_ATR_SIZE;
+ rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength);
+
+ /* the protocol is unset after a power on */
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
+
+ secdebug("pcscd", "EHStatusHandlerThread: initial call to IFDPowerICC: %d [%04X]", rv, rv);
+
+ if (rv == IFD_SUCCESS)
+ {
+ rs->xcardAtrLength(tmpCardAtrLength);
+
+ dwStatus |= SCARD_PRESENT;
+ dwStatus &= ~SCARD_ABSENT;
+ dwStatus |= SCARD_POWERED;
+ dwStatus |= SCARD_NEGOTIABLE;
+ dwStatus &= ~SCARD_SPECIFIC;
+ dwStatus &= ~SCARD_SWALLOWED;
+ dwStatus &= ~SCARD_UNKNOWN;
+
+ if (rs->xcardAtrLength() > 0)
+ {
+ LogXxd(PCSC_LOG_INFO, "Card ATR: ",
+ rs->xcardAtr(),
+ rs->xcardAtrLength());
+ }
+ else
+ Log1(PCSC_LOG_INFO, "Card ATR: (NULL)");
+ }
+ else
+ {
+ dwStatus |= SCARD_PRESENT;
+ dwStatus &= ~SCARD_ABSENT;
+ dwStatus |= SCARD_SWALLOWED;
+ dwStatus &= ~SCARD_POWERED;
+ dwStatus &= ~SCARD_NEGOTIABLE;
+ dwStatus &= ~SCARD_SPECIFIC;
+ dwStatus &= ~SCARD_UNKNOWN;
+ Log3(PCSC_LOG_ERROR, "Error powering up card: %d 0x%04X", rv, rv);
+ }
+
+ dwCurrentState = SCARD_PRESENT;
+ }
+ else
+ {
+ dwStatus |= SCARD_ABSENT;
+ dwStatus &= ~SCARD_PRESENT;
+ dwStatus &= ~SCARD_POWERED;
+ dwStatus &= ~SCARD_NEGOTIABLE;
+ dwStatus &= ~SCARD_SPECIFIC;
+ dwStatus &= ~SCARD_SWALLOWED;
+ dwStatus &= ~SCARD_UNKNOWN;
+ rs->xcardAtrLength(0);
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
+
+ dwCurrentState = SCARD_ABSENT;
+ }
+
+ /*
+ * Set all the public attributes to this reader
+ */
+ rs->xreaderState(dwStatus);
+ dwReaderSharing = rContext->dwContexts;
+ rs->sharing(dwReaderSharing);
+
+ SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
+
+ while (1)
+ {
+ dwStatus = 0;
+
+ // Defensive measure
+ if (!rContext->vHandle)
+ {
+ // Exit and notify the caller
+ secdebug("pcscd", "EHStatusHandlerThread: lost dynamic callbacks ??");
+ ReaderContextUnlock(rContext);
+ SYS_ThreadDetach(rContext->pthThread);
+ SYS_ThreadExit(0);
+ }
+
+ DWORD tmpCardAtrLength = MAX_ATR_SIZE;
+ rv = IFDStatusICC(rContext, &dwStatus, rs->xcardAtr(), &tmpCardAtrLength);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log2(PCSC_LOG_ERROR, "Error communicating to: %s", lpcReader);
+
+ /*
+ * Set error status on this reader while errors occur
+ */
+
+ DWORD readerStateTmp = rs->xreaderState();
+ readerStateTmp &= ~SCARD_ABSENT;
+ readerStateTmp &= ~SCARD_PRESENT;
+ readerStateTmp &= ~SCARD_POWERED;
+ readerStateTmp &= ~SCARD_NEGOTIABLE;
+ readerStateTmp &= ~SCARD_SPECIFIC;
+ readerStateTmp &= ~SCARD_SWALLOWED;
+ readerStateTmp |= SCARD_UNKNOWN;
+ rs->xcardAtrLength(0);
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
+ rs->xreaderState(readerStateTmp);
+
+ dwCurrentState = SCARD_UNKNOWN;
+
+ SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
+
+ /*
+ * This code causes race conditions on G4's with USB
+ * insertion
+ */
+ /*
+ * dwErrorCount += 1; SYS_Sleep(1);
+ */
+ /*
+ * After 10 seconds of errors, try to reinitialize the reader
+ * This sometimes helps bring readers out of *crazy* states.
+ */
+ /*
+ * if ( dwErrorCount == 10 ) { RFUnInitializeReader( rContext
+ * ); RFInitializeReader( rContext ); dwErrorCount = 0; }
+ */
+
+ /*
+ * End of race condition code block
+ */
+ }
+
+ if (dwStatus & SCARD_ABSENT)
+ {
+ if (dwCurrentState == SCARD_PRESENT ||
+ dwCurrentState == SCARD_UNKNOWN)
+ {
+ /*
+ * Change the status structure
+ */
+ Log2(PCSC_LOG_INFO, "Card Removed From %s", lpcReader);
+ /*
+ * Notify the card has been removed
+ */
+ RFSetReaderEventState(rContext, SCARD_REMOVED);
+
+ rs->xcardAtrLength(0);
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
+ DWORD readerStateTmp = rs->xreaderState();
+ readerStateTmp |= SCARD_ABSENT;
+ readerStateTmp &= ~SCARD_UNKNOWN;
+ readerStateTmp &= ~SCARD_PRESENT;
+ readerStateTmp &= ~SCARD_POWERED;
+ readerStateTmp &= ~SCARD_NEGOTIABLE;
+ readerStateTmp &= ~SCARD_SWALLOWED;
+ readerStateTmp &= ~SCARD_SPECIFIC;
+ rs->xreaderState(readerStateTmp);
+ dwCurrentState = SCARD_ABSENT;
+
+ SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
+ }
+
+ }
+ else if (dwStatus & SCARD_PRESENT)
+ {
+ if (dwCurrentState == SCARD_ABSENT ||
+ dwCurrentState == SCARD_UNKNOWN)
+ {
+ /*
+ * Power and reset the card
+ */
+ SYS_USleep(PCSCLITE_STATUS_WAIT);
+ DWORD tmpCardAtrLength = MAX_ATR_SIZE;
+ rv = IFDPowerICC(rContext, IFD_POWER_UP, rs->xcardAtr(), &tmpCardAtrLength);
+
+ /* the protocol is unset after a power on */
+ rs->xcardProtocol(SCARD_PROTOCOL_UNSET);
+
+ secdebug("pcscd", "EHStatusHandlerThread: power-and-reset call to IFDPowerICC: %d [%04X]", rv, rv);
+
+ DWORD readerStateTmp = rs->xreaderState();
+ if (rv == IFD_SUCCESS)
+ {
+ rs->xcardAtrLength(tmpCardAtrLength);
+
+ readerStateTmp |= SCARD_PRESENT;
+ readerStateTmp &= ~SCARD_ABSENT;
+ readerStateTmp |= SCARD_POWERED;
+ readerStateTmp |= SCARD_NEGOTIABLE;
+ readerStateTmp &= ~SCARD_SPECIFIC;
+ readerStateTmp &= ~SCARD_UNKNOWN;
+ readerStateTmp &= ~SCARD_SWALLOWED;
+ rs->xreaderState(readerStateTmp);
+
+ /*
+ * Notify the card has been reset
+ */
+ RFSetReaderEventState(rContext, SCARD_RESET);
+ }
+ else
+ {
+ readerStateTmp |= SCARD_PRESENT;
+ readerStateTmp &= ~SCARD_ABSENT;
+ readerStateTmp |= SCARD_SWALLOWED;
+ readerStateTmp &= ~SCARD_POWERED;
+ readerStateTmp &= ~SCARD_NEGOTIABLE;
+ readerStateTmp &= ~SCARD_SPECIFIC;
+ readerStateTmp &= ~SCARD_UNKNOWN;
+ rs->xreaderState(readerStateTmp);
+ rs->xcardAtrLength(0);
+ }
+
+ dwCurrentState = SCARD_PRESENT;
+
+ SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
+
+ Log2(PCSC_LOG_INFO, "Card inserted into %s", lpcReader);
+
+ if (rv == IFD_SUCCESS)
+ {
+ if (rs->xcardAtrLength() > 0)
+ LogXxd(PCSC_LOG_INFO, "Card ATR: ", rs->xcardAtr(), rs->xcardAtrLength());
+ else
+ Log1(PCSC_LOG_INFO, "Card ATR: (NULL)");
+ }
+ else
+ Log1(PCSC_LOG_ERROR,"Error powering up card.");
+ }
+ }
+
+ if (ReaderContextIsLocked(rContext))
+ {
+ /*
+ * Exit and notify the caller
+ */
+ secdebug("pcscd", "EHStatusHandlerThread: parent requested shutdown");
+ ReaderContextUnlock(rContext);
+ SYS_ThreadDetach(rContext->pthThread);
+ SYS_ThreadExit(0);
+ }
+
+ /*
+ * Sharing may change w/o an event pass it on
+ */
+
+ if (dwReaderSharing != (uint32_t)rContext->dwContexts)
+ {
+ dwReaderSharing = rContext->dwContexts;
+ rs->sharing(dwReaderSharing);
+ SYS_MMapSynchronize((void *) rContext->readerState, pageSize);
+ }
+
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE);
+ }
+}
+
+void EHSetSharingEvent(PREADER_CONTEXT rContext, DWORD dwValue)
+{
+ PCSCD::SharedReaderState *rs = PCSCD::SharedReaderState::overlay(rContext->readerState);
+ rs->xlockState(dwValue);
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/eventhandler.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * eventhandler.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 2004
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: eventhandler.h 2151 2006-09-06 20:02:47Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles card insertion/removal events, updates ATR,
+ * protocol, and status information.
+ */
+
+#ifndef __eventhandler_h__
+#define __eventhandler_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /**
+ * Define an exported public reader state structure so each
+ * application gets instant notification of changes in state.
+ */
+ typedef struct pubReaderStatesList
+ {
+ LONG readerID;
+ char readerName[MAX_READERNAME];
+ DWORD readerState;
+ LONG readerSharing;
+ DWORD lockState;
+
+ UCHAR cardAtr[MAX_ATR_SIZE];
+ DWORD cardAtrLength;
+ DWORD cardProtocol;
+ }
+ READER_STATE, *PREADER_STATE;
+
+ LONG EHInitializeEventStructures(void);
+ LONG EHSpawnEventHandler(PREADER_CONTEXT);
+ LONG EHDestroyEventHandler(PREADER_CONTEXT);
+ void EHSetSharingEvent(PREADER_CONTEXT, DWORD);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __eventhandler_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * hotplug.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2000-2003
+ * David Corcoran <corcoran at linuxnet.com>
+ *
+ * $Id: hotplug.h 2310 2007-01-06 21:14:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This provides a search API for hot pluggble devices.
+ */
+
+#ifndef __hotplug_h__
+#define __hotplug_h__
+
+#include "pthread.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define PCSCLITE_HP_BASE_PORT 0x200000
+
+ LONG HPSearchHotPluggables();
+ LONG HPRegisterForHotplugEvents();
+ LONG HPStopHotPluggables(void);
+ void HPReCheckSerialReaders(void);
+ int SendHotplugSignal(void);
+
+ LONG HPRegisterForHotplugEventsT(pthread_t *wthread);
+
+ void systemAwakeAndReadyCheck();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : hotplug_macosx.c
+ Package: pcsc lite
+ Author : Stephen M. Webb <stephenw at cryptocard.com>
+ Date : 03 Dec 2002
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This provides a search API for hot pluggble
+ devices.
+
+********************************************************************/
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOCFPlugIn.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/usb/IOUSBLib.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "debuglog.h"
+#include "hotplug.h"
+#include "readerfactory.h"
+#include "thread_generic.h"
+
+#define PCSCLITE_HP_DROPDIR "/usr/libexec/SmartCardServices/drivers/"
+#define PCSCLITE_HP_MANUKEY_NAME "ifdVendorID"
+#define PCSCLITE_HP_PRODKEY_NAME "ifdProductID"
+#define PCSCLITE_HP_NAMEKEY_NAME "ifdFriendlyName"
+#define PCSCLITE_HP_IFACECLASSKEY_NAME "ifdInterfaceClass"
+#define PCSCLITE_HP_IFACESUBCLASSKEY_NAME "ifdInterfaceSubClass"
+#define PCSCLITE_HP_IFACEPROTOCOLKEY_NAME "ifdInterfaceProtocol"
+#define PCSCLITE_HP_BASE_PORT 0x200000
+
+
+/*
+ * Defines the type of driver in the driver vector
+ */
+typedef enum
+{
+ PCSCLITE_HP_Proprietary = 0,
+ PCSCLITE_HP_InterfaceClass = 1,
+ // * Could accomodate more types */
+} HPDriverType;
+
+
+
+/*
+ * An aggregation of useful information on a driver bundle in the
+ * drop directory.
+ */
+typedef struct HPDriver
+{
+ UInt8 m_NotEOV; /* set to 1 for any driver before the end */
+ UInt8 m_initialized; /* set to 1 on successful intialization */
+ HPDriverType m_type; /* type of the driver in this element */
+ UInt32 m_vendorId; /* unique vendor's manufacturer code */
+ UInt32 m_productId; /* manufacturer's unique product code */
+ UInt8 m_class; /* class of a non product specific driver */
+ UInt8 m_subClass; /* subClass of a non product specific driver */
+ UInt8 m_protocol; /* protocol of a non product specific driver */
+ char* m_friendlyName; /* bundle friendly name */
+ char* m_libPath; /* bundle's plugin library location */
+} HPDriver, *HPDriverVector;
+
+/*
+ * An aggregation on information on currently active reader drivers.
+ */
+typedef struct HPDevice
+{
+ HPDriver* m_driver; /* driver bundle information */
+ UInt32 m_address; /* unique system address of device */
+ struct HPDevice* m_next; /* next device in list */
+} HPDevice, *HPDeviceList;
+
+/*
+ * Pointer to a list of (currently) known hotplug reader devices (and their
+ * drivers).
+ */
+static HPDeviceList sDeviceList = NULL;
+static IONotificationPortRef sNotificationPort = NULL;
+static io_iterator_t sUSBAppearedIter = NULL;
+static io_iterator_t sUSBRemovedIter = NULL;
+static io_iterator_t sPCCardAppearedIter = NULL;
+static io_iterator_t sPCCardRemovedIter = NULL;
+
+/*
+ * A callback to handle the asynchronous appearance of new devices that are
+ * candidates for PCSC readers.
+ */
+static void
+HPDeviceAppeared(void* refCon, io_iterator_t iterator)
+{
+ kern_return_t kret;
+ io_service_t obj;
+ while ((obj = IOIteratorNext(iterator)))
+ {
+ kret = IOObjectRelease(obj);
+ }
+
+ HPSearchHotPluggables();
+}
+
+/*
+ * A callback to handle the asynchronous disappearance of devices that are
+ * possibly PCSC readers.
+ */
+static void
+HPDeviceDisappeared(void* refCon, io_iterator_t iterator)
+{
+ kern_return_t kret;
+ io_service_t obj;
+ while ((obj = IOIteratorNext(iterator)))
+ {
+ kret = IOObjectRelease(obj);
+ }
+ HPSearchHotPluggables();
+}
+
+
+/*
+ * Creates a vector of driver bundle info structures from the hot-plug driver
+ * directory.
+ *
+ * Returns NULL on error and a pointer to an allocated HPDriver vector on
+ * success. The caller must free the HPDriver with a call to
+ * HPDriversRelease().
+ */
+static HPDriverVector
+HPDriversGetFromDirectory(const char* driverBundlePath)
+{
+ HPDriverVector bundleVector = NULL;
+ CFArrayRef bundleArray;
+ CFStringRef driverBundlePathString;
+ driverBundlePathString = CFStringCreateWithCString(kCFAllocatorDefault,
+ driverBundlePath,
+ kCFStringEncodingMacRoman);
+ CFURLRef pluginUrl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
+ driverBundlePathString,
+ kCFURLPOSIXPathStyle, TRUE);
+ CFRelease(driverBundlePathString);
+ if (!pluginUrl)
+ {
+ DebugLogA("error getting plugin directory URL");
+ return bundleVector;
+ }
+ bundleArray = CFBundleCreateBundlesFromDirectory(kCFAllocatorDefault,
+ pluginUrl,
+ NULL);
+ if (!bundleArray)
+ {
+ DebugLogA("error getting plugin directory bundles");
+ return bundleVector;
+ }
+ CFRelease(pluginUrl);
+
+ size_t bundleArraySize = CFArrayGetCount(bundleArray);
+ // bundleArraySize + 1 <- because the last vector element is
+ // blank and is used to determine the length (m_NotEOV == 0)
+ bundleVector = (HPDriver*)calloc(bundleArraySize + 1, sizeof(HPDriver));
+ if (!bundleVector)
+ {
+ DebugLogA("memory allocation failure");
+ return bundleVector;
+ }
+
+ int i = 0;
+ for (; i < bundleArraySize; ++i)
+ {
+ HPDriver* driverBundle = bundleVector + i;
+ // This is not the last
+ driverBundle->m_NotEOV = 1;
+ CFBundleRef currBundle = (CFBundleRef)CFArrayGetValueAtIndex(bundleArray, i);
+ CFDictionaryRef dict = CFBundleGetInfoDictionary(currBundle);
+
+ CFURLRef bundleUrl = CFBundleCopyBundleURL(currBundle);
+ CFStringRef bundlePath = CFURLCopyPath(bundleUrl);
+ driverBundle->m_libPath = strdup(CFStringGetCStringPtr(bundlePath,
+ CFStringGetSystemEncoding()));
+ if (driverBundle->m_libPath == NULL)
+ {
+ DebugLogA("memory allocation failure");
+ return bundleVector;
+ }
+ UInt32 vendorId = 0;
+ UInt8 gotVendorId = 0;
+ UInt32 productId = 0;
+ UInt8 gotProductId = 0;
+
+ CFStringRef strValue = (CFStringRef)CFDictionaryGetValue(dict,
+ CFSTR(PCSCLITE_HP_MANUKEY_NAME));
+ if (strValue)
+ {
+ gotVendorId = 1;
+ vendorId = strtoul(CFStringGetCStringPtr(strValue,
+ CFStringGetSystemEncoding()),
+ NULL, 16);
+
+ strValue = (CFStringRef)CFDictionaryGetValue(dict,
+ CFSTR(PCSCLITE_HP_PRODKEY_NAME));
+ if (strValue)
+ {
+ gotProductId = 1;
+ productId = strtoul(CFStringGetCStringPtr(strValue,
+ CFStringGetSystemEncoding()),
+ NULL, 16);
+ }
+ }
+ if (gotVendorId && gotProductId)
+ {
+ /* This is a product-specific driver */
+ driverBundle->m_productId = productId;
+ driverBundle->m_vendorId = vendorId;
+ driverBundle->m_type = PCSCLITE_HP_Proprietary;
+ }
+ else
+ {
+ /* If not a product-specific driver, it must be */
+ /* an interface class-specifc driver */
+ UInt8 class;
+ UInt8 subClass;
+ UInt8 protocol;
+
+ strValue = (CFStringRef)CFDictionaryGetValue(dict,
+ CFSTR(PCSCLITE_HP_IFACECLASSKEY_NAME));
+ if (strValue)
+ {
+ class = (UInt8) strtoul(CFStringGetCStringPtr(strValue,
+ CFStringGetSystemEncoding()),
+ NULL, 16);
+ driverBundle->m_class = class;
+ }
+ else
+ {
+ DebugLogB("Malformed bundle (class absent) in driver folder: %s. Will be ignored",
+ driverBundle->m_libPath);
+ free(driverBundle->m_libPath);
+ driverBundle->m_libPath = NULL;
+ continue;
+ }
+ strValue = (CFStringRef)CFDictionaryGetValue(dict,
+ CFSTR(PCSCLITE_HP_IFACESUBCLASSKEY_NAME));
+ if (strValue)
+ {
+ subClass = (UInt8) strtoul(CFStringGetCStringPtr(strValue,
+ CFStringGetSystemEncoding()),
+ NULL, 16);
+ driverBundle->m_subClass = subClass;
+ }
+ else
+ {
+ DebugLogB("Malformed bundle (subClass absent) in driver folder: %s. Will be ignored",
+ driverBundle->m_libPath);
+ free(driverBundle->m_libPath);
+ driverBundle->m_libPath = NULL;
+ continue;
+ }
+ strValue = (CFStringRef)CFDictionaryGetValue(dict,
+ CFSTR(PCSCLITE_HP_IFACEPROTOCOLKEY_NAME));
+ if (strValue)
+ {
+ protocol = (UInt8) strtoul(CFStringGetCStringPtr(strValue,
+ CFStringGetSystemEncoding()),
+ NULL, 16);
+ driverBundle->m_protocol = protocol;
+ }
+ else
+ {
+ DebugLogB("Malformed bundle (protocol absent) in driver folder: %s. Will be ignored",
+ driverBundle->m_libPath);
+ free(driverBundle->m_libPath);
+ driverBundle->m_libPath = NULL;
+ continue;
+ }
+ driverBundle->m_type = PCSCLITE_HP_InterfaceClass;
+ }
+ strValue = (CFStringRef)CFDictionaryGetValue(dict,
+ CFSTR(PCSCLITE_HP_NAMEKEY_NAME));
+ if (!strValue)
+ {
+ DebugLogB("Product friendly name absent in driver folder: %s.",
+ driverBundle->m_libPath);
+ driverBundle->m_friendlyName = strdup("unnamed device");
+ }
+ else
+ {
+ const char* cstr = CFStringGetCStringPtr(strValue,
+ CFStringGetSystemEncoding());
+ driverBundle->m_friendlyName = strdup(cstr);
+ }
+ driverBundle->m_initialized = 1;
+ }
+ CFRelease(bundleArray);
+ return bundleVector;
+}
+
+/*
+ * Copies a driver bundle instance.
+ */
+static HPDriver*
+HPDriverCopy(HPDriver* rhs)
+{
+ if (!rhs)
+ {
+ return NULL;
+ }
+ HPDriver* newDriverBundle = (HPDriver*)calloc(1, sizeof(HPDriver));
+ if (!newDriverBundle)
+ {
+ return NULL;
+ }
+
+ newDriverBundle->m_initialized = rhs->m_initialized;
+ newDriverBundle->m_type = rhs->m_type;
+ newDriverBundle->m_vendorId = rhs->m_vendorId;
+ newDriverBundle->m_productId = rhs->m_productId;
+
+ newDriverBundle->m_class = rhs->m_class;
+ newDriverBundle->m_subClass = rhs->m_subClass;
+ newDriverBundle->m_friendlyName = strdup(rhs->m_friendlyName);
+ newDriverBundle->m_libPath = strdup(rhs->m_libPath);
+ if (newDriverBundle->m_friendlyName == NULL)
+ {
+ if (newDriverBundle->m_libPath != NULL)
+ {
+ free(newDriverBundle->m_libPath);
+ }
+ free(newDriverBundle);
+ return NULL;
+ }
+
+ if (newDriverBundle->m_libPath == NULL)
+ {
+ if (newDriverBundle->m_friendlyName != NULL)
+ {
+ free(newDriverBundle->m_friendlyName);
+ }
+ free(newDriverBundle);
+ return NULL;
+ }
+ return newDriverBundle;
+}
+
+/*
+ * Releases resources allocated to a driver bundle vector.
+ */
+static void
+HPDriverRelease(HPDriver* driverBundle)
+{
+ if (driverBundle)
+ {
+ free(driverBundle->m_friendlyName);
+ free(driverBundle->m_libPath);
+ }
+}
+
+/*
+ * Releases resources allocated to a driver bundle vector.
+ */
+static void
+HPDriverVectorRelease(HPDriverVector driverBundleVector)
+{
+ if (driverBundleVector)
+ {
+ HPDriver* b = driverBundleVector;
+ for (; b->m_initialized; ++b)
+ {
+ HPDriverRelease(b);
+ }
+ free(driverBundleVector);
+ }
+}
+
+/*
+ * Inserts a new reader device in the list.
+ */
+static HPDeviceList
+HPDeviceListInsert(HPDeviceList list, HPDriver* bundle, UInt32 address)
+{
+ HPDevice* newReader = (HPDevice*)calloc(1, sizeof(HPDevice));
+ if (!newReader)
+ {
+ DebugLogA("memory allocation failure");
+ return list;
+ }
+ newReader->m_driver = HPDriverCopy(bundle);
+ newReader->m_address = address;
+ newReader->m_next = list;
+ return newReader;
+}
+
+/*
+ * Frees resources allocated to a HPDeviceList.
+ */
+static void
+HPDeviceListRelease(HPDeviceList list)
+{
+ HPDevice* p = list;
+ for (; p; p = p->m_next)
+ {
+ HPDriverRelease(p->m_driver);
+ }
+}
+
+/*
+ * Compares two driver bundle instances for equality.
+ */
+static int
+HPDeviceEquals(HPDevice* a, HPDevice* b)
+{
+ int res;
+ if (a->m_driver->m_type == b->m_driver->m_type)
+ {
+ if (a->m_driver->m_type == PCSCLITE_HP_Proprietary)
+ {
+ // a and b have same vendor and product id
+ res = (a->m_driver->m_vendorId == b->m_driver->m_vendorId)
+ && (a->m_driver->m_productId == b->m_driver->m_productId);
+ }
+ else
+ {
+ // a and b have same class
+ res = (a->m_driver->m_subClass == b->m_driver->m_subClass)
+ && (a->m_driver->m_class == b->m_driver->m_class);
+ }
+ // AND have the same address
+ res = res && (a->m_address == b->m_address);
+
+ return res;
+ }
+ return 0;
+}
+
+/*
+ * Finds USB devices currently registered in the system that match any of
+ * the drivers detected in the driver bundle vector.
+ */
+static int
+HPDriversMatchUSBDevices(HPDriverVector driverBundle, HPDeviceList* readerList)
+{
+ CFDictionaryRef usbMatch = IOServiceMatching("IOUSBDevice");
+ if (0 == usbMatch)
+ {
+ DebugLogA("error getting USB match from IOServiceMatching()");
+ return 1;
+ }
+
+ io_iterator_t usbIter;
+ kern_return_t kret = IOServiceGetMatchingServices(kIOMasterPortDefault,
+ usbMatch,
+ &usbIter);
+ if (kret != 0)
+ {
+ DebugLogA("error getting iterator from IOServiceGetMatchingServices()");
+ return 1;
+ }
+
+ io_object_t usbDevice = 0;
+ while ((usbDevice = IOIteratorNext(usbIter)))
+ {
+ IOCFPlugInInterface** iodev;
+ SInt32 score;
+ kret = IOCreatePlugInInterfaceForService(usbDevice,
+ kIOUSBDeviceUserClientTypeID,
+ kIOCFPlugInInterfaceID,
+ &iodev,
+ &score);
+ IOObjectRelease(usbDevice);
+ if (kret != 0)
+ {
+ DebugLogA("error getting plugin interface from IOCreatePlugInInterfaceForService()");
+ continue;
+ }
+
+ IOUSBDeviceInterface245** usbdev;
+ HRESULT hres = (*iodev)->QueryInterface(iodev,
+ CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID245),
+ (LPVOID*)&usbdev);
+ if (hres)
+ {
+ DebugLogA("error querying interface in QueryInterface()");
+ IODestroyPlugInInterface ( iodev );
+ continue;
+ }
+
+ else
+ {
+
+ UInt16 vendorId = 0;
+ UInt16 productId = 0;
+ UInt32 usbAddress = 0;
+ kret = (*usbdev)->GetDeviceVendor(usbdev, &vendorId);
+ kret = (*usbdev)->GetDeviceProduct(usbdev, &productId);
+ kret = (*usbdev)->GetLocationID(usbdev, &usbAddress);
+
+ HPDriver* driver = driverBundle;
+ int match = 0;
+ for (; driver->m_NotEOV; ++driver)
+ {
+ if (!driver->m_initialized)
+ {
+ // Malformed driver, skip
+ continue;
+ }
+ if ( (driver->m_type == PCSCLITE_HP_Proprietary)
+ && (driver->m_vendorId == vendorId)
+ && (driver->m_productId == productId))
+ {
+ *readerList = HPDeviceListInsert(*readerList, driver, usbAddress);
+ match = 1;
+ }
+ }
+ if (!match)
+ {
+ // Now try to locate Interfaces with supported classes
+ // We create an interface iterator for each of the
+ // classes supported by drivers of PCSCLITE_HP_InterfaceClass
+ // type.
+
+ // Using IOServiceMatching(kIOUSBInterfaceClassName)
+ // does not seem feasible as there does not seem to be a
+ // way to limit the search to the device we are currently
+ // analysing
+
+ // Another option would be to iterate on all interfaces
+ // and get the class of each of them. This is probably
+ // not interesting as the list of PCSCLITE_HP_InterfaceClass
+ // type of readers should only have one element (CCID)
+
+ // Restart scan at the begining of the array
+ driver = driverBundle;
+ // Iterate on PCSCLITE_HP_InterfaceClass driver types
+ for (; driver->m_NotEOV; ++driver)
+ {
+ if (!driver->m_initialized)
+ {
+ // Malformed driver, skip
+ continue;
+ }
+ if ( driver->m_type == PCSCLITE_HP_InterfaceClass)
+ {
+ // Iterate on interfaces of the current device
+ IOUSBFindInterfaceRequest interfaceClassRequest;
+ io_iterator_t interfaceIterator;
+ io_service_t interface;
+
+ interfaceClassRequest.bInterfaceClass = driver->m_class;
+ interfaceClassRequest.bInterfaceSubClass = driver->m_subClass;
+ interfaceClassRequest.bInterfaceProtocol = driver->m_protocol;
+ interfaceClassRequest.bAlternateSetting = kIOUSBFindInterfaceDontCare;
+ hres = (*usbdev)->CreateInterfaceIterator(usbdev,
+ &interfaceClassRequest,
+ &interfaceIterator);
+ if (hres)
+ {
+ // Continue to next driver class
+ continue;
+ }
+
+ while ( (interface = IOIteratorNext(interfaceIterator)) )
+ {
+ // Found a matching device
+ *readerList = HPDeviceListInsert(*readerList, driver, usbAddress);
+ match = 1;
+ IOObjectRelease ( interface );
+ }
+
+ IOObjectRelease ( interfaceIterator );
+
+ }
+ }
+ // Add another if (!match) for other driver types
+ }
+ (*usbdev)->Release(usbdev);
+ IODestroyPlugInInterface ( iodev );
+ }
+ }
+
+ IOObjectRelease(usbIter);
+ return 0;
+}
+
+/*
+ * Finds PC Card devices currently registered in the system that match any of
+ * the drivers detected in the driver bundle vector.
+ */
+static int
+HPDriversMatchPCCardDevices(HPDriver* driverBundle, HPDeviceList* readerList)
+{
+ CFDictionaryRef pccMatch = IOServiceMatching("IOPCCard16Device");
+ if (0 == pccMatch)
+ {
+ DebugLogA("error getting PCCard match from IOServiceMatching()");
+ return 1;
+ }
+
+ io_iterator_t pccIter;
+ kern_return_t kret = IOServiceGetMatchingServices(kIOMasterPortDefault, pccMatch, &pccIter);
+ if (kret != 0)
+ {
+ DebugLogA("error getting iterator from IOServiceGetMatchingServices()");
+ return 1;
+ }
+
+ io_object_t pccDevice = 0;
+ while ((pccDevice = IOIteratorNext(pccIter)))
+ {
+
+ UInt32 vendorId = 0;
+ UInt32 productId = 0;
+ UInt32 pccAddress = 0;
+ CFTypeRef valueRef = IORegistryEntryCreateCFProperty(pccDevice, CFSTR("VendorID"),
+ kCFAllocatorDefault, 0);
+ if (!valueRef)
+ {
+ DebugLogA("error getting vendor");
+ }
+ else
+ {
+ CFNumberGetValue((CFNumberRef)valueRef, kCFNumberSInt32Type, &vendorId);
+ CFRelease ( valueRef );
+ }
+ valueRef = IORegistryEntryCreateCFProperty(pccDevice, CFSTR("DeviceID"),
+ kCFAllocatorDefault, 0);
+ if (!valueRef)
+ {
+ DebugLogA("error getting device");
+ }
+ else
+ {
+ CFNumberGetValue((CFNumberRef)valueRef, kCFNumberSInt32Type, &productId);
+ CFRelease ( valueRef );
+ }
+ valueRef = IORegistryEntryCreateCFProperty(pccDevice, CFSTR("SocketNumber"),
+ kCFAllocatorDefault, 0);
+ if (!valueRef)
+ {
+ DebugLogA("error getting PC Card socket");
+ }
+ else
+ {
+ CFNumberGetValue((CFNumberRef)valueRef, kCFNumberSInt32Type, &pccAddress);
+ CFRelease ( valueRef );
+ }
+ HPDriver* driver = driverBundle;
+ for (; driver->m_vendorId; ++driver)
+ {
+ if ((driver->m_vendorId == vendorId)
+ && (driver->m_productId == productId))
+ {
+ *readerList = HPDeviceListInsert(*readerList, driver, pccAddress);
+ }
+ }
+
+ IOObjectRelease ( pccDevice );
+
+ }
+ IOObjectRelease(pccIter);
+ return 0;
+}
+
+
+static void
+HPEstablishUSBNotification()
+{
+
+ CFMutableDictionaryRef matchingDictionary;
+ IOReturn kret;
+
+ if ( sNotificationPort == NULL )
+ sNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(),
+ IONotificationPortGetRunLoopSource(sNotificationPort),
+ kCFRunLoopDefaultMode);
+
+ matchingDictionary = IOServiceMatching("IOUSBDevice");
+ if (!matchingDictionary)
+ {
+ DebugLogB("IOServiceMatching() failed", 0);
+ }
+ matchingDictionary = (CFMutableDictionaryRef)CFRetain(matchingDictionary);
+
+ kret = IOServiceAddMatchingNotification(sNotificationPort,
+ kIOMatchedNotification,
+ matchingDictionary,
+ HPDeviceAppeared, NULL,
+ &sUSBAppearedIter);
+ if (kret)
+ {
+ DebugLogB("IOServiceAddMatchingNotification()-1 failed with code %d", kret);
+ }
+
+ HPDeviceAppeared(NULL, sUSBAppearedIter);
+
+ kret = IOServiceAddMatchingNotification(sNotificationPort,
+ kIOTerminatedNotification,
+ matchingDictionary,
+ HPDeviceDisappeared, NULL,
+ &sUSBRemovedIter);
+ if (kret)
+ {
+ DebugLogB("IOServiceAddMatchingNotification()-2 failed with code %d", kret);
+ }
+ HPDeviceDisappeared(NULL, sUSBRemovedIter);
+}
+
+static void
+HPEstablishPCCardNotification()
+{
+
+ CFMutableDictionaryRef matchingDictionary;
+ IOReturn kret;
+
+ if ( sNotificationPort == NULL )
+ sNotificationPort = IONotificationPortCreate(kIOMasterPortDefault);
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(),
+ IONotificationPortGetRunLoopSource(sNotificationPort),
+ kCFRunLoopDefaultMode);
+
+ matchingDictionary = IOServiceMatching("IOPCCard16Device");
+ if (!matchingDictionary)
+ {
+ DebugLogB("IOServiceMatching() failed", 0);
+ }
+ matchingDictionary = (CFMutableDictionaryRef)CFRetain(matchingDictionary);
+
+ kret = IOServiceAddMatchingNotification(sNotificationPort,
+ kIOMatchedNotification,
+ matchingDictionary,
+ HPDeviceAppeared, NULL,
+ &sPCCardAppearedIter);
+ if (kret)
+ {
+ DebugLogB("IOServiceAddMatchingNotification()-1 failed with code %d", kret);
+ }
+ HPDeviceAppeared(NULL, sPCCardAppearedIter);
+
+ kret = IOServiceAddMatchingNotification(sNotificationPort,
+ kIOTerminatedNotification,
+ matchingDictionary,
+ HPDeviceDisappeared, NULL,
+ &sPCCardRemovedIter);
+ if (kret)
+ {
+ DebugLogB("IOServiceAddMatchingNotification()-2 failed with code %d", kret);
+ }
+ HPDeviceDisappeared(NULL, sPCCardRemovedIter);
+}
+
+/*
+ * Thread runner (does not return).
+ */
+static void
+HPDeviceNotificationThread()
+{
+ HPEstablishUSBNotification();
+ HPEstablishPCCardNotification();
+ CFRunLoopRun();
+}
+
+/*
+ * Scans the hotplug driver directory and looks in the system for matching devices.
+ * Adds or removes matching readers as necessary.
+ */
+LONG
+HPSearchHotPluggables()
+{
+ HPDriver* drivers = HPDriversGetFromDirectory(PCSCLITE_HP_DROPDIR);
+ if (!drivers) return 1;
+
+ HPDeviceList devices = NULL;
+ int istat;
+ istat = HPDriversMatchUSBDevices(drivers, &devices);
+ if (istat)
+ {
+ return -1;
+ }
+ istat = HPDriversMatchPCCardDevices(drivers, &devices);
+ if (istat)
+ {
+ return -1;
+ }
+
+ HPDevice* a = devices;
+ for (; a; a = a->m_next)
+ {
+ int found = 0;
+ HPDevice* b = sDeviceList;
+ for (; b; b = b->m_next)
+ {
+ if (HPDeviceEquals(a, b))
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ RFAddReader(a->m_driver->m_friendlyName,
+ PCSCLITE_HP_BASE_PORT + a->m_address,
+ a->m_driver->m_libPath);
+ }
+ }
+
+ a = sDeviceList;
+ for (; a; a = a->m_next)
+ {
+ int found = 0;
+ HPDevice* b = devices;
+ for (; b; b = b->m_next)
+ {
+ if (HPDeviceEquals(a, b))
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ {
+ RFRemoveReader(a->m_driver->m_friendlyName,
+ PCSCLITE_HP_BASE_PORT + a->m_address);
+ }
+ }
+
+ HPDeviceListRelease(sDeviceList);
+ sDeviceList = devices;
+ HPDriverVectorRelease(drivers);
+ return 0;
+}
+
+
+PCSCLITE_THREAD_T sHotplugWatcherThread;
+
+/*
+ * Sets up callbacks for device hotplug events.
+ */
+LONG
+HPRegisterForHotplugEvents()
+{
+ LONG sstat;
+ sstat = SYS_ThreadCreate(&sHotplugWatcherThread,
+ NULL,
+ (LPVOID)HPDeviceNotificationThread,
+ NULL);
+ return 0;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/hotplug_macosx.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : hotplug_macosx.c
+ Package: pcsc lite
+ Author : Stephen M. Webb <stephenw at cryptocard.com>
+ Date : 03 Dec 2002
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This provides a search API for hot pluggble
+ devices.
+
+********************************************************************/
+
+#include "wintypes.h"
+
+#include "hotplug.h"
+#include "pthread.h"
+#include "PCSCDriverBundles.h"
+#include "pcscdserver.h"
+#include "pcscdmonitor.h"
+#include <security_utilities/debugging.h>
+
+const uint32_t kPCSCLITE_HP_BASE_PORT = 0x200000;
+PCSCDMonitor *gPCSCDMonitor = NULL;
+
+#ifndef HOTPLUGTEST
+ #include "readerfactory.h"
+#else
+LONG RFAddReader(LPSTR, DWORD, LPSTR)
+{
+ return 0;
+}
+
+LONG RFRemoveReader(LPSTR, DWORD)
+{
+ return 0;
+}
+#endif
+
+// See PCSCDMonitor::addDevice for where this is actually called
+
+int32_t WrapRFAddReader(const char *name, uint32_t address, const char *pathLibrary, const char *deviceName)
+{
+ secdebug("device", "RFAddReader: name: %s, address: %04X, pathLibrary: %s, pathDevice: %s", name, address, pathLibrary, deviceName);
+ return RFAddReader(const_cast<char *>(name), kPCSCLITE_HP_BASE_PORT+address, const_cast<char *>(pathLibrary), const_cast<char *>(deviceName));
+}
+
+int32_t WrapRFRemoveReader(const char *name, uint32_t address)
+{
+ secdebug("device", "RFRemoveReader: name: %s, address: %04X", name, address);
+ return RFRemoveReader(const_cast<char *>(name), kPCSCLITE_HP_BASE_PORT+address);
+}
+
+int32_t WrapRFAwakeAllReaders()
+{
+ secdebug("device", "RFAwakeAllReaders");
+ RFAwakeAllReaders();
+ return 0;
+}
+
+int32_t WrapRFSuspendAllReaders()
+{
+ secdebug("device", "RFSuspendAllReaders");
+ RFSuspendAllReaders();
+ return 0;
+}
+
+static void *HPDeviceNotificationThread(void *foo)
+{
+ try
+ {
+ // Thread runner (does not return)
+ PCSCD::DriverBundles bdls;
+ PCSCD::Server myserv("hotplug");
+ PCSCDMonitor xmon(myserv,bdls);
+ gPCSCDMonitor = &xmon;
+ xmon.setCallbacks(WrapRFAddReader, WrapRFRemoveReader, WrapRFSuspendAllReaders, WrapRFAwakeAllReaders);
+ bdls.update();
+ myserv.run();
+ }
+ catch (Security::MachPlusPlus::Error e)
+ {
+ char *perr = (char *)mach_error_string(e.error);
+ if (perr)
+ secdebug("device", "Caught error in xx: %s, error: %04lX", perr, e.osStatus());
+ else
+ secdebug("device", "Caught error in xx: %04X", e.error);
+ }
+ catch (...)
+ {
+ }
+ exit(0);
+ return NULL; // never gets here
+}
+
+void systemAwakeAndReadyCheck()
+{
+ gPCSCDMonitor->systemAwakeAndReadyCheck();
+}
+
+/*
+ * Scans the hotplug driver directory and looks in the system for matching devices.
+ * Adds or removes matching readers as necessary.
+ */
+int32_t HPSearchHotPluggables()
+{
+ // this function is a no-op now
+ return 0;
+}
+
+static pthread_t sHotplugWatcherThread;
+
+int32_t HPRegisterForHotplugEvents()
+{
+ return HPRegisterForHotplugEventsT(&sHotplugWatcherThread);
+}
+
+int32_t HPRegisterForHotplugEventsT(pthread_t *wthread)
+{
+ // Sets up callbacks for device hotplug events
+ int rx = pthread_create(wthread, NULL, HPDeviceNotificationThread, NULL);
+ return rx;
+}
+
+LONG HPStopHotPluggables(void)
+{
+ return 0;
+}
+
+void HPReCheckSerialReaders(void)
+{
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdhandler.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdhandler.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdhandler.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * ifdhandler.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ *
+ * $Id: ifdhandler.h 2348 2007-01-20 15:12:19Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This provides reader specific low-level calls.
+ */
+
+#ifndef _ifd_handler_h_
+#define _ifd_handler_h_
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /*
+ * List of data structures available to ifdhandler
+ */
+
+ typedef struct _DEVICE_CAPABILITIES
+ {
+ LPSTR Vendor_Name; /* Tag 0x0100 */
+ LPSTR IFD_Type; /* Tag 0x0101 */
+ DWORD IFD_Version; /* Tag 0x0102 */
+ LPSTR IFD_Serial; /* Tag 0x0103 */
+ DWORD IFD_Channel_ID; /* Tag 0x0110 */
+
+ DWORD Asynch_Supported; /* Tag 0x0120 */
+ DWORD Default_Clock; /* Tag 0x0121 */
+ DWORD Max_Clock; /* Tag 0x0122 */
+ DWORD Default_Data_Rate; /* Tag 0x0123 */
+ DWORD Max_Data_Rate; /* Tag 0x0124 */
+ DWORD Max_IFSD; /* Tag 0x0125 */
+ DWORD Synch_Supported; /* Tag 0x0126 */
+ DWORD Power_Mgmt; /* Tag 0x0131 */
+ DWORD Card_Auth_Devices; /* Tag 0x0140 */
+ DWORD User_Auth_Device; /* Tag 0x0142 */
+ DWORD Mechanics_Supported; /* Tag 0x0150 */
+ DWORD Vendor_Features; /* Tag 0x0180 - 0x01F0 User Defined. */
+ }
+ DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;
+
+ typedef struct _ICC_STATE
+ {
+ UCHAR ICC_Presence; /* Tag 0x0300 */
+ UCHAR ICC_Interface_Status; /* Tag 0x0301 */
+ UCHAR ATR[MAX_ATR_SIZE]; /* Tag 0x0303 */
+ UCHAR ICC_Type; /* Tag 0x0304 */
+ }
+ ICC_STATE, *PICC_STATE;
+
+ typedef struct _PROTOCOL_OPTIONS
+ {
+ DWORD Protocol_Type; /* Tag 0x0201 */
+ DWORD Current_Clock; /* Tag 0x0202 */
+ DWORD Current_F; /* Tag 0x0203 */
+ DWORD Current_D; /* Tag 0x0204 */
+ DWORD Current_N; /* Tag 0x0205 */
+ DWORD Current_W; /* Tag 0x0206 */
+ DWORD Current_IFSC; /* Tag 0x0207 */
+ DWORD Current_IFSD; /* Tag 0x0208 */
+ DWORD Current_BWT; /* Tag 0x0209 */
+ DWORD Current_CWT; /* Tag 0x020A */
+ DWORD Current_EBC; /* Tag 0x020B */
+ }
+ PROTOCOL_OPTIONS, *PPROTOCOL_OPTIONS;
+
+ typedef struct _SCARD_IO_HEADER
+ {
+ DWORD Protocol;
+ DWORD Length;
+ }
+ SCARD_IO_HEADER, *PSCARD_IO_HEADER;
+
+ /*
+ * End of structure list
+ */
+
+ /*
+ * The list of tags should be alot more but this is all I use in the
+ * meantime
+ */
+
+#define TAG_IFD_ATR 0x0303
+#define TAG_IFD_SLOTNUM 0x0180
+#define TAG_IFD_SLOT_THREAD_SAFE 0x0FAC
+#define TAG_IFD_THREAD_SAFE 0x0FAD
+#define TAG_IFD_SLOTS_NUMBER 0x0FAE
+#define TAG_IFD_SIMULTANEOUS_ACCESS 0x0FAF
+
+ /*
+ * End of tag list
+ */
+
+ /*
+ * IFD Handler version number enummerations
+ */
+#define IFD_HVERSION_1_0 0x00010000
+#define IFD_HVERSION_2_0 0x00020000
+#define IFD_HVERSION_3_0 0x00030000
+ /*
+ * End of version number enummerations
+ */
+
+ /*
+ * List of defines available to ifdhandler
+ */
+
+#define IFD_POWER_UP 500
+#define IFD_POWER_DOWN 501
+#define IFD_RESET 502
+
+#define IFD_NEGOTIATE_PTS1 1
+#define IFD_NEGOTIATE_PTS2 2
+#define IFD_NEGOTIATE_PTS3 4
+
+#define IFD_SUCCESS 0
+#define IFD_ERROR_TAG 600
+#define IFD_ERROR_SET_FAILURE 601
+#define IFD_ERROR_VALUE_READ_ONLY 602
+#define IFD_ERROR_PTS_FAILURE 605
+#define IFD_ERROR_NOT_SUPPORTED 606
+#define IFD_PROTOCOL_NOT_SUPPORTED 607
+#define IFD_ERROR_POWER_ACTION 608
+#define IFD_ERROR_SWALLOW 609
+#define IFD_ERROR_EJECT 610
+#define IFD_ERROR_CONFISCATE 611
+#define IFD_COMMUNICATION_ERROR 612
+#define IFD_RESPONSE_TIMEOUT 613
+#define IFD_NOT_SUPPORTED 614
+#define IFD_ICC_PRESENT 615
+#define IFD_ICC_NOT_PRESENT 616
+#define IFD_NO_SUCH_DEVICE 617
+
+// typedef long RESPONSECODE;
+
+ /*
+ * If you want to compile a V2.0 IFDHandler, define IFDHANDLERv2 before you
+ * include this file.
+ *
+ * By default it is setup for for most recent version of the API (V3.0)
+ */
+
+#ifndef IFDHANDLERv2
+
+ /*
+ * List of Defined Functions Available to IFD_Handler 3.0
+ *
+ * All the functions of IFD_Handler 2.0 are available
+ * IFDHCreateChannelByName() is new
+ * IFDHControl() API changed
+ */
+
+ RESPONSECODE IFDHCreateChannelByName(DWORD, LPSTR);
+ RESPONSECODE IFDHControl(DWORD, DWORD, PUCHAR, DWORD, PUCHAR,
+ DWORD, LPDWORD);
+#else
+
+ /*
+ * List of Defined Functions Available to IFD_Handler 2.0
+ */
+
+ RESPONSECODE IFDHControl(DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
+
+#endif
+
+ /*
+ * common functions in IFD_Handler 2.0 and 3.0
+ */
+ RESPONSECODE IFDHCreateChannel(DWORD, DWORD);
+ RESPONSECODE IFDHCloseChannel(DWORD);
+ RESPONSECODE IFDHGetCapabilities(DWORD, DWORD, PDWORD, PUCHAR);
+ RESPONSECODE IFDHSetCapabilities(DWORD, DWORD, DWORD, PUCHAR);
+ RESPONSECODE IFDHSetProtocolParameters(DWORD, DWORD, UCHAR,
+ UCHAR, UCHAR, UCHAR);
+ RESPONSECODE IFDHPowerICC(DWORD, DWORD, PUCHAR, PDWORD);
+ RESPONSECODE IFDHTransmitToICC(DWORD, SCARD_IO_HEADER, PUCHAR,
+ DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER);
+ RESPONSECODE IFDHICCPresence(DWORD);
+
+ /*
+ * List of Defined Functions Available to IFD_Handler 1.0
+ */
+
+ RESPONSECODE IO_Create_Channel(DWORD);
+ RESPONSECODE IO_Close_Channel();
+ RESPONSECODE IFD_Get_Capabilities(DWORD, PUCHAR);
+ RESPONSECODE IFD_Set_Capabilities(DWORD, PUCHAR);
+ RESPONSECODE IFD_Set_Protocol_Parameters(DWORD, UCHAR, UCHAR,
+ UCHAR, UCHAR);
+ RESPONSECODE IFD_Power_ICC(DWORD);
+ RESPONSECODE IFD_Swallow_ICC();
+ RESPONSECODE IFD_Eject_ICC();
+ RESPONSECODE IFD_Confiscate_ICC();
+ RESPONSECODE IFD_Transmit_to_ICC(SCARD_IO_HEADER, PUCHAR, DWORD,
+ PUCHAR, PDWORD, PSCARD_IO_HEADER);
+ RESPONSECODE IFD_Is_ICC_Present();
+ RESPONSECODE IFD_Is_ICC_Absent();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,807 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * ifdwrapper.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: ifdwrapper.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This wraps the dynamic ifdhandler functions.
+ */
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "ifdhandler.h"
+#include "debuglog.h"
+#include "readerfactory.h"
+#include "ifdwrapper.h"
+#include "atrhandler.h"
+#include "dyn_generic.h"
+#include "sys_generic.h"
+
+#include <security_utilities/debugging.h>
+
+#undef PCSCLITE_STATIC_DRIVER
+
+/*
+ * Function: IFDSetPTS Purpose : To set the protocol type selection (PTS).
+ * This function sets the appropriate protocol to be used on the card.
+ */
+
+LONG IFDSetPTS(PREADER_CONTEXT rContext, DWORD dwProtocol, UCHAR ucFlags,
+ UCHAR ucPTS1, UCHAR ucPTS2, UCHAR ucPTS3)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+ UCHAR ucValue[1];
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFD_set_protocol_parameters) (DWORD, UCHAR, UCHAR,
+ UCHAR, UCHAR) = NULL;
+ RESPONSECODE(*IFDH_set_protocol_parameters) (DWORD, DWORD, UCHAR,
+ UCHAR, UCHAR, UCHAR) = NULL;
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ IFD_set_protocol_parameters = (RESPONSECODE(*)(DWORD, UCHAR, UCHAR,
+ UCHAR, UCHAR)) rContext->psFunctions.psFunctions_v1.pvfSetProtocolParameters;
+
+ if (NULL == IFD_set_protocol_parameters)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+ }
+ else
+ {
+ IFDH_set_protocol_parameters = (RESPONSECODE(*)(DWORD, DWORD, UCHAR,
+ UCHAR, UCHAR, UCHAR))
+ rContext->psFunctions.psFunctions_v2.pvfSetProtocolParameters;
+
+ if (NULL == IFDH_set_protocol_parameters)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+ }
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+ SYS_MutexLock(rContext->mMutex);
+
+ ucValue[0] = rContext->dwSlot;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = (*IFD_set_protocol_parameters) (dwProtocol,
+ ucFlags, ucPTS1, ucPTS2, ucPTS3);
+ }
+ else
+ {
+ rv = (*IFDH_set_protocol_parameters) (rContext->dwSlot,
+ dwProtocol,
+ ucFlags, ucPTS1,
+ ucPTS2, ucPTS3);
+ }
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = IFD_Set_Protocol_Parameters(dwProtocol, ucFlags, ucPTS1,
+ ucPTS2, ucPTS3);
+ }
+ else
+ {
+ rv = IFDHSetProtocolParameters(rContext->dwSlot, dwProtocol,
+ ucFlags, ucPTS1, ucPTS2, ucPTS3);
+ }
+#endif
+
+ SYS_MutexUnLock(rContext->mMutex);
+ /*
+ * END OF LOCKED REGION
+ */
+
+ return rv;
+}
+
+/*
+ * Function: IFDOpenIFD Purpose : This function opens a communication
+ * channel to the IFD.
+ */
+
+LONG IFDOpenIFD(PREADER_CONTEXT rContext)
+{
+ RESPONSECODE rv = 0;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IO_create_channel) (DWORD) = NULL;
+ RESPONSECODE(*IFDH_create_channel) (DWORD, DWORD) = NULL;
+ RESPONSECODE(*IFDH_create_channel_by_name) (DWORD, LPSTR) = NULL;
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IO_create_channel =
+ rContext->psFunctions.psFunctions_v1.pvfCreateChannel;
+ else
+ if (rContext->dwVersion == IFD_HVERSION_2_0)
+ IFDH_create_channel =
+ rContext->psFunctions.psFunctions_v2.pvfCreateChannel;
+ else
+ {
+ IFDH_create_channel =
+ rContext->psFunctions.psFunctions_v3.pvfCreateChannel;
+ IFDH_create_channel_by_name =
+ rContext->psFunctions.psFunctions_v3.pvfCreateChannelByName;
+ }
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ rv = (*IO_create_channel) (rContext->dwPort);
+ } else if (rContext->dwVersion == IFD_HVERSION_2_0)
+ {
+ rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
+ } else
+ {
+ /* use device name only if defined */
+ if (rContext->lpcDevice[0] != '\0')
+ rv = (*IFDH_create_channel_by_name) (rContext->dwSlot, rContext->lpcDevice);
+ else
+ rv = (*IFDH_create_channel) (rContext->dwSlot, rContext->dwPort);
+ }
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ rv = IO_Create_Channel(rContext->dwPort);
+ } else if (rContext->dwVersion == IFD_HVERSION_2_0)
+ {
+ rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
+ } else
+ {
+ /* Use device name only if defined */
+ if (rContext->lpcDevice[0] != '\0')
+ rv = IFDHCreateChannelByName(rContext->dwSlot, rContext->lpcDevice);
+ else
+ rv = IFDHCreateChannel(rContext->dwSlot, rContext->dwPort);
+ }
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ return rv;
+}
+
+/*
+ * Function: IFDCloseIFD Purpose : This function closes a communication
+ * channel to the IFD.
+ */
+
+LONG IFDCloseIFD(PREADER_CONTEXT rContext)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IO_close_channel) () = NULL;
+ RESPONSECODE(*IFDH_close_channel) (DWORD) = NULL;
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IO_close_channel = rContext->psFunctions.psFunctions_v1.pvfCloseChannel;
+ else
+ IFDH_close_channel = rContext->psFunctions.psFunctions_v2.pvfCloseChannel;
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+
+ rv = (*IO_close_channel) ();
+ else
+ rv = (*IFDH_close_channel) (rContext->dwSlot);
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ rv = IO_Close_Channel();
+ else
+ rv = IFDHCloseChannel(rContext->dwSlot);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ return rv;
+}
+
+/*
+ * Function: IFDSetCapabilites Purpose : This function set's capabilities
+ * in the reader.
+ */
+
+LONG IFDSetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
+ DWORD dwLength, PUCHAR pucValue)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFD_set_capabilities) (DWORD, PUCHAR) = NULL;
+ RESPONSECODE(*IFDH_set_capabilities) (DWORD, DWORD, DWORD, PUCHAR) = NULL;
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IFD_set_capabilities = rContext->psFunctions.psFunctions_v1.pvfSetCapabilities;
+ else
+ IFDH_set_capabilities = rContext->psFunctions.psFunctions_v2.pvfSetCapabilities;
+#endif
+
+ /*
+ * Let the calling function lock this otherwise a deadlock will
+ * result
+ */
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ rv = (*IFD_set_capabilities) (dwTag, pucValue);
+ else
+ rv = (*IFDH_set_capabilities) (rContext->dwSlot, dwTag,
+ dwLength, pucValue);
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ rv = IFD_Set_Capabilities(dwTag, pucValue);
+ else
+ rv = IFDHSetCapabilities(rContext->dwSlot, dwTag, dwLength,
+ pucValue);
+#endif
+
+ return rv;
+}
+
+/*
+ * Function: IFDGetCapabilites Purpose : This function get's capabilities
+ * in the reader. Other functions int this file will call the driver
+ * directly to not cause a deadlock.
+ */
+
+LONG IFDGetCapabilities(PREADER_CONTEXT rContext, DWORD dwTag,
+ PDWORD pdwLength, PUCHAR pucValue)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
+ RESPONSECODE(*IFDH_get_capabilities) (DWORD, DWORD, PDWORD, PUCHAR) = NULL;
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IFD_get_capabilities =
+ rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
+ else
+ IFDH_get_capabilities =
+ rContext->psFunctions.psFunctions_v2.pvfGetCapabilities;
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ rv = (*IFD_get_capabilities) (dwTag, pucValue);
+ else
+ rv = (*IFDH_get_capabilities) (rContext->dwSlot, dwTag,
+ pdwLength, pucValue);
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ rv = IFD_Get_Capabilities(dwTag, pucValue);
+ else
+ rv = IFDHGetCapabilities(rContext->dwSlot, dwTag, pdwLength,
+ pucValue);
+#endif
+
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ return rv;
+}
+
+/*
+ * Function: IFDPowerICC Purpose : This function powers up/down or reset's
+ * an ICC located in the IFD.
+ */
+
+LONG IFDPowerICC(PREADER_CONTEXT rContext, DWORD dwAction,
+ const unsigned char *pucAtr, PDWORD pdwAtrLen)
+{
+ RESPONSECODE rv;
+ short ret;
+ SMARTCARD_EXTENSION sSmartCard;
+ DWORD dwStatus;
+ UCHAR ucValue[1];
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFD_power_icc) (DWORD) = NULL;
+ RESPONSECODE(*IFDH_power_icc) (DWORD, DWORD, PUCHAR, PDWORD) = NULL;
+#endif
+
+ /*
+ * Zero out everything
+ */
+ rv = IFD_SUCCESS;
+ dwStatus = 0;
+ ucValue[0] = 0;
+
+ /*
+ * Check that the card is inserted first
+ */
+ IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
+
+ if (dwStatus & SCARD_ABSENT)
+ return SCARD_W_REMOVED_CARD;
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IFD_power_icc = rContext->psFunctions.psFunctions_v1.pvfPowerICC;
+ else
+ IFDH_power_icc = rContext->psFunctions.psFunctions_v2.pvfPowerICC;
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = (*IFD_power_icc) (dwAction);
+ }
+ else
+ {
+ rv = (*IFDH_power_icc) (rContext->dwSlot, dwAction,
+ pucAtr, pdwAtrLen);
+
+ ret = ATRDecodeAtr(&sSmartCard, pucAtr, *pdwAtrLen);
+ }
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = IFD_Power_ICC(dwAction);
+ }
+ else
+ rv = IFDHPowerICC(rContext->dwSlot, dwAction, pucAtr, pdwAtrLen);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ /* use clean values in case of error */
+ if (rv != IFD_SUCCESS)
+ {
+ *pdwAtrLen = 0;
+// pucAtr[0] = '\0';
+
+ if (rv == IFD_NO_SUCH_DEVICE)
+ {
+ // SendHotplugSignal();
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ return SCARD_E_NOT_TRANSACTED;
+ }
+
+ /*
+ * Get the ATR and it's length
+ */
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IFDStatusICC(rContext, &dwStatus, pucAtr, pdwAtrLen);
+
+ return rv;
+}
+
+/*
+ * Function: IFDStatusICC Purpose : This function provides statistical
+ * information about the IFD and ICC including insertions, atr, powering
+ * status/etc.
+ */
+
+LONG IFDStatusICC(PREADER_CONTEXT rContext, PDWORD pdwStatus,
+ const unsigned char *pucAtr, PDWORD pdwAtrLen)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+ DWORD dwTag = 0, dwCardStatus = 0;
+ SMARTCARD_EXTENSION sSmartCard;
+ UCHAR ucValue[1] = "\x00";
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFD_is_icc_present) () = NULL;
+ RESPONSECODE(*IFDH_icc_presence) (DWORD) = NULL;
+ RESPONSECODE(*IFD_get_capabilities) (DWORD, PUCHAR) = NULL;
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ IFD_is_icc_present =
+ rContext->psFunctions.psFunctions_v1.pvfICCPresence;
+ IFD_get_capabilities =
+ rContext->psFunctions.psFunctions_v1.pvfGetCapabilities;
+ }
+ else
+ {
+ IFDH_icc_presence = rContext->psFunctions.psFunctions_v2.pvfICCPresence;
+ // Defensive measure
+ if (!IFDH_icc_presence)
+ return SCARD_E_SYSTEM_CANCELLED;
+ }
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = (*IFD_is_icc_present) ();
+ }
+ else
+ rv = (*IFDH_icc_presence) (rContext->dwSlot);
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = IFD_Is_ICC_Present();
+ }
+ else
+ rv = IFDHICCPresence(rContext->dwSlot);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
+ dwCardStatus |= SCARD_PRESENT;
+ else
+ if (rv == IFD_ICC_NOT_PRESENT)
+ dwCardStatus |= SCARD_ABSENT;
+ else
+ {
+ Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
+ *pdwStatus = SCARD_UNKNOWN;
+
+ if (rv == IFD_NO_SUCH_DEVICE)
+ {
+ // SendHotplugSignal();
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ return SCARD_E_NOT_TRANSACTED;
+ }
+
+ /*
+ * Now lets get the ATR and process it if IFD Handler version 1.0.
+ * IFD Handler version 2.0 does this immediately after reset/power up
+ * to conserve resources
+ */
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ if (rv == IFD_SUCCESS || rv == IFD_ICC_PRESENT)
+ {
+ short ret;
+
+ dwTag = TAG_IFD_ATR;
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ rv = (*IFD_get_capabilities) (dwTag, pucAtr);
+#else
+ rv = IFD_Get_Capabilities(dwTag, pucAtr);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ /*
+ * FIX :: This is a temporary way to return the correct size
+ * of the ATR since most of the drivers return MAX_ATR_SIZE
+ */
+
+ ret = ATRDecodeAtr(&sSmartCard, pucAtr, MAX_ATR_SIZE);
+
+ /*
+ * Might be a memory card without an ATR
+ */
+ if (ret == 0)
+ *pdwAtrLen = 0;
+ else
+ *pdwAtrLen = sSmartCard.ATR.Length;
+ }
+ else
+ {
+ /*
+ * No card is inserted - Atr length is 0
+ */
+ *pdwAtrLen = 0;
+ }
+ /*
+ * End of FIX
+ */
+ }
+
+ *pdwStatus = dwCardStatus;
+
+ return SCARD_S_SUCCESS;
+}
+
+/*
+ * Function: IFDControl Purpose : This function provides a means for
+ * toggling a specific action on the reader such as swallow, eject,
+ * biometric.
+ */
+
+/*
+ * Valid only for IFDHandler version 2.0
+ */
+
+LONG IFDControl_v2(PREADER_CONTEXT rContext, PUCHAR TxBuffer,
+ DWORD TxLength, PUCHAR RxBuffer, PDWORD RxLength)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFDH_control_v2) (DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
+#endif
+
+ if (rContext->dwVersion != IFD_HVERSION_2_0)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ IFDH_control_v2 = rContext->psFunctions.psFunctions_v2.pvfControl;
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+ SYS_MutexLock(rContext->mMutex);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ rv = (*IFDH_control_v2) (rContext->dwSlot, TxBuffer, TxLength,
+ RxBuffer, RxLength);
+#else
+ rv = IFDHControl_v2(rContext->dwSlot, TxBuffer, TxLength,
+ RxBuffer, RxLength);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+ /*
+ * END OF LOCKED REGION
+ */
+
+ if (rv == IFD_SUCCESS)
+ return SCARD_S_SUCCESS;
+ else
+ {
+ Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
+ return SCARD_E_NOT_TRANSACTED;
+ }
+}
+
+/*
+ * Function: IFDControl Purpose : This function provides a means for
+ * toggling a specific action on the reader such as swallow, eject,
+ * biometric.
+ */
+
+/*
+ * Valid only for IFDHandler version 3.0 and up
+ */
+
+LONG IFDControl(PREADER_CONTEXT rContext, DWORD ControlCode,
+ LPCVOID TxBuffer, DWORD TxLength, LPVOID RxBuffer, DWORD RxLength,
+ LPDWORD BytesReturned)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFDH_control) (DWORD, DWORD, LPCVOID, DWORD, LPVOID, DWORD, LPDWORD);
+#endif
+
+ if (rContext->dwVersion < IFD_HVERSION_3_0)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ IFDH_control = rContext->psFunctions.psFunctions_v3.pvfControl;
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ rv = (*IFDH_control) (rContext->dwSlot, ControlCode, TxBuffer,
+ TxLength, RxBuffer, RxLength, BytesReturned);
+#else
+ rv = IFDHControl(rContext->dwSlot, ControlCode, TxBuffer,
+ TxLength, RxBuffer, RxLength, BytesReturned);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ if (rv == IFD_SUCCESS)
+ return SCARD_S_SUCCESS;
+ else
+ {
+ Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
+
+ if (rv == IFD_NO_SUCH_DEVICE)
+ {
+// SendHotplugSignal();
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ return SCARD_E_NOT_TRANSACTED;
+ }
+}
+
+/*
+ * Function: IFDTransmit Purpose : This function transmits an APDU to the
+ * ICC.
+ */
+
+LONG IFDTransmit(PREADER_CONTEXT rContext, SCARD_IO_HEADER pioTxPci,
+ PUCHAR pucTxBuffer, DWORD dwTxLength, PUCHAR pucRxBuffer,
+ PDWORD pdwRxLength, PSCARD_IO_HEADER pioRxPci)
+{
+ RESPONSECODE rv = IFD_SUCCESS;
+ UCHAR ucValue[1] = "\x00";
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ RESPONSECODE(*IFD_transmit_to_icc) (SCARD_IO_HEADER, PUCHAR, DWORD,
+ PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
+ RESPONSECODE(*IFDH_transmit_to_icc) (DWORD, SCARD_IO_HEADER, PUCHAR,
+ DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER) = NULL;
+#endif
+
+ /* log the APDU */
+ DebugLogCategory(DEBUG_CATEGORY_APDU, pucTxBuffer, dwTxLength);
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ IFD_transmit_to_icc =
+ rContext->psFunctions.psFunctions_v1.pvfTransmitToICC;
+ else
+ IFDH_transmit_to_icc =
+ rContext->psFunctions.psFunctions_v2.pvfTransmitToICC;
+#endif
+
+ /*
+ * LOCK THIS CODE REGION
+ */
+
+ SYS_MutexLock(rContext->mMutex);
+
+
+#ifndef PCSCLITE_STATIC_DRIVER
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = (*IFD_transmit_to_icc) (pioTxPci, (LPBYTE) pucTxBuffer,
+ dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
+ }
+ else
+ rv = (*IFDH_transmit_to_icc) (rContext->dwSlot, pioTxPci,
+ (LPBYTE) pucTxBuffer, dwTxLength,
+ pucRxBuffer, pdwRxLength, pioRxPci);
+#else
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ ucValue[0] = rContext->dwSlot;
+ IFDSetCapabilities(rContext, TAG_IFD_SLOTNUM, 1, ucValue);
+ rv = IFD_Transmit_to_ICC(pioTxPci, (LPBYTE) pucTxBuffer,
+ dwTxLength, pucRxBuffer, pdwRxLength, pioRxPci);
+ }
+ else
+ rv = IFDHTransmitToICC(rContext->dwSlot, pioTxPci,
+ (LPBYTE) pucTxBuffer, dwTxLength,
+ pucRxBuffer, pdwRxLength, pioRxPci);
+#endif
+ SYS_MutexUnLock(rContext->mMutex);
+
+ /*
+ * END OF LOCKED REGION
+ */
+
+ /* log the returned status word */
+ DebugLogCategory(DEBUG_CATEGORY_SW, pucRxBuffer, *pdwRxLength);
+
+ if (rv == IFD_SUCCESS)
+ return SCARD_S_SUCCESS;
+ else
+ {
+ Log2(PCSC_LOG_ERROR, "Card not transacted: %ld", rv);
+
+ if (rv == IFD_NO_SUCH_DEVICE)
+ {
+ // SendHotplugSignal();
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ return SCARD_E_NOT_TRANSACTED;
+ }
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/ifdwrapper.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * ifdwrapper.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Ludovic Rousseau <ludovic.rouseau at free.fr>
+ *
+ * $Id: ifdwrapper.h 2151 2006-09-06 20:02:47Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This wraps the dynamic ifdhandler functions. The abstraction will
+ * eventually allow multiple card slots in the same terminal.
+ */
+
+#ifndef __ifdwrapper_h__
+#define __ifdwrapper_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ LONG IFDOpenIFD(PREADER_CONTEXT);
+ LONG IFDCloseIFD(PREADER_CONTEXT);
+ LONG IFDPowerICC(PREADER_CONTEXT, DWORD, const unsigned char *, PDWORD);
+ LONG IFDStatusICC(PREADER_CONTEXT, PDWORD, const unsigned char *, PDWORD);
+ LONG IFDControl_v2(PREADER_CONTEXT, PUCHAR, DWORD, PUCHAR, PDWORD);
+ LONG IFDControl(PREADER_CONTEXT, DWORD, LPCVOID, DWORD, LPVOID,
+ DWORD, LPDWORD);
+ LONG IFDTransmit(PREADER_CONTEXT, SCARD_IO_HEADER,
+ PUCHAR, DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER);
+ LONG IFDSetPTS(PREADER_CONTEXT, DWORD, UCHAR, UCHAR, UCHAR, UCHAR);
+ LONG IFDSetCapabilities(PREADER_CONTEXT, DWORD, DWORD, PUCHAR);
+ LONG IFDGetCapabilities(PREADER_CONTEXT, DWORD, PDWORD, PUCHAR);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ifdwrapper_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/mscdefines.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/mscdefines.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/mscdefines.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : mscdefines.h
+ Package: MuscleCard Framework
+ Author : David Corcoran
+ Date : 10/02/01
+ License: Copyright (C) 2001-2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This provides high level definitions for
+ data types, structures.
+
+ You may not remove this header from this file
+ without prior permission from the author.
+
+********************************************************************/
+
+#ifndef __mscdefines_h__
+#define __mscdefines_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef WIN32
+#include "../win32/win32_pcsclite.h"
+#else
+#include "pcsclite.h"
+#endif
+
+#ifndef __APPLE__
+#include <winscard.h>
+#else
+#include <PCSC/winscard.h>
+#endif
+
+#include <stdint.h>
+
+#ifdef MSC_ARCH_WIN32
+#define MAX_BUFFER_SIZE 265
+#endif
+
+ /*
+ * Some type defines used in MuscleCard
+ */
+
+ typedef uint32_t MSC_RV;
+ typedef char MSCChar8;
+ typedef uint8_t *MSCPUChar8;
+ typedef const uint8_t *MSCPCUChar8;
+ typedef uint8_t MSCUChar8;
+ typedef uint16_t *MSCPUShort16;
+ typedef uint16_t MSCUShort16;
+ typedef int16_t *MSCPShort16;
+ typedef int16_t MSCShort16;
+ typedef uint32_t *MSCPULong32;
+ typedef uint32_t MSCULong32;
+ typedef int32_t *MSCPLong32;
+ typedef int32_t MSCLong32;
+ typedef const void *MSCPCVoid32;
+ typedef void *MSCPVoid32;
+ typedef const char *MSCCString;
+ typedef char *MSCString;
+
+ typedef struct
+ {
+ MSCPVoid32 pvfWriteFramework;
+ MSCPVoid32 pvfInitializePlugin;
+ MSCPVoid32 pvfIdentifyToken;
+ MSCPVoid32 pvfFinalizePlugin;
+ MSCPVoid32 pvfGetStatus;
+ MSCPVoid32 pvfGetCapabilities;
+ MSCPVoid32 pvfExtendedFeature;
+ MSCPVoid32 pvfGenerateKeys;
+ MSCPVoid32 pvfImportKey;
+ MSCPVoid32 pvfExportKey;
+ MSCPVoid32 pvfComputeCrypt;
+ MSCPVoid32 pvfExtAuthenticate;
+ MSCPVoid32 pvfListKeys;
+ MSCPVoid32 pvfCreatePIN;
+ MSCPVoid32 pvfVerifyPIN;
+ MSCPVoid32 pvfChangePIN;
+ MSCPVoid32 pvfUnblockPIN;
+ MSCPVoid32 pvfListPINs;
+ MSCPVoid32 pvfCreateObject;
+ MSCPVoid32 pvfDeleteObject;
+ MSCPVoid32 pvfWriteObject;
+ MSCPVoid32 pvfReadObject;
+ MSCPVoid32 pvfListObjects;
+ MSCPVoid32 pvfLogoutAll;
+ MSCPVoid32 pvfGetChallenge;
+
+ }
+ CFDyLibPointers, *LPCFDyLibPointers;
+
+#define MSC_MAXSIZE_TOKENAME 150
+#define MSC_MAXSIZE_SVCPROV 200
+#define MSC_MAXSIZE_OBJID 16
+#define MSC_MAXSIZE_AID 64
+#define MSC_MAXSIZE_MAC 128
+#define MSC_MAXSIZE_LABEL 32
+#define MSC_MAXSIZE_CERT_ISSUER 512
+#define MSC_MAXSIZE_CERT_SUBJECT 512
+#define MSC_MAXSIZE_CERT_SERIAL 512
+#define MSC_MAXSIZE_BUFFER MAX_BUFFER_SIZE
+
+ typedef struct
+ {
+ MSCChar8 tokenName[MSC_MAXSIZE_TOKENAME]; /* Token name */
+ MSCChar8 slotName[MAX_READERNAME]; /* Slot/reader name */
+ MSCChar8 svProvider[MSC_MAXSIZE_SVCPROV]; /* Library */
+ MSCUChar8 tokenId[MAX_ATR_SIZE]; /* Token ID (ATR) */
+ MSCUChar8 tokenApp[MSC_MAXSIZE_AID]; /* Default app ID */
+ MSCULong32 tokenAppLen; /* Default AID Length */
+ MSCULong32 tokenIdLength; /* ID Length (ATR Length) */
+ MSCULong32 tokenState; /* State (dwEventState) */
+ MSCULong32 tokenType; /* Type - RFU */
+ MSCPVoid32 addParams; /* Additional Data */
+ MSCULong32 addParamsSize; /* Size of additional data */
+ }
+ MSCTokenInfo, *MSCLPTokenInfo;
+
+ /*
+ * Callback function definitions
+ */
+
+ typedef MSCULong32(*MSCCallBack) (MSCLPTokenInfo, MSCULong32,
+ MSCPVoid32);
+
+ typedef struct
+ {
+ MSCULong32 arraySize;
+ MSCLPTokenInfo tokenArray;
+ MSCPVoid32 appData;
+ MSCCallBack callBack;
+ }
+ MSCEventWaitInfo, *MSCLPEventWaitInfo;
+
+ typedef MSC_RV(*LPRWEventCallback) (MSCPVoid32, int);
+
+ typedef struct
+ {
+ MSCLong32 hContext; /* Handle to resource manager */
+ MSCLong32 hCard; /* Handle to the connection */
+ LPSCARD_IO_REQUEST ioType; /* Type of protocol */
+ MSCUChar8 pMac[MSC_MAXSIZE_MAC]; /* MAC code */
+ MSCULong32 macSize; /* Size of the MAC code */
+ MSCPVoid32 tokenLibHandle; /* Handle to token library */
+ CFDyLibPointers libPointers; /* Function pointers */
+ MSCTokenInfo tokenInfo; /* token information */
+ MSCUChar8 loggedIDs; /* Verification bit mask */
+ MSCULong32 shareMode; /* Sharing mode for this */
+ LPRWEventCallback rwCallback; /* Registered callback */
+ }
+ MSCTokenConnection, *MSCLPTokenConnection;
+
+#define MSC_OK MSC_SUCCESS
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __mscdefines_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,2285 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : musclecard.c
+ Package: MuscleCard Framework
+ Author : David Corcoran
+ Date : 09/26/01
+ License: Copyright (C) 2001-2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This loads MuscleCard plug-ins and provides
+ functions for applications.
+
+ You may not remove this header from this file without
+ prior permission from the author.
+
+********************************************************************/
+
+#ifndef WIN32
+#include "config.h"
+#else
+#include "../win32/win32_config.h"
+#endif
+
+#include "musclecard.h"
+#include "tokenfactory.h"
+#include "debuglog.h"
+
+#ifdef USE_THREAD_SAFETY
+#ifndef WIN32
+#include "wintypes.h"
+#endif
+#include "thread_generic.h"
+#include "sys_generic.h"
+#endif
+
+#ifdef USE_THREAD_SAFETY
+static PCSCLITE_MUTEX mcardMutex = PTHREAD_MUTEX_INITIALIZER;
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+static SCARDCONTEXT localHContext = 0;
+
+#ifdef USE_THREAD_SAFETY
+static PCSCLITE_THREAD_T callbackThread;
+#endif
+
+/*
+ * internal function
+ */
+MSC_RV pcscToMSC(MSCLong32);
+MSC_RV MSCReEstablishConnection(MSCLPTokenConnection);
+
+void mscLockThread()
+{
+#ifdef USE_THREAD_SAFETY
+ SYS_MutexLock(&mcardMutex);
+#endif
+}
+
+void mscUnLockThread()
+{
+#ifdef USE_THREAD_SAFETY
+ SYS_MutexUnLock(&mcardMutex);
+#endif
+}
+
+/**************** MSC Connection Functions **************************/
+
+MSC_RV MSCListTokens(MSCULong32 listScope, MSCLPTokenInfo tokenArray,
+ MSCPULong32 arrayLength)
+{
+
+ MSCLong32 rv;
+ SCARD_READERSTATE_A rgReaderStates;
+ MSCTokenInfo tokenInfo;
+ MSCLPTokenInfo currentToken;
+ MSCULong32 tokensFound;
+ MSCULong32 readerLength;
+ char *readerList;
+ int i, strLoc;
+
+ readerLength = 0;
+ tokensFound = 0;
+ readerList = 0;
+ strLoc = 0;
+ i = 0;
+
+ if (arrayLength == 0)
+ return MSC_INVALID_PARAMETER;
+ if (listScope != MSC_LIST_KNOWN &&
+ listScope != MSC_LIST_ALL && listScope != MSC_LIST_SLOTS)
+ {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ mscLockThread();
+ if (localHContext == 0)
+ {
+ rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
+ &localHContext);
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ localHContext = 0;
+ mscUnLockThread();
+ return pcscToMSC(rv);
+ }
+ }
+ mscUnLockThread();
+
+ /*
+ * Get the reader list size
+ */
+ rv = SCardListReaders(localHContext, 0, readerList, &readerLength);
+
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ return pcscToMSC(rv);
+ }
+
+ readerList = (char *) malloc(sizeof(char) * readerLength);
+
+ if (readerList == 0)
+ {
+ return MSC_INTERNAL_ERROR;
+ }
+
+ rv = SCardListReaders(localHContext, 0, readerList, &readerLength);
+
+ /*
+ * Now that we have the readers, lets check their status
+ */
+ for (i = 0; i < readerLength - 1; i++)
+ {
+ rgReaderStates.szReader = &readerList[i];
+ rgReaderStates.dwCurrentState = SCARD_STATE_UNAWARE;
+
+ rv = SCardGetStatusChange(localHContext, INFINITE,
+ &rgReaderStates,
+ 1);
+
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ if (readerList)
+ free(readerList);
+ return pcscToMSC(rv);
+ }
+
+ /*
+ * We only care about slots with a token unless stated
+ */
+ if ((rgReaderStates.dwEventState & SCARD_STATE_PRESENT) ||
+ (listScope == MSC_LIST_SLOTS))
+ {
+
+ if (rgReaderStates.dwEventState & SCARD_STATE_PRESENT)
+ {
+ /*
+ * We only care about supported tokens
+ */
+ rv = TPSearchBundlesForAtr(rgReaderStates.rgbAtr,
+ rgReaderStates.cbAtr, &tokenInfo);
+ }
+
+ /*
+ * Success for this function
+ */
+ if ((rv == 0) || (listScope == MSC_LIST_SLOTS) ||
+ (listScope == MSC_LIST_ALL))
+ {
+
+ /*
+ * We found something interesting to the application
+ */
+ tokensFound += 1;
+
+ if ((tokensFound <= *arrayLength) && (tokenArray != 0))
+ {
+ currentToken = &tokenArray[tokensFound - 1];
+ currentToken->addParams = 0;
+ currentToken->addParamsSize = 0;
+ currentToken->tokenType = 0; /* Vinnie 1693 */
+
+ if (rgReaderStates.dwEventState & SCARD_STATE_EMPTY)
+ {
+ currentToken->tokenType |= MSC_TOKEN_TYPE_REMOVED;
+ strncpy(currentToken->tokenName,
+ MSC_TOKEN_EMPTY_STR, MSC_MAXSIZE_TOKENAME);
+ } else if (rv == 0)
+ {
+ currentToken->tokenType |= MSC_TOKEN_TYPE_KNOWN;
+ strncpy(currentToken->tokenName,
+ tokenInfo.tokenName, MSC_MAXSIZE_TOKENAME);
+ } else
+ {
+ currentToken->tokenType |= MSC_TOKEN_TYPE_UNKNOWN;
+ strncpy(currentToken->tokenName,
+ MSC_TOKEN_UNKNOWN_STR, MSC_MAXSIZE_TOKENAME);
+ }
+
+ strncpy(currentToken->slotName,
+ rgReaderStates.szReader, MAX_READERNAME);
+
+ if (rgReaderStates.dwEventState & SCARD_STATE_PRESENT)
+ {
+ memcpy(currentToken->tokenId,
+ rgReaderStates.rgbAtr, rgReaderStates.cbAtr);
+ currentToken->tokenIdLength = rgReaderStates.cbAtr;
+ }
+ else
+ {
+ memset(currentToken->tokenId, 0x00, MAX_ATR_SIZE);
+ currentToken->tokenIdLength = 0x00;
+ }
+
+ if (rv == 0)
+ {
+ memcpy(currentToken->tokenApp,
+ tokenInfo.tokenApp, tokenInfo.tokenAppLen);
+ currentToken->tokenAppLen = tokenInfo.tokenAppLen;
+
+ strncpy(currentToken->svProvider,
+ tokenInfo.svProvider, MSC_MAXSIZE_SVCPROV);
+ } else
+ {
+ memset(currentToken->tokenApp, 0x00, MSC_MAXSIZE_AID);
+ currentToken->tokenAppLen = 0x00;
+ memset(currentToken->svProvider, 0x00, MSC_MAXSIZE_SVCPROV);
+ }
+
+ currentToken->tokenState = rgReaderStates.dwEventState;
+
+ }
+ }
+ /*
+ * End of TPSearch success
+ */
+ }
+ /*
+ * End of if token present
+ */
+ while (readerList[++i] != 0) ;
+ } /* End of for .. readers */
+
+ if (readerList)
+ free(readerList);
+
+ /*
+ * Application provides null requesting length
+ */
+ if (tokenArray == 0)
+ {
+ *arrayLength = tokensFound;
+ return MSC_SUCCESS;
+ }
+
+ /*
+ * Provided length is too small
+ */
+ if (*arrayLength < tokensFound)
+ {
+ *arrayLength = tokensFound;
+ return MSC_INSUFFICIENT_BUFFER;
+ }
+
+ *arrayLength = tokensFound;
+ return MSC_SUCCESS;
+}
+
+MSC_RV MSCEstablishConnection(MSCLPTokenInfo tokenStruct,
+ MSCULong32 sharingMode,
+ MSCPUChar8 applicationName,
+ MSCULong32 nameSize,
+ MSCLPTokenConnection pConnection)
+{
+ MSCLong32 rv;
+ MSCULong32 tokenSize;
+ MSCLPTokenInfo tokenList;
+ MSCPVoid32 vInitFunction;
+ MSCPVoid32 vIdFunction;
+ MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection);
+ MSCLong32(*libPL_MSCIdentifyToken) (MSCLPTokenConnection);
+ MSCULong32 dwActiveProtocol;
+ int selectedIFD;
+ char slotName[MAX_READERNAME];
+ MSCULong32 slotNameSize, slotState, slotProtocol;
+ MSCUChar8 tokenId[MAX_ATR_SIZE];
+ MSCULong32 tokenIdLength;
+
+ tokenSize = 0;
+ tokenList = 0;
+ tokenSize = 0;
+ selectedIFD = -1;
+ tokenIdLength = sizeof(tokenId);
+ slotState = 0;
+ slotProtocol = 0;
+ slotNameSize = sizeof(slotName);
+ vIdFunction = 0;
+ vInitFunction = 0;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (tokenStruct == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (nameSize > MSC_MAXSIZE_AID)
+ return MSC_INVALID_PARAMETER;
+
+ pConnection->tokenLibHandle = 0;
+ pConnection->hContext = 0;
+ pConnection->tokenInfo.tokenIdLength = 0;
+ pConnection->shareMode = 0;
+
+ /*
+ * Check the token name strings
+ */
+ if (sharingMode != MSC_SHARE_DIRECT)
+ {
+ if (strcmp(tokenStruct->tokenName, MSC_TOKEN_EMPTY_STR) == 0)
+ {
+ return MSC_TOKEN_REMOVED;
+ } else if (strcmp(tokenStruct->tokenName,
+ MSC_TOKEN_UNKNOWN_STR) == 0)
+ {
+ return MSC_UNRECOGNIZED_TOKEN;
+ }
+ }
+
+ /*
+ * Set up the initial connection to the resource manager
+ */
+
+ mscLockThread();
+ if (localHContext == 0)
+ {
+ rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
+ &localHContext);
+#ifdef MSC_DEBUG
+ DebugLogB("SCardEstablishContext returns %s\n",
+ pcsc_stringify_error(rv));
+#endif
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ localHContext = 0;
+ mscUnLockThread();
+ return pcscToMSC(rv);
+ }
+
+ pConnection->hContext = localHContext;
+ } else
+ {
+ pConnection->hContext = localHContext;
+ }
+ mscUnLockThread();
+
+#ifdef WIN32
+ rv = SCardConnect(pConnection->hContext, tokenStruct->slotName,
+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ &pConnection->hCard, &dwActiveProtocol);
+#else
+ rv = SCardConnect(pConnection->hContext, tokenStruct->slotName,
+ sharingMode, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ &pConnection->hCard, &dwActiveProtocol);
+#endif
+
+#ifdef MSC_DEBUG
+ DebugLogB("SCardConnect returns %s\n", pcsc_stringify_error(rv));
+#endif
+
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ return pcscToMSC(rv);
+ }
+
+ /*
+ * Set the sendPCI value based on the ActiveProtocol
+ */
+ switch (dwActiveProtocol)
+ {
+ case SCARD_PROTOCOL_T0:
+ pConnection->ioType = SCARD_PCI_T0;
+ break;
+ case SCARD_PROTOCOL_T1:
+ pConnection->ioType = SCARD_PCI_T1;
+ break;
+ default:
+ pConnection->ioType = SCARD_PCI_RAW;
+ break;
+ }
+
+ /*
+ * Call SCardStatus, make sure the card information matches if it does
+ * not return an error. If it does, copy it
+ */
+
+ rv = SCardStatus(pConnection->hCard, slotName,
+ &slotNameSize, &slotState, &slotProtocol, tokenId, &tokenIdLength);
+
+#ifdef MSC_DEBUG
+ DebugLogB("SCardStatus returns %s\n", pcsc_stringify_error(rv));
+#endif
+
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ pConnection->hCard = 0;
+ return pcscToMSC(rv);
+ }
+
+ if ((sharingMode == MSC_SHARE_DIRECT) && (slotState & SCARD_ABSENT))
+ {
+
+ /*
+ * They asked for direct mode and no card is inserted so we are
+ * done with this
+ */
+ pConnection->shareMode = sharingMode;
+ return MSC_SUCCESS;
+ }
+
+ if ((tokenIdLength != tokenStruct->tokenIdLength) ||
+ (strcmp(slotName, tokenStruct->slotName) != 0) ||
+ (memcmp(tokenId, tokenStruct->tokenId, tokenIdLength) != 0))
+ {
+ DebugLogA("Internal inconsistent values, ID, slotName\n");
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ pConnection->hCard = 0;
+ return MSC_INCONSISTENT_STATUS;
+ }
+
+ memcpy(pConnection->tokenInfo.tokenId, tokenId, tokenIdLength);
+ pConnection->tokenInfo.tokenIdLength = tokenIdLength;
+ strncpy(pConnection->tokenInfo.slotName, tokenStruct->slotName,
+ MAX_READERNAME);
+ strncpy(pConnection->tokenInfo.tokenName, tokenStruct->tokenName,
+ MSC_MAXSIZE_TOKENAME);
+
+ /*
+ * Load the library for the token
+ */
+ rv = TPLoadToken(pConnection);
+
+#ifdef MSC_DEBUG
+ DebugLogB("TPLoadToken returns %s\n", pcsc_stringify_error(rv));
+#endif
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ pConnection->hCard = 0;
+ return pcscToMSC(rv);
+ }
+
+ /*
+ * Select the AID or initialization routine for the card
+ */
+ vInitFunction = pConnection->libPointers.pvfInitializePlugin;
+ vIdFunction = pConnection->libPointers.pvfIdentifyToken;
+
+ if (vInitFunction == 0)
+ {
+ DebugLogB("Error: Card service failure: %s\n",
+ "InitializePlugin function missing");
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ pConnection->hCard = 0;
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ if (vIdFunction == 0)
+ {
+ DebugLogB("Error: Card service failure: %s\n",
+ "IdentifyToken function missing");
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ pConnection->hCard = 0;
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection))
+ vInitFunction;
+
+ libPL_MSCIdentifyToken = (MSCLong32(*)(MSCLPTokenConnection))
+ vIdFunction;
+
+ rv = (*libPL_MSCInitializePlugin) (pConnection);
+
+ if (rv != MSC_SUCCESS)
+ {
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ if (pConnection->tokenLibHandle != 0)
+ {
+ TPUnloadToken(pConnection);
+ pConnection->tokenLibHandle = 0;
+ }
+ pConnection->hCard = 0;
+ }
+
+ if (sharingMode != MSC_SHARE_DIRECT)
+ {
+
+ if ((applicationName == 0) || (nameSize == 0))
+ {
+ /*
+ * Use the default AID given by the Info.plist
+ */
+
+ rv = (*libPL_MSCIdentifyToken) (pConnection);
+ } else
+ {
+ pConnection->tokenInfo.tokenAppLen = nameSize;
+ memcpy(pConnection->tokenInfo.tokenApp,
+ applicationName, nameSize);
+ rv = (*libPL_MSCIdentifyToken) (pConnection);
+ }
+
+#ifdef MSC_DEBUG
+ DebugLogB("MSCIdentifyToken returns %s\n", msc_error(rv));
+#endif
+
+ if (rv != MSC_SUCCESS)
+ {
+ SCardDisconnect(pConnection->hCard, SCARD_LEAVE_CARD);
+ if (pConnection->tokenLibHandle != 0)
+ {
+ TPUnloadToken(pConnection);
+ pConnection->tokenLibHandle = 0;
+ }
+ pConnection->hCard = 0;
+
+ if (rv == MSC_SHARING_VIOLATION)
+ {
+ return rv;
+ } else
+ {
+ return MSC_UNRECOGNIZED_TOKEN;
+ }
+ }
+ }
+
+ pConnection->shareMode = sharingMode;
+ return MSC_SUCCESS;
+}
+
+MSC_RV MSCReleaseConnection(MSCLPTokenConnection pConnection,
+ MSCULong32 endAction)
+{
+
+ MSCLong32 rv = SCARD_S_SUCCESS;
+ MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection);
+ MSCPVoid32 vFunction;
+
+ vFunction = 0;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (pConnection->tokenLibHandle == 0 ||
+ pConnection->hContext == 0 || pConnection->hCard == 0)
+ {
+ return MSC_INVALID_HANDLE;
+ }
+
+ /*
+ * Select finalization routine for the token plugin
+ */
+ vFunction = pConnection->libPointers.pvfFinalizePlugin;
+
+ if (vFunction == 0)
+ {
+ DebugLogB("Error: Card service failure: %s\n",
+ "FinalizePlugin function missing");
+ return MSC_INTERNAL_ERROR;
+ }
+
+ libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection))
+ vFunction;
+
+ /*
+ * Stop and clean up the plugin
+ */
+ rv = (*libPL_MSCFinalizePlugin) (pConnection);
+
+ /*
+ * Disconnect from the token
+ */
+ if (pConnection->hCard != 0)
+ {
+ rv = SCardDisconnect(pConnection->hCard, endAction);
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ return pcscToMSC(rv);
+ }
+ }
+
+ /*
+ * Unload the token driver
+ */
+ if (pConnection->tokenLibHandle != 0)
+ {
+ rv = TPUnloadToken(pConnection);
+ pConnection->tokenLibHandle = 0;
+ }
+
+ pConnection->tokenLibHandle = 0;
+ pConnection->hCard = 0;
+ pConnection->hContext = 0;
+ pConnection->shareMode = 0;
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV MSCWaitForTokenEvent(MSCLPTokenInfo tokenArray,
+ MSCULong32 arraySize,
+ MSCULong32 timeoutValue)
+{
+
+ MSCLong32 rv, rt;
+ LPSCARD_READERSTATE_A rgReaderStates;
+ MSCTokenInfo tokenInfo;
+ int i;
+
+ rgReaderStates = 0;
+
+ /*
+ * Allocate array of SCARD_READERSTATE_A structures, set UNAWARE on
+ * all of the structures to get the current status and then send them
+ * to GetStatusChange for blocking event
+ */
+
+ if (arraySize == 0)
+ {
+ return MSC_SUCCESS;
+ } else if (arraySize > MSC_MAXSIZE_TOKENARRAY)
+ {
+ return MSC_INSUFFICIENT_BUFFER;
+ }
+
+ /*
+ * Set up the initial connection to the resource manager
+ */
+
+ mscLockThread();
+ if (localHContext == 0)
+ {
+ rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0,
+ &localHContext);
+ if (pcscToMSC(rv) != MSC_SUCCESS)
+ {
+ localHContext = 0;
+ mscUnLockThread();
+ return pcscToMSC(rv);
+ }
+ }
+ mscUnLockThread();
+
+ rgReaderStates = (LPSCARD_READERSTATE_A)
+ malloc(sizeof(SCARD_READERSTATE_A) * arraySize);
+
+ if (rgReaderStates == 0)
+ {
+ return MSC_INTERNAL_ERROR;
+ }
+
+ for (i = 0; i < arraySize; i++)
+ {
+ /*
+ * Make sure they don't pass an empty structure
+ */
+ if (strlen(tokenArray[i].slotName) == 0)
+ {
+ free(rgReaderStates);
+ return MSC_INVALID_PARAMETER;
+ }
+
+ rgReaderStates[i].szReader = tokenArray[i].slotName;
+ rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
+ rgReaderStates[i].dwEventState = 0;
+ }
+
+ rv = SCardGetStatusChange(localHContext, timeoutValue,
+ rgReaderStates, arraySize);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ free(rgReaderStates);
+ return pcscToMSC(rv);
+ }
+
+ for (i = 0; i < arraySize; i++)
+ {
+ if (tokenArray[i].tokenState == 0)
+ {
+ rgReaderStates[i].dwCurrentState =
+ rgReaderStates[i].dwEventState;
+ } else if (tokenArray[i].tokenState == MSC_STATE_UNAWARE)
+ {
+ rgReaderStates[i].dwCurrentState = SCARD_STATE_UNAWARE;
+ } else
+ {
+ rgReaderStates[i].dwCurrentState = tokenArray[i].tokenState;
+ }
+ rgReaderStates[i].dwEventState = 0;
+ }
+
+ rv = SCardGetStatusChange(localHContext, timeoutValue,
+ rgReaderStates, arraySize);
+
+ for (i = 0; i < arraySize; i++)
+ {
+ tokenArray[i].tokenState = rgReaderStates[i].dwEventState;
+
+ if (tokenArray[i].tokenState & MSC_STATE_CHANGED)
+ {
+ /*
+ * If it is removed, we need to update the names/etc
+ */
+ if (tokenArray[i].tokenState & MSC_STATE_EMPTY)
+ {
+ memset(tokenArray[i].tokenId, 0x00, MAX_ATR_SIZE);
+ tokenArray[i].tokenIdLength = 0;
+ tokenArray[i].tokenType = MSC_TOKEN_TYPE_REMOVED;
+ strncpy(tokenArray[i].tokenName, MSC_TOKEN_EMPTY_STR,
+ MSC_MAXSIZE_TOKENAME);
+ } else if (tokenArray[i].tokenState & MSC_STATE_PRESENT)
+ {
+ memcpy(tokenArray[i].tokenId, rgReaderStates[i].rgbAtr,
+ rgReaderStates[i].cbAtr);
+ tokenArray[i].tokenIdLength = rgReaderStates[i].cbAtr;
+
+ rt = TPSearchBundlesForAtr(rgReaderStates[i].rgbAtr,
+ rgReaderStates[i].cbAtr, &tokenInfo);
+ /*
+ * Successfully found
+ */
+ if (rt == 0)
+ {
+ tokenArray[i].tokenType = MSC_TOKEN_TYPE_KNOWN;
+ strncpy(tokenArray[i].tokenName, tokenInfo.tokenName,
+ MSC_MAXSIZE_TOKENAME);
+ } else
+ {
+ tokenArray[i].tokenType = MSC_TOKEN_TYPE_UNKNOWN;
+ strncpy(tokenArray[i].tokenName, MSC_TOKEN_UNKNOWN_STR,
+ MSC_MAXSIZE_TOKENAME);
+ }
+ }
+ }
+ }
+
+ free(rgReaderStates);
+ return pcscToMSC(rv);
+}
+
+MSC_RV MSCCancelEventWait(void)
+{
+
+ MSCLong32 rv;
+
+ rv = SCardCancel(localHContext);
+
+ return pcscToMSC(rv);
+}
+
+/************************ Start of Callbacks ****************************/
+#ifdef USE_THREAD_SAFETY
+void *_MSCEventThread(void *arg)
+{
+
+ MSCLong32 rv;
+ MSCLPEventWaitInfo evlist;
+ MSCLong32 curToken;
+
+ if (arg == NULL)
+ {
+ SYS_ThreadExit(NULL);
+ }
+
+ evlist = (MSCLPEventWaitInfo) arg;
+ blockingContext = MSC_BLOCKSTATUS_BLOCKING;
+
+ while (1)
+ {
+ rv = MSCWaitForTokenEvent(evlist->tokenArray,
+ evlist->arraySize,
+ MSC_NO_TIMEOUT);
+
+ if (rv == MSC_SUCCESS)
+ {
+ (evlist->callBack) (evlist->tokenArray,
+ evlist->arraySize,
+ evlist->appData);
+ } else {
+ break;
+
+ }
+
+ if (blockingContext == MSC_BLOCKSTATUS_CANCELLING)
+ {
+ break;
+ }
+ }
+
+ for (curToken = 0; curToken < evlist->arraySize; curToken++)
+ {
+ if (evlist->tokenArray[curToken].addParams)
+ {
+ free(evlist->tokenArray[curToken].addParams);
+ }
+ }
+
+
+ free(evlist);
+ blockingContext = MSC_BLOCKSTATUS_RESUME;
+ SYS_ThreadExit(&rv);
+
+ return NULL;
+}
+
+MSC_RV MSCCallbackForTokenEvent(MSCLPTokenInfo tokenArray,
+ MSCULong32 arraySize,
+ MSCCallBack callBack,
+ MSCPVoid32 appData)
+{
+ MSCLPEventWaitInfo evlist;
+ MSCULong32 curToken;
+
+ /*
+ * Create the event wait list
+ */
+ evlist = (MSCLPEventWaitInfo) malloc(sizeof(MSCEventWaitInfo));
+
+ if (evlist == NULL)
+ {
+ return MSC_INTERNAL_ERROR;
+ }
+
+ evlist->arraySize = arraySize;
+ evlist->tokenArray = malloc(sizeof(MSCTokenInfo) * arraySize);
+ evlist->appData = appData;
+ evlist->callBack = callBack;
+
+ if (evlist->tokenArray == NULL)
+ {
+ free(evlist);
+ return MSC_INTERNAL_ERROR;
+ }
+
+ mscLockThread();
+ memcpy(evlist->tokenArray, tokenArray,
+ sizeof(MSCTokenInfo) * arraySize);
+
+ /*
+ * Copy the "extra" data
+ */
+ for (curToken = 0; curToken < arraySize; curToken++)
+ {
+ if (tokenArray[curToken].addParams != NULL)
+ {
+ evlist->tokenArray[curToken].addParams =
+ malloc(evlist->tokenArray[curToken].addParamsSize);
+ memcpy((void *) (evlist->tokenArray[curToken].addParams),
+ &tokenArray[curToken],
+ evlist->tokenArray[curToken].addParamsSize);
+
+ }
+ }
+ mscUnLockThread();
+
+ if (SYS_ThreadCreate(&callbackThread, THREAD_ATTR_DEFAULT, _MSCEventThread,
+ (void *) evlist) == 0)
+ {
+ return MSC_INTERNAL_ERROR;
+ }
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV MSCCallbackCancelEvent()
+{
+
+ LONG rv;
+
+ /* Release the thread and stop the GetStatusChange */
+ if (blockingContext == MSC_BLOCKSTATUS_BLOCKING)
+ {
+ blockingContext = MSC_BLOCKSTATUS_CANCELLING;
+ rv = MSCCancelEventWait();
+
+ SYS_ThreadJoin(&callbackThread, 0);
+
+ }
+
+ return MSC_SUCCESS;
+}
+
+#endif
+/************************** End of Callbacks *****************************/
+
+MSC_RV MSCBeginTransaction(MSCLPTokenConnection pConnection)
+{
+
+ MSCLong32 rv;
+ MSCLong32 ret;
+
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ while (1)
+ {
+ rv = SCardBeginTransaction(pConnection->hCard);
+ ret = pcscToMSC(rv);
+
+ if (ret == MSC_SUCCESS)
+ break;
+ if (ret == MSC_TOKEN_RESET)
+ {
+ pConnection->tokenInfo.tokenType |=
+ MSC_TOKEN_TYPE_RESET;
+ ret = MSCReEstablishConnection(pConnection);
+ if (ret != MSC_SUCCESS)
+ break;
+ continue;
+ } else if (ret == MSC_TOKEN_REMOVED)
+ {
+ pConnection->tokenInfo.tokenType =
+ MSC_TOKEN_TYPE_REMOVED;
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+MSC_RV MSCEndTransaction(MSCLPTokenConnection pConnection,
+ MSCULong32 endAction)
+{
+
+ MSCLong32 rv;
+ MSCLong32 ret;
+
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ while (1)
+ {
+ rv = SCardEndTransaction(pConnection->hCard, endAction);
+ ret = pcscToMSC(rv);
+
+ if (ret == MSC_SUCCESS)
+ break;
+ if (ret == MSC_TOKEN_RESET)
+ {
+ pConnection->tokenInfo.tokenType |=
+ MSC_TOKEN_TYPE_RESET;
+ ret = MSCReEstablishConnection(pConnection);
+ if (ret != MSC_SUCCESS)
+ break;
+ continue;
+ } else if (ret == MSC_TOKEN_REMOVED)
+ {
+ pConnection->tokenInfo.tokenType =
+ MSC_TOKEN_TYPE_REMOVED;
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+MSC_RV MSCWriteFramework(MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams)
+{
+
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCWriteFramework) (MSCLPTokenConnection,
+ MSCLPInitTokenParams);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfWriteFramework;
+
+ if (vFunction != 0)
+ {
+ libMSCWriteFramework = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCLPInitTokenParams)) vFunction;
+ rv = (*libMSCWriteFramework) (pConnection, pInitParams);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+/*
+ * Real MSC functions
+ */
+
+MSC_RV MSCGetStatus(MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCGetStatus) (MSCLPTokenConnection, MSCLPStatusInfo);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfGetStatus;
+
+ if (vFunction != 0)
+ {
+ libMSCGetStatus = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCLPStatusInfo)) vFunction;
+ rv = (*libMSCGetStatus) (pConnection, pStatusInfo);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCGetCapabilities(MSCLPTokenConnection pConnection, MSCULong32 Tag,
+ MSCPUChar8 Value, MSCPULong32 Length)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCGetCapabilities) (MSCLPTokenConnection, MSCULong32,
+ MSCPUChar8, MSCPULong32);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfGetCapabilities;
+
+ if (vFunction != 0)
+ {
+ libMSCGetCapabilities =
+ (MSCLong32(*)(MSCLPTokenConnection, MSCULong32, MSCPUChar8,
+ MSCPULong32)) vFunction;
+ rv = (*libMSCGetCapabilities) (pConnection, Tag, Value, Length);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCExtendedFeature(MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature, MSCPUChar8 outData,
+ MSCULong32 outLength, MSCPUChar8 inData, MSCPULong32 inLength)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCExtendedFeature) (MSCLPTokenConnection, MSCULong32,
+ MSCPUChar8, MSCULong32, MSCPUChar8, MSCPULong32);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfExtendedFeature;
+
+ if (vFunction != 0)
+ {
+ libMSCExtendedFeature =
+ (MSCLong32(*)(MSCLPTokenConnection, MSCULong32, MSCPUChar8,
+ MSCULong32, MSCPUChar8, MSCPULong32)) vFunction;
+ rv = (*libMSCExtendedFeature) (pConnection, extFeature, outData,
+ outLength, inData, inLength);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCGenerateKeys(MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum, MSCUChar8 pubKeyNum, MSCLPGenKeyParams pParams)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCGenerateKeys) (MSCLPTokenConnection, MSCUChar8,
+ MSCUChar8, MSCLPGenKeyParams);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfGenerateKeys;
+
+ if (vFunction != 0)
+ {
+ libMSCGenerateKeys = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCUChar8, MSCUChar8,
+ MSCLPGenKeyParams))
+ vFunction;
+ rv = (*libMSCGenerateKeys) (pConnection, prvKeyNum, pubKeyNum,
+ pParams);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCImportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL, MSCPUChar8 pKeyBlob,MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy, MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCImportKey) (MSCLPTokenConnection, MSCUChar8,
+ MSCLPKeyACL, MSCPUChar8,
+ MSCULong32, MSCLPKeyPolicy, MSCPVoid32,
+ MSCUChar8);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfImportKey;
+
+ if (vFunction != 0)
+ {
+ libMSCImportKey = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCUChar8,
+ MSCLPKeyACL, MSCPUChar8,
+ MSCULong32, MSCLPKeyPolicy,
+ MSCPVoid32, MSCUChar8))
+ vFunction;
+
+ rv = (*libMSCImportKey) (pConnection, keyNum,
+ pKeyACL, pKeyBlob, keyBlobSize,
+ keyPolicy, pAddParams, addParamsSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCExportKey(MSCLPTokenConnection pConnection, MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob, MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCExportKey) (MSCLPTokenConnection, MSCUChar8,
+ MSCPUChar8, MSCPULong32, MSCPVoid32, MSCUChar8);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfExportKey;
+
+ if (vFunction != 0)
+ {
+ libMSCExportKey = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCUChar8, MSCPUChar8,
+ MSCPULong32, MSCPVoid32,
+ MSCUChar8)) vFunction;
+
+ rv = (*libMSCExportKey) (pConnection, keyNum, pKeyBlob,
+ keyBlobSize, pAddParams, addParamsSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCComputeCrypt(MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit, MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize, MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCComputeCrypt) (MSCLPTokenConnection, MSCLPCryptInit,
+ MSCPUChar8, MSCULong32, MSCPUChar8,
+ MSCPULong32);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfComputeCrypt;
+
+ if (vFunction != 0)
+ {
+ libMSCComputeCrypt =
+ (MSCLong32(*)(MSCLPTokenConnection, MSCLPCryptInit,
+ MSCPUChar8, MSCULong32, MSCPUChar8,
+ MSCPULong32)) vFunction;
+ rv = (*libMSCComputeCrypt) (pConnection, cryptInit, pInputData,
+ inputDataSize, pOutputData,
+ outputDataSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCExtAuthenticate(MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum, MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData, MSCULong32 dataSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCExtAuthenticate) (MSCLPTokenConnection, MSCUChar8,
+ MSCUChar8, MSCUChar8, MSCPUChar8,
+ MSCULong32);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfExtAuthenticate;
+
+ if (vFunction != 0)
+ {
+ libMSCExtAuthenticate =
+ (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
+ MSCUChar8, MSCUChar8, MSCPUChar8,
+ MSCULong32)) vFunction;
+ rv = (*libMSCExtAuthenticate) (pConnection, keyNum, cipherMode,
+ cipherDirection, pData, dataSize);
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCListKeys(MSCLPTokenConnection pConnection, MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCListKeys) (MSCLPTokenConnection, MSCUChar8,
+ MSCLPKeyInfo);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfListKeys;
+
+ if (vFunction != 0)
+ {
+ libMSCListKeys = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
+ MSCLPKeyInfo)) vFunction;
+ rv = (*libMSCListKeys) (pConnection, seqOption, pKeyInfo);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCCreatePIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts, MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize, MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCCreatePIN) (MSCLPTokenConnection, MSCUChar8,
+ MSCUChar8, MSCPUChar8, MSCULong32, MSCPUChar8, MSCUChar8);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfCreatePIN;
+
+ if (vFunction != 0)
+ {
+ libMSCCreatePIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
+ MSCUChar8, MSCPUChar8,
+ MSCULong32, MSCPUChar8, MSCUChar8)) vFunction;
+ rv = (*libMSCCreatePIN) (pConnection, pinNum, pinAttempts,
+ pPinCode, pinCodeSize, pUnblockCode, unblockCodeSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCVerifyPIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode, MSCULong32 pinCodeSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCVerifyPIN) (MSCLPTokenConnection, MSCUChar8,
+ MSCPUChar8, MSCULong32);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfVerifyPIN;
+
+ if (vFunction != 0)
+ {
+ libMSCVerifyPIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
+ MSCPUChar8, MSCULong32)) vFunction;
+ rv = (*libMSCVerifyPIN) (pConnection, pinNum, pPinCode,
+ pinCodeSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCChangePIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode, MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCChangePIN) (MSCLPTokenConnection, MSCUChar8,
+ MSCPUChar8, MSCUChar8, MSCPUChar8, MSCUChar8);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfChangePIN;
+
+ if (vFunction != 0)
+ {
+ libMSCChangePIN = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
+ MSCPUChar8, MSCUChar8, MSCPUChar8, MSCUChar8)) vFunction;
+ rv = (*libMSCChangePIN) (pConnection, pinNum, pOldPinCode,
+ oldPinCodeSize, pNewPinCode, newPinCodeSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCUnblockPIN(MSCLPTokenConnection pConnection, MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode, MSCULong32 unblockCodeSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCUnblockPIN) (MSCLPTokenConnection, MSCUChar8,
+ MSCPUChar8, MSCULong32);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfUnblockPIN;
+
+ if (vFunction != 0)
+ {
+ libMSCUnblockPIN = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCUChar8, MSCPUChar8, MSCULong32)) vFunction;
+ rv = (*libMSCUnblockPIN) (pConnection, pinNum, pUnblockCode,
+ unblockCodeSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCListPINs(MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCListPINs) (MSCLPTokenConnection, MSCPUShort16);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfListPINs;
+
+ if (vFunction != 0)
+ {
+ libMSCListPINs = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCPUShort16)) vFunction;
+ rv = (*libMSCListPINs) (pConnection, pPinBitMask);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCCreateObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 objectSize, MSCLPObjectACL pObjectACL)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCCreateObject) (MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCLPObjectACL);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfCreateObject;
+
+ if (vFunction != 0)
+ {
+ libMSCCreateObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCLPObjectACL)) vFunction;
+ rv = (*libMSCCreateObject) (pConnection, objectID, objectSize,
+ pObjectACL);
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCDeleteObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCUChar8 zeroFlag)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCDeleteObject) (MSCLPTokenConnection, MSCString,
+ MSCUChar8);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfDeleteObject;
+
+ if (vFunction != 0)
+ {
+ libMSCDeleteObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString,
+ MSCUChar8)) vFunction;
+ rv = (*libMSCDeleteObject) (pConnection, objectID, zeroFlag);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCWriteObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offSet,
+ MSCPUChar8 pInputData, MSCULong32 dataSize,
+ LPRWEventCallback rwCallback, MSCPVoid32 addParams)
+{
+ MSC_RV rv = MSC_UNSPECIFIED_ERROR;
+ MSCULong32 objectSize;
+ int totalSteps, stepInterval;
+ MSC_RV(*callBackFunction) (void *, int);
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCWriteObject) (MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCPUChar8, MSCUChar8);
+ int i;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfWriteObject;
+ callBackFunction = (MSC_RV(*)(void *, int)) rwCallback;
+ objectSize = dataSize;
+
+ if (vFunction == 0)
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ libMSCWriteObject = (MSCLong32(*)(MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCPUChar8, MSCUChar8))
+ vFunction;
+
+ /*
+ * Figure out the number of steps total and present this in a percent
+ * step basis
+ */
+
+ totalSteps = objectSize / MSC_SIZEOF_KEYPACKET + 1;
+ stepInterval = MSC_PERCENT_STEPSIZE / totalSteps;
+
+ for (i = 0; i < objectSize / MSC_SIZEOF_KEYPACKET; i++)
+ {
+ rv = (*libMSCWriteObject) (pConnection, objectID,
+ i * MSC_SIZEOF_KEYPACKET + offSet,
+ &pInputData[i * MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET);
+ if (rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+
+ if (rwCallback)
+ {
+ if ((*callBackFunction) (addParams,
+ stepInterval * i) == MSC_CANCELLED)
+ {
+ return MSC_CANCELLED;
+ }
+ }
+ }
+
+ if (objectSize % MSC_SIZEOF_KEYPACKET)
+ {
+
+ rv = (*libMSCWriteObject) (pConnection, objectID,
+ i * MSC_SIZEOF_KEYPACKET + offSet,
+ &pInputData[i * MSC_SIZEOF_KEYPACKET],
+ objectSize % MSC_SIZEOF_KEYPACKET);
+
+ if (rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+ }
+
+ if (rwCallback)
+ {
+ (*callBackFunction) (addParams, MSC_PERCENT_STEPSIZE);
+ }
+
+ return rv;
+}
+
+MSC_RV MSCReadObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offSet,
+ MSCPUChar8 pOutputData, MSCULong32 dataSize,
+ LPRWEventCallback rwCallback,
+ MSCPVoid32 addParams)
+{
+
+ MSC_RV rv = MSC_UNSPECIFIED_ERROR;
+ MSCULong32 objectSize;
+ int totalSteps, stepInterval;
+ MSC_RV(*callBackFunction) (void *, int);
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCReadObject) (MSCLPTokenConnection, MSCString,
+ MSCULong32, MSCPUChar8, MSCUChar8);
+ int i;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfReadObject;
+ callBackFunction = (MSC_RV(*)(void *, int)) rwCallback;
+ objectSize = dataSize;
+
+ if (vFunction == 0)
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ libMSCReadObject = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCString, MSCULong32,
+ MSCPUChar8, MSCUChar8))
+ vFunction;
+
+ /*
+ * Figure out the number of steps total and present this in a percent
+ * step basis
+ */
+
+ totalSteps = objectSize / MSC_SIZEOF_KEYPACKET + 1;
+ stepInterval = MSC_PERCENT_STEPSIZE / totalSteps;
+
+ for (i = 0; i < objectSize / MSC_SIZEOF_KEYPACKET; i++)
+ {
+ rv = (*libMSCReadObject) (pConnection, objectID,
+ i * MSC_SIZEOF_KEYPACKET + offSet,
+ &pOutputData[i * MSC_SIZEOF_KEYPACKET],
+ MSC_SIZEOF_KEYPACKET);
+
+ if (rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+
+ if (rwCallback)
+ {
+ if ((*callBackFunction) (addParams,
+ stepInterval * i) == MSC_CANCELLED)
+ {
+ return MSC_CANCELLED;
+ }
+ }
+ }
+
+ if (objectSize % MSC_SIZEOF_KEYPACKET)
+ {
+ rv = (*libMSCReadObject) (pConnection, objectID,
+ i * MSC_SIZEOF_KEYPACKET + offSet,
+ &pOutputData[i * MSC_SIZEOF_KEYPACKET],
+ objectSize % MSC_SIZEOF_KEYPACKET);
+
+ if (rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+ }
+
+ if (rwCallback)
+ {
+ (*callBackFunction) (addParams, MSC_PERCENT_STEPSIZE);
+ }
+
+ return rv;
+}
+
+MSC_RV MSCListObjects(MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption, MSCLPObjectInfo pObjectInfo)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCListObjects) (MSCLPTokenConnection, MSCUChar8,
+ MSCLPObjectInfo);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfListObjects;
+
+ if (vFunction != 0)
+ {
+ libMSCListObjects = (MSCLong32(*)(MSCLPTokenConnection, MSCUChar8,
+ MSCLPObjectInfo)) vFunction;
+ rv = (*libMSCListObjects) (pConnection, seqOption, pObjectInfo);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCLogoutAll(MSCLPTokenConnection pConnection)
+{
+
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCLogoutAll) (MSCLPTokenConnection);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfLogoutAll;
+
+ if (vFunction != 0)
+ {
+ libMSCLogoutAll = (MSCLong32(*)(MSCLPTokenConnection)) vFunction;
+ rv = (*libMSCLogoutAll) (pConnection);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCGetChallenge(MSCLPTokenConnection pConnection, MSCPUChar8 pSeed,
+ MSCUShort16 seedSize, MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize)
+{
+ MSCLong32 rv;
+ MSCPVoid32 vFunction;
+ MSCLong32(*libMSCGetChallenge) (MSCLPTokenConnection, MSCPUChar8,
+ MSCUShort16, MSCPUChar8, MSCUShort16);
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ vFunction = pConnection->libPointers.pvfGetChallenge;
+
+ if (vFunction != 0)
+ {
+ libMSCGetChallenge = (MSCLong32(*)(MSCLPTokenConnection,
+ MSCPUChar8, MSCUShort16,
+ MSCPUChar8, MSCUShort16)) vFunction;
+ rv = (*libMSCGetChallenge) (pConnection, pSeed, seedSize,
+ pRandomData, randomDataSize);
+
+ } else
+ {
+ return MSC_UNSUPPORTED_FEATURE;
+ }
+
+ return rv;
+}
+
+MSC_RV MSCGetKeyAttributes(MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNumber, MSCLPKeyInfo pKeyInfo)
+{
+
+ MSC_RV rv;
+ MSCKeyInfo keyInfo;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ rv = MSCListKeys(pConnection, MSC_SEQUENCE_RESET, &keyInfo);
+
+ if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+
+ if (rv == MSC_SEQUENCE_END)
+ {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ if (keyNumber == keyInfo.keyNum)
+ {
+ pKeyInfo->keyNum = keyInfo.keyNum;
+ pKeyInfo->keyType = keyInfo.keyType;
+ pKeyInfo->keySize = keyInfo.keySize;
+
+ pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode;
+ pKeyInfo->keyPolicy.cipherDirection =
+ keyInfo.keyPolicy.cipherDirection;
+
+ pKeyInfo->keyACL.readPermission =
+ keyInfo.keyACL.readPermission;
+ pKeyInfo->keyACL.writePermission =
+ keyInfo.keyACL.writePermission;
+ pKeyInfo->keyACL.usePermission =
+ keyInfo.keyACL.usePermission;
+
+ return MSC_SUCCESS;
+ }
+
+ do
+ {
+ rv = MSCListKeys(pConnection, MSC_SEQUENCE_NEXT, &keyInfo);
+ if (keyNumber == keyInfo.keyNum)
+ break;
+ }
+ while (rv == MSC_SUCCESS);
+
+ if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+
+ if (rv == MSC_SEQUENCE_END)
+ {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ pKeyInfo->keyNum = keyInfo.keyNum;
+ pKeyInfo->keyType = keyInfo.keyType;
+ pKeyInfo->keySize = keyInfo.keySize;
+
+ pKeyInfo->keyPolicy.cipherMode = keyInfo.keyPolicy.cipherMode;
+ pKeyInfo->keyPolicy.cipherDirection =
+ keyInfo.keyPolicy.cipherDirection;
+
+ pKeyInfo->keyACL.readPermission = keyInfo.keyACL.readPermission;
+ pKeyInfo->keyACL.writePermission = keyInfo.keyACL.writePermission;
+ pKeyInfo->keyACL.usePermission = keyInfo.keyACL.usePermission;
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV MSCGetObjectAttributes(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCLPObjectInfo pObjectInfo)
+{
+
+ MSC_RV rv;
+ MSCObjectInfo objInfo;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ rv = MSCListObjects(pConnection, MSC_SEQUENCE_RESET, &objInfo);
+
+ if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+
+ if (rv == MSC_SEQUENCE_END)
+ {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0)
+ {
+ pObjectInfo->objectSize = objInfo.objectSize;
+ pObjectInfo->objectACL.readPermission =
+ objInfo.objectACL.readPermission;
+ pObjectInfo->objectACL.writePermission =
+ objInfo.objectACL.writePermission;
+ pObjectInfo->objectACL.deletePermission =
+ objInfo.objectACL.deletePermission;
+ strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID);
+ return MSC_SUCCESS;
+ }
+
+ do
+ {
+ rv = MSCListObjects(pConnection, MSC_SEQUENCE_NEXT, &objInfo);
+ if (strncmp(objectID, objInfo.objectID, MSC_MAXSIZE_OBJID) == 0)
+ break;
+ }
+ while (rv == MSC_SUCCESS);
+
+ if (rv != MSC_SEQUENCE_END && rv != MSC_SUCCESS)
+ {
+ return rv;
+ }
+
+ if (rv == MSC_SEQUENCE_END)
+ {
+ return MSC_OBJECT_NOT_FOUND;
+ }
+
+ pObjectInfo->objectSize = objInfo.objectSize;
+ pObjectInfo->objectACL.readPermission =
+ objInfo.objectACL.readPermission;
+ pObjectInfo->objectACL.writePermission =
+ objInfo.objectACL.writePermission;
+ pObjectInfo->objectACL.deletePermission =
+ objInfo.objectACL.deletePermission;
+ strncpy(pObjectInfo->objectID, objectID, MSC_MAXSIZE_OBJID);
+
+ return MSC_SUCCESS;
+}
+
+MSC_RV MSCReadAllocateObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCPUChar8 * pOutputData,
+ MSCPULong32 dataSize,
+ LPRWEventCallback rwCallback,
+ MSCPVoid32 addParams)
+{
+ MSC_RV rv;
+ MSCObjectInfo objInfo;
+ MSCULong32 objectSize;
+ MSCPUChar8 data = NULL;
+
+ if (pConnection == NULL)
+ return MSC_INVALID_PARAMETER;
+ if (localHContext == 0)
+ return MSC_INTERNAL_ERROR;
+
+ if (pOutputData == 0)
+ {
+ return MSC_INVALID_PARAMETER;
+ }
+
+ *dataSize = 0;
+ *pOutputData = 0;
+
+ rv = MSCGetObjectAttributes(pConnection, objectID, &objInfo);
+ if (rv == MSC_SUCCESS)
+ {
+ objectSize = objInfo.objectSize;
+ data = (MSCPUChar8) malloc(sizeof(MSCUChar8) * objectSize);
+ if(data)
+ {
+ rv = MSCReadObject(pConnection, objectID, 0, data,
+ objectSize, rwCallback, addParams);
+
+ if (rv == MSC_SUCCESS)
+ {
+ *dataSize = objectSize;
+ *pOutputData = data;
+ }
+ else
+ {
+ rv = MSC_INTERNAL_ERROR;
+ free(data);
+ }
+ }
+ }
+
+ return rv;
+}
+
+
+MSC_RV pcscToMSC(MSCLong32 pcscCode)
+{
+
+ switch (pcscCode)
+ {
+ case SCARD_S_SUCCESS:
+ return MSC_SUCCESS;
+ case SCARD_E_INVALID_HANDLE:
+ return MSC_INVALID_HANDLE;
+ case SCARD_E_SHARING_VIOLATION:
+ return MSC_SHARING_VIOLATION;
+ case SCARD_W_REMOVED_CARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_E_NO_SMARTCARD:
+ return MSC_TOKEN_REMOVED;
+ case SCARD_W_RESET_CARD:
+ return MSC_TOKEN_RESET;
+ case SCARD_W_INSERTED_CARD:
+ return MSC_TOKEN_INSERTED;
+ case SCARD_E_NO_SERVICE:
+ return MSC_SERVICE_UNRESPONSIVE;
+ case SCARD_E_UNKNOWN_CARD:
+ case SCARD_W_UNSUPPORTED_CARD:
+ case SCARD_E_CARD_UNSUPPORTED:
+ return MSC_UNRECOGNIZED_TOKEN;
+ case SCARD_E_INVALID_PARAMETER:
+ case SCARD_E_INVALID_VALUE:
+ case SCARD_E_UNKNOWN_READER:
+ case SCARD_E_PROTO_MISMATCH:
+ case SCARD_E_READER_UNAVAILABLE:
+ return MSC_INVALID_PARAMETER;
+ case SCARD_E_CANCELLED:
+ return MSC_CANCELLED;
+ case SCARD_E_TIMEOUT:
+ return MSC_TIMEOUT_OCCURRED;
+
+ default:
+ return MSC_INTERNAL_ERROR;
+ }
+}
+
+char *msc_error(unsigned long int errorCode) //MSC_RV
+{
+
+ static char message[500];
+
+ switch (errorCode)
+ {
+ case MSC_SUCCESS:
+ strncpy(message, "Successful", sizeof(message));
+ break;
+ case MSC_NO_MEMORY_LEFT:
+ strncpy(message, "No more memory", sizeof(message));
+ break;
+ case MSC_AUTH_FAILED:
+ strncpy(message, "Authentication failed", sizeof(message));
+ break;
+ case MSC_OPERATION_NOT_ALLOWED:
+ strncpy(message, "Operation not allowed", sizeof(message));
+ break;
+ case MSC_INCONSISTENT_STATUS:
+ strncpy(message, "Inconsistent status", sizeof(message));
+ break;
+ case MSC_UNSUPPORTED_FEATURE:
+ strncpy(message, "Feature unsupported", sizeof(message));
+ break;
+ case MSC_UNAUTHORIZED:
+ strncpy(message, "Unauthorized usage", sizeof(message));
+ break;
+ case MSC_OBJECT_NOT_FOUND:
+ strncpy(message, "Object not found", sizeof(message));
+ break;
+ case MSC_OBJECT_EXISTS:
+ strncpy(message, "Object already exists", sizeof(message));
+ break;
+ case MSC_INCORRECT_ALG:
+ strncpy(message, "Incorrect algorithm", sizeof(message));
+ break;
+ case MSC_SIGNATURE_INVALID:
+ strncpy(message, "Invalid signature", sizeof(message));
+ break;
+ case MSC_IDENTITY_BLOCKED:
+ strncpy(message, "Identity is blocked", sizeof(message));
+ break;
+ case MSC_UNSPECIFIED_ERROR:
+ strncpy(message, "Unspecified error", sizeof(message));
+ break;
+ case MSC_TRANSPORT_ERROR:
+ strncpy(message, "Transport error", sizeof(message));
+ break;
+ case MSC_INVALID_PARAMETER:
+ strncpy(message, "Invalid parameter", sizeof(message));
+ break;
+ case MSC_SEQUENCE_END:
+ strncpy(message, "End of sequence", sizeof(message));
+ break;
+ case MSC_INTERNAL_ERROR:
+ strncpy(message, "Internal Error", sizeof(message));
+ break;
+ case MSC_CANCELLED:
+ strncpy(message, "Operation Cancelled", sizeof(message));
+ break;
+ case MSC_INSUFFICIENT_BUFFER:
+ strncpy(message, "Buffer is too small", sizeof(message));
+ break;
+ case MSC_UNRECOGNIZED_TOKEN:
+ strncpy(message, "Token is unsupported", sizeof(message));
+ break;
+ case MSC_SERVICE_UNRESPONSIVE:
+ strncpy(message, "Service is not running", sizeof(message));
+ break;
+ case MSC_TIMEOUT_OCCURRED:
+ strncpy(message, "Timeout has occurred", sizeof(message));
+ break;
+ case MSC_TOKEN_REMOVED:
+ strncpy(message, "Token was removed", sizeof(message));
+ break;
+ case MSC_TOKEN_RESET:
+ strncpy(message, "Token was reset", sizeof(message));
+ break;
+ case MSC_TOKEN_INSERTED:
+ strncpy(message, "Token was inserted", sizeof(message));
+ break;
+ case MSC_TOKEN_UNRESPONSIVE:
+ strncpy(message, "Token is unresponsive", sizeof(message));
+ break;
+ case MSC_INVALID_HANDLE:
+ strncpy(message, "Handle is invalid", sizeof(message));
+ break;
+ case MSC_SHARING_VIOLATION:
+ strncpy(message, "Sharing violation", sizeof(message));
+ break;
+
+ default:
+ sprintf(message, "Unknown SW: %04lu", errorCode);
+ break;
+ }
+
+ return message;
+}
+
+MSC_RV MSCReEstablishConnection(MSCLPTokenConnection pConnection)
+{
+
+ MSC_RV rv;
+ MSCPVoid32 vInitFunction, vFinFunction, vIdFunction;
+ MSCULong32 dwActiveProtocol;
+ MSCLong32(*libPL_MSCInitializePlugin) (MSCLPTokenConnection);
+ MSCLong32(*libPL_MSCFinalizePlugin) (MSCLPTokenConnection);
+ MSCLong32 (*libPL_MSCIdentifyToken)(MSCLPTokenConnection);
+
+ vInitFunction = 0;
+ vFinFunction = 0;
+ vIdFunction = 0;
+
+ /*
+ * Select the AID or initialization routine for the card
+ */
+ vInitFunction = pConnection->libPointers.pvfInitializePlugin;
+ vFinFunction = pConnection->libPointers.pvfFinalizePlugin;
+ vIdFunction = pConnection->libPointers.pvfIdentifyToken;
+
+ if (vInitFunction == 0)
+ {
+ DebugLogB("Error: Card service failure: %s\n",
+ "InitializePlugin function missing");
+ return MSC_INTERNAL_ERROR;
+ }
+
+ if (vFinFunction == 0)
+ {
+ DebugLogB("Error: Card service failure: %s\n",
+ "FinalizePlugin function missing");
+ return MSC_INTERNAL_ERROR;
+ }
+
+ if ( vIdFunction == 0 )
+ {
+ DebugLogB("Error: Card service failure: %s\n",
+ "IdentifyToken function missing");
+ return MSC_INTERNAL_ERROR;
+ }
+
+ libPL_MSCInitializePlugin = (MSCLong32(*)(MSCLPTokenConnection))
+ vInitFunction;
+
+ libPL_MSCFinalizePlugin = (MSCLong32(*)(MSCLPTokenConnection))
+ vFinFunction;
+
+ libPL_MSCIdentifyToken = (MSCLong32 (*)(MSCLPTokenConnection))
+ vIdFunction;
+
+ rv = SCardReconnect(pConnection->hCard, pConnection->shareMode,
+ SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ SCARD_LEAVE_CARD, &dwActiveProtocol);
+
+ if (rv != SCARD_S_SUCCESS)
+ return pcscToMSC(rv);
+
+ /*
+ * Stop the plugin and start it up again
+ */
+ rv = (*libPL_MSCFinalizePlugin) (pConnection);
+
+ /*
+ * Use the default AID given by the Info.plist
+ */
+ rv = (*libPL_MSCInitializePlugin) (pConnection);
+
+ /*
+ * Use the default AID given by the Info.plist
+ */
+ rv = (*libPL_MSCIdentifyToken)(pConnection);
+
+ if (rv != MSC_SUCCESS)
+ return rv;
+
+ return MSC_SUCCESS;
+}
+
+MSCUChar8 MSCIsTokenReset(MSCLPTokenConnection pConnection)
+{
+ MSCULong32 rv;
+ char slotName[MAX_READERNAME];
+ MSCULong32 slotNameSize, slotState, slotProtocol;
+ MSCUChar8 tokenId[MAX_ATR_SIZE];
+ MSCULong32 tokenIdLength;
+
+ rv = SCardStatus(pConnection->hCard, slotName,
+ &slotNameSize, &slotState, &slotProtocol,
+ tokenId, &tokenIdLength);
+
+ if (rv == SCARD_W_RESET_CARD)
+ {
+ return 1;
+ }
+
+ if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_RESET)
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+}
+
+MSCUChar8 MSCClearReset(MSCLPTokenConnection pConnection)
+{
+ pConnection->tokenInfo.tokenType &= ~MSC_TOKEN_TYPE_RESET;
+ return 1;
+}
+
+MSCUChar8 MSCIsTokenMoved(MSCLPTokenConnection pConnection)
+{
+ MSCULong32 rv;
+ char slotName[MAX_READERNAME];
+ MSCULong32 slotNameSize, slotState, slotProtocol;
+ MSCUChar8 tokenId[MAX_ATR_SIZE];
+ MSCULong32 tokenIdLength;
+
+
+ rv = SCardStatus(pConnection->hCard, slotName,
+ &slotNameSize, &slotState, &slotProtocol,
+ tokenId, &tokenIdLength);
+
+ if (rv == SCARD_W_REMOVED_CARD)
+ {
+ return 1;
+ } else if (rv == SCARD_W_INSERTED_CARD)
+ {
+ return 1;
+ } else if (slotState & SCARD_ABSENT)
+ {
+ return 1;
+ }
+
+
+ if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_REMOVED)
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+}
+
+MSCUChar8 MSCIsTokenChanged(MSCLPTokenConnection pConnection)
+{
+ if (MSCIsTokenMoved(pConnection))
+ {
+ return 1;
+ } else if (MSCIsTokenReset(pConnection))
+ {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+MSCUChar8 MSCIsTokenKnown(MSCLPTokenConnection pConnection)
+{
+ if (pConnection->tokenInfo.tokenType & MSC_TOKEN_TYPE_KNOWN)
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/musclecard.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1050 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : musclecard.h
+ Package: MuscleCard Framework
+ Author : David Corcoran
+ Date : 11/28/01
+ License: Copyright (C) 2001 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This abstracts the MUSCLE Card Edge Inteface
+
+ You may not remove this header from this file
+ without prior permission from the author.
+
+********************************************************************/
+
+#ifndef __musclecard_h__
+#define __musclecard_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef WIN32
+#include "PCSC.h"
+#endif
+
+#ifndef __APPLE__
+#include <mscdefines.h>
+#else
+#include <PCSC/mscdefines.h>
+#endif
+
+ /****************
+ * Return codes *
+ ****************/
+
+ /** success */
+#define MSC_SUCCESS 0x9000
+
+ /** There have been memory problems on the card */
+#define MSC_NO_MEMORY_LEFT 0x9C01
+ /** Entered PIN is not correct */
+#define MSC_AUTH_FAILED 0x9C02
+ /** Required operation is not allowed in actual circumstances */
+#define MSC_OPERATION_NOT_ALLOWED 0x9C03
+ /** Required operation is inconsistent with memory contents */
+#define MSC_INCONSISTENT_STATUS 0x9C04
+ /** Required feature is not (yet) supported */
+#define MSC_UNSUPPORTED_FEATURE 0x9C05
+ /** Required operation was not authorized because of a lack of privileges */
+#define MSC_UNAUTHORIZED 0x9C06
+ /** Required object is missing */
+#define MSC_OBJECT_NOT_FOUND 0x9C07
+ /** New object ID already in use */
+#define MSC_OBJECT_EXISTS 0x9C08
+ /** Algorithm specified is not correct */
+#define MSC_INCORRECT_ALG 0x9C09
+
+ /** Verify operation detected an invalid signature */
+#define MSC_SIGNATURE_INVALID 0x9C0B
+ /** Operation has been blocked for security reason */
+#define MSC_IDENTITY_BLOCKED 0x9C0C
+ /** Unspecified error */
+#define MSC_UNSPECIFIED_ERROR 0x9C0D
+ /** PCSC and driver transport errors */
+#define MSC_TRANSPORT_ERROR 0x9C0E
+ /** Invalid parameter given */
+#define MSC_INVALID_PARAMETER 0x9C0F
+ /** Incorrect P1 parameter */
+#define MSC_INCORRECT_P1 0x9C10
+ /** Incorrect P2 parameter */
+#define MSC_INCORRECT_P2 0x9C11
+ /** End of sequence */
+#define MSC_SEQUENCE_END 0x9C12
+ /** For debugging purposes */
+#define MSC_INTERNAL_ERROR 0x9CFF
+
+ /*******************************************************/
+ /*
+ * These returns are beyond the protocol specification
+ */
+ /*
+ * and only exist here to provide return codes for the
+ */
+ /*
+ * additional functions provided by the MuscleCard API
+ */
+ /*
+ * beyond the protocol specification.
+ */
+ /*******************************************************/
+
+ /** A blocking event has been cancelled */
+#define MSC_CANCELLED 0x9C50
+ /*
+ * The buffer provided is too short
+ */
+#define MSC_INSUFFICIENT_BUFFER 0x9C51
+ /*
+ * The selected token is not recognized
+ */
+#define MSC_UNRECOGNIZED_TOKEN 0x9C52
+ /*
+ * The PC/SC services is not available
+ */
+#define MSC_SERVICE_UNRESPONSIVE 0x9C53
+ /*
+ * The action has timed out
+ */
+#define MSC_TIMEOUT_OCCURRED 0x9C54
+ /*
+ * The token has been removed
+ */
+#define MSC_TOKEN_REMOVED 0x9C55
+ /*
+ * The token has been reset
+ */
+#define MSC_TOKEN_RESET 0x9C56
+ /*
+ * The token has been inserted
+ */
+#define MSC_TOKEN_INSERTED 0x9C57
+ /*
+ * The token is unresponsive
+ */
+#define MSC_TOKEN_UNRESPONSIVE 0x9C58
+ /*
+ * The handle is invalid
+ */
+#define MSC_INVALID_HANDLE 0x9C59
+ /*
+ * Invalid sharing
+ */
+#define MSC_SHARING_VIOLATION 0x9C60
+
+
+#define MSC_BLOCKSTATUS_RESUME 0x0000
+#define MSC_BLOCKSTATUS_BLOCKING 0x0001
+#define MSC_BLOCKSTATUS_CANCELLING 0x0002
+
+ /*
+ * Some boundary defines
+ */
+#define MSC_MAX_KEYS 16
+#define MSC_MAX_PINS 8
+#define MSC_SIZEOF_KEYPACKET 200
+#define MSC_MAXSIZEOF_APDU_DATALEN 255
+#define MSC_PERCENT_STEPSIZE 1000
+#define MSC_SINGLE_READ_PACKET 255
+#define MSC_MAXSIZE_TOKENARRAY 255
+
+ /*
+ * KeyPair Generation algorithms
+ */
+#define MSC_GEN_ALG_RSA 0x00
+#define MSC_GEN_ALG_RSA_CRT 0x01
+#define MSC_GEN_ALG_DSA 0x02
+#define MSC_GEN_ALG_DES 0x03
+#define MSC_GEN_ALG_3DES 0x04
+#define MSC_GEN_ALG_3DES3 0x05
+
+ /*
+ * Blob encodings in KeyBlob structure
+ */
+#define MSC_BLOB_ENC_PLAIN 0x00
+#define MSC_BLOB_ENC_CRYPT 0x01
+
+ /*
+ * Key Type in Key Blobs
+ */
+#define MSC_KEY_RSA_PUBLIC 0x01
+#define MSC_KEY_RSA_PRIVATE 0x02
+#define MSC_KEY_RSA_PRIVATE_CRT 0x03
+#define MSC_KEY_DSA_PUBLIC 0x04
+#define MSC_KEY_DSA_PRIVATE 0x05
+#define MSC_KEY_DES 0x06
+#define MSC_KEY_3DES 0x07
+#define MSC_KEY_3DES3 0x08
+
+ /*
+ * Key generation options TODO: add other
+ */
+#define MSC_OPT_DEFAULT 0x00
+#define MSC_OPT_RSA_PUB_EXP 0x01
+#define MSC_OPT_DSA_GPQ 0x02
+
+ /*
+ * Cipher operations in ComputeCrypt()
+ */
+#define MSC_CIPHER_INIT 0x01
+#define MSC_CIPHER_PROCESS 0x02
+#define MSC_CIPHER_FINAL 0x03
+
+ /*
+ * Cipher modes in ComputeCrypt()
+ */
+#define MSC_MODE_RSA_NOPAD 0x00
+#define MSC_MODE_RSA_PAD_PKCS1 0x01
+#define MSC_MODE_DSA_SHA 0x10
+#define MSC_MODE_DES_CBC_NOPAD 0x20
+#define MSC_MODE_DES_ECB_NOPAD 0x21
+
+ /*
+ * Cipher directions
+ */
+#define MSC_DIR_SIGN 0x01
+#define MSC_DIR_VERIFY 0x02
+#define MSC_DIR_ENCRYPT 0x03
+#define MSC_DIR_DECRYPT 0x04
+
+ /*
+ * Sequence options in ListXXX()
+ */
+#define MSC_SEQUENCE_RESET 0x00
+#define MSC_SEQUENCE_NEXT 0x01
+
+ /*
+ * Zero flag in DeleteObject()
+ */
+#define MSC_ZF_DEFAULT 0x00
+#define MSC_ZF_WRITE_ZERO 0x01
+
+ /*
+ * Some defines for ID's Bitmask
+ */
+#define MSC_AUT_ALL 0x0000
+#define MSC_AUT_NONE 0xFFFF
+
+#define MSC_AUT_PIN_0 0x0001
+#define MSC_AUT_PIN_1 0x0002
+#define MSC_AUT_PIN_2 0x0004
+#define MSC_AUT_PIN_3 0x0008
+#define MSC_AUT_PIN_4 0x0010
+
+#define MSC_AUT_KEY_0 0x0100
+#define MSC_AUT_KEY_1 0x0200
+#define MSC_AUT_KEY_2 0x0400
+#define MSC_AUT_KEY_3 0x0800
+#define MSC_AUT_KEY_4 0x1000
+#define MSC_AUT_KEY_5 0x2000
+
+#define MSC_AUT_USR_0 0x4000
+#define MSC_AUT_USR_1 0x8000
+
+ /*
+ * This structure allows you to customize your MuscleCard. It is used
+ * in MSCWriteFramework to specify attributes you may want to set in
+ * this 'personalization' routine and will be getting new values in
+ * future revisions of the API
+ */
+
+#define MSC_INIT_DEFAULT_KEY 0x00 /* Use card's default transport
+ * key */
+#define MSC_INIT_IGNORE_KEY 0x01 /* Don't verify any key at all */
+#define MSC_INIT_USE_KEY 0x02 /* Use the key in this struct */
+
+ typedef struct
+ {
+ MSCUChar8 transportKey[MAX_BUFFER_SIZE];
+ MSCULong32 transportKeyLen;
+ MSCUChar8 transportBehavior;
+ MSCULong32 objectMemory;
+
+ MSCUChar8 newTransportKey[MAX_BUFFER_SIZE];
+ MSCULong32 newTransportKeyLen;
+
+ MSCUChar8 defaultCHV[MAX_BUFFER_SIZE];
+ MSCULong32 defaultCHVLen;
+ MSCUChar8 defaultCHVTries;
+
+ MSCUChar8 defaultCHVUnblock[MAX_BUFFER_SIZE];
+ MSCULong32 defaultCHVUnblockSize;
+ MSCUChar8 defaultCHVUnblockTries;
+
+ MSCUShort16 createObjectACL;
+ MSCUShort16 createKeysACL;
+ MSCUShort16 createPINsACL;
+
+ MSCUChar8 maxNumberKeys;
+ MSCUChar8 maxNumberPINs;
+ MSCUShort16 maxNumberObjects;
+
+ }
+ MSCInitTokenParams, *MSCLPInitTokenParams;
+
+ /*
+ * Direction policy bitmasks for MSCKeyPolicy
+ */
+#define MSC_KEYPOLICY_MODE_RSA_NOPAD 0x0001
+#define MSC_KEYPOLICY_MODE_RSA_PAD_PKCS1 0x0002
+#define MSC_KEYPOLICY_MODE_DSA_SHA 0x0004
+#define MSC_KEYPOLICY_MODE_DES_CBC_NOPAD 0x0008
+#define MSC_KEYPOLICY_MODE_DES_ECB_NOPAD 0x0010
+
+#define MSC_KEYPOLICY_DIR_SIGN 0x0100
+#define MSC_KEYPOLICY_DIR_VERIFY 0x0200
+#define MSC_KEYPOLICY_DIR_ENCRYPT 0x0400
+#define MSC_KEYPOLICY_DIR_DECRYPT 0x0800
+
+ typedef struct
+ {
+ MSCUShort16 cipherMode;
+ MSCUShort16 cipherDirection;
+ }
+ MSCKeyPolicy, *MSCLPKeyPolicy;
+
+ typedef struct
+ {
+ MSCUShort16 readPermission;
+ MSCUShort16 writePermission;
+ MSCUShort16 usePermission;
+ }
+ MSCKeyACL, *MSCLPKeyACL;
+
+ typedef struct
+ {
+ MSCUShort16 readPermission;
+ MSCUShort16 writePermission;
+ MSCUShort16 deletePermission;
+ }
+ MSCObjectACL, *MSCLPObjectACL, MSCCertACL, *MSCLPCertACL;
+
+ typedef struct
+ {
+ MSCUChar8 algoType;
+ MSCUShort16 keySize;
+ MSCKeyACL privateKeyACL;
+ MSCKeyACL publicKeyACL;
+ MSCKeyPolicy privateKeyPolicy;
+ MSCKeyPolicy publicKeyPolicy;
+ MSCUChar8 keyGenOptions;
+ MSCPUChar8 pOptParams;
+ MSCULong32 optParamsSize;
+ }
+ MSCGenKeyParams, *MSCLPGenKeyParams;
+
+ typedef MSCPUChar8 MSCLPKeyBlob;
+
+ typedef struct
+ {
+ MSCUChar8 keyNum;
+ MSCUChar8 keyType;
+ MSCUChar8 keyPartner; /* Do not use (deprecated) */
+ MSCUChar8 keyMapping; /* Do not use (deprecated) */
+ MSCUShort16 keySize;
+ MSCKeyPolicy keyPolicy;
+ MSCKeyACL keyACL;
+ }
+ MSCKeyInfo, *MSCLPKeyInfo;
+
+ typedef struct
+ {
+ MSCUChar8 keyNum;
+ MSCUChar8 cipherMode;
+ MSCUChar8 cipherDirection;
+ MSCPUChar8 optParams;
+ MSCUShort16 optParamsSize;
+ }
+ MSCCryptInit, *MSCLPCryptInit;
+
+ /*
+ * Scope definitions for MSCListTokens
+ */
+#define MSC_LIST_KNOWN 1 /* Lists known tokens only */
+#define MSC_LIST_SLOTS 2 /* Lists all slots, with or without tokens
+ */
+#define MSC_LIST_ALL 3 /* Lists all tokens, known or not */
+
+#define MSC_TOKEN_EMPTY_STR "Token Removed"
+#define MSC_TOKEN_UNKNOWN_STR "Token Unknown"
+
+#define MSC_TOKEN_TYPE_REMOVED 1 /* Token was removed at one point */
+#define MSC_TOKEN_TYPE_UNKNOWN 2 /* Token is unknown, state is fine */
+#define MSC_TOKEN_TYPE_KNOWN 4 /* Token is known, state is fine */
+#define MSC_TOKEN_TYPE_RESET 8 /* Token is known, was reset */
+
+ /*
+ * endAction definitions for MSCReleaseConnection
+ */
+#define MSC_LEAVE_TOKEN SCARD_LEAVE_CARD
+#define MSC_RESET_TOKEN SCARD_RESET_CARD
+#define MSC_EJECT_TOKEN SCARD_EJECT_CARD
+
+ /*
+ * sharingMode for MSCEstablishConnection
+ */
+#define MSC_SHARE_SHARED SCARD_SHARE_SHARED
+#define MSC_SHARE_EXCLUSIVE SCARD_SHARE_EXCLUSIVE
+#define MSC_SHARE_DIRECT SCARD_SHARE_DIRECT
+
+ /*
+ * tokenState for MSCWaitForTokenEvent
+ */
+#define MSC_STATE_UNAWARE 0x4000
+#define MSC_STATE_CHANGED SCARD_STATE_CHANGED
+#define MSC_STATE_UNKNOWN SCARD_STATE_UNKNOWN
+#define MSC_STATE_UNAVAILABLE SCARD_STATE_UNAVAILABLE
+#define MSC_STATE_EMPTY SCARD_STATE_EMPTY
+#define MSC_STATE_PRESENT SCARD_STATE_PRESENT
+#define MSC_STATE_EXCLUSIVE SCARD_STATE_EXCLUSIVE
+#define MSC_STATE_INUSE SCARD_STATE_INUSE
+#define MSC_STATE_MUTE SCARD_STATE_MUTE
+
+#define MSC_NO_TIMEOUT INFINITE
+
+/********************** TAGS for GetStatus ********************************/
+
+ /*
+ * high level tags
+ */
+#define MSC_TAG_SUPPORT_FUNCTIONS 101 /* Supported functions */
+#define MSC_TAG_SUPPORT_CRYPTOALG 102 /* Supported crypto algorithms
+ */
+
+ /*
+ * crypto related tags
+ */
+#define MSC_TAG_CAPABLE_RSA 103 /* RSA capabilities */
+#define MSC_TAG_CAPABLE_DSA 104 /* DSA capabilities */
+#define MSC_TAG_CAPABLE_ECURVE 105 /* Eliptic Curve capabilities */
+#define MSC_TAG_CAPABLE_ELGAMAL 106 /* El Gamal capabilities */
+
+#define MSC_TAG_CAPABLE_KEY_AUTH 180 /* Key import/gen AUT needed */
+
+#define MSC_TAG_CAPABLE_DES 201 /* DES capabilities */
+#define MSC_TAG_CAPABLE_3DES 202 /* Triple DES capabilities */
+#define MSC_TAG_CAPABLE_IDEA 203 /* IDEA capabilities */
+#define MSC_TAG_CAPABLE_AES 204 /* AES capabilities */
+#define MSC_TAG_CAPABLE_BLOWFISH 205 /* Blowfish capabilities */
+#define MSC_TAG_CAPABLE_TWOFISH 206 /* Twofish capabilities */
+
+#define MSC_TAG_CAPABLE_MD5 207 /* MD5 capabilities */
+#define MSC_TAG_CAPABLE_SHA1 208 /* SHA1 capabilities */
+
+ /*
+ * object related tags
+ */
+#define MSC_TAG_CAPABLE_OBJ_ATTR 301 /* returns general attributes */
+#define MSC_TAG_CAPABLE_OBJ_IDSIZE 302 /* returns size of object id */
+#define MSC_TAG_CAPABLE_OBJ_AUTH 303 /* return AUT needed for
+ * create */
+#define MSC_TAG_CAPABLE_OBJ_MAXNUM 304 /* maximum number of objects */
+
+ /*
+ * pin related tags
+ */
+#define MSC_TAG_CAPABLE_PIN_ATTR 401 /* returns general attributes */
+#define MSC_TAG_CAPABLE_PIN_MAXNUM 402 /* returns max number of pins */
+#define MSC_TAG_CAPABLE_PIN_MINSIZE 403 /* returns minimum pin size */
+#define MSC_TAG_CAPABLE_PIN_MAXSIZE 404 /* returns maximum pin size */
+#define MSC_TAG_CAPABLE_PIN_CHARSET 405 /* char set supported
+ * (bitmask) */
+#define MSC_TAG_CAPABLE_PIN_POLICY 406 /* returns pin policy
+ * (bitmask) */
+#define MSC_TAG_CAPABLE_PIN_AUTH 407 /* return AUT needed for
+ * create */
+
+#define MSC_TAG_CAPABLE_ID_STATE 501 /* returns state capability */
+
+#define MSC_TAG_CAPABLE_RANDOM 600 /* Random number capabilities */
+#define MSC_TAG_CAPABLE_RANDOM_MAX 601 /* Maximum random number */
+#define MSC_TAG_CAPABLE_RANDOM_MIN 602 /* Minimum random number */
+
+/********************************** END OF TAGS ***************************/
+
+ /*
+ * Bitmask for TAG MSC_TAG_SUPPORT_FUNCTIONS
+ */
+#define MSC_SUPPORT_GENKEYS 0x00000001
+#define MSC_SUPPORT_IMPORTKEY 0x00000002
+#define MSC_SUPPORT_EXPORTKEY 0x00000004
+#define MSC_SUPPORT_COMPUTECRYPT 0x00000008
+#define MSC_SUPPORT_EXTAUTH 0x00000010
+#define MSC_SUPPORT_LISTKEYS 0x00000020
+#define MSC_SUPPORT_CREATEPIN 0x00000040
+#define MSC_SUPPORT_VERIFYPIN 0x00000080
+#define MSC_SUPPORT_CHANGEPIN 0x00000100
+#define MSC_SUPPORT_UNBLOCKPIN 0x00000200
+#define MSC_SUPPORT_LISTPINS 0x00000400
+#define MSC_SUPPORT_CREATEOBJECT 0x00000800
+#define MSC_SUPPORT_DELETEOBJECT 0x00001000
+#define MSC_SUPPORT_WRITEOBJECT 0x00002000
+#define MSC_SUPPORT_READOBJECT 0x00004000
+#define MSC_SUPPORT_LISTOBJECTS 0x00008000
+#define MSC_SUPPORT_LOGOUTALL 0x00010000
+#define MSC_SUPPORT_GETCHALLENGE 0x00020000
+
+ /*
+ * Bitmask for MSC_TAG_SUPPORT_CRYPTOALG
+ */
+#define MSC_SUPPORT_RSA 0x00000001 /* Supports RSA */
+#define MSC_SUPPORT_DSA 0x00000002 /* Supports DSA */
+#define MSC_SUPPORT_ECURVE 0x00000004 /* Supports Eliptic Curve */
+#define MSC_SUPPORT_ELGAMAL 0x00000008 /* Supports El Gamal */
+
+#define MSC_SUPPORT_DES 0x00000010 /* Supports DES */
+#define MSC_SUPPORT_3DES 0x00000020 /* Supports Triple DES */
+#define MSC_SUPPORT_IDEA 0x00000040 /* Supports IDEA */
+#define MSC_SUPPORT_AES 0x00000080 /* Supports AES */
+#define MSC_SUPPORT_BLOWFISH 0x00000100 /* Supports Blowfish */
+#define MSC_SUPPORT_TWOFISH 0x00000200 /* Supports Twofish */
+#define MSC_SUPPORT_SHA1 0x00000400 /* Supports SHA1 */
+#define MSC_SUPPORT_MD5 0x00000800 /* Supports MD5 */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_RSA
+ */
+#define MSC_CAPABLE_RSA_512 0x00000001 /* Supports 512 bit RSA */
+#define MSC_CAPABLE_RSA_768 0x00000002 /* Supports 768 bit RSA */
+#define MSC_CAPABLE_RSA_1024 0x00000004 /* Supports 1024 bit RSA */
+#define MSC_CAPABLE_RSA_2048 0x00000008 /* Supports 2048 bit RSA */
+#define MSC_CAPABLE_RSA_4096 0x00000010 /* Supports 4096 bit RSA */
+
+#define MSC_CAPABLE_RSA_KEYGEN 0x00001000 /* Support RSA key-gen */
+#define MSC_CAPABLE_RSA_NOPAD 0x00002000 /* Supports RSA NO PAD */
+#define MSC_CAPABLE_RSA_PKCS1 0x00004000 /* Supports PKCS padding */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_DSA
+ */
+#define MSC_CAPABLE_DSA_512 0x00000001 /* Supports 512 bit DSA */
+#define MSC_CAPABLE_DSA_768 0x00000002 /* Supports 768 bit DSA */
+#define MSC_CAPABLE_DSA_1024 0x00000004 /* Supports 1024 bit DSA */
+#define MSC_CAPABLE_DSA_2048 0x00000008 /* Supports 2048 bit DSA */
+#define MSC_CAPABLE_DSA_4096 0x00000010 /* Supports 4096 bit DSA */
+#define MSC_CAPABLE_DSA_KEYGEN 0x00001000 /* Supports DSA key-gen */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_DES
+ */
+#define MSC_CAPABLE_DES_KEYGEN 0x00001000 /* Supports DES key-gen */
+#define MSC_CAPABLE_DES_CBC 0x00002000 /* Supports DES CBC mode */
+#define MSC_CAPABLE_DES_EBC 0x00004000 /* Supports DES EBC mode */
+#define MSC_CAPABLE_DES_ECB 0x00008000 /* Supports DES ECB mode */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_3DES
+ */
+#define MSC_CAPABLE_3DES_KEYGEN 0x00001000 /* Supports 3DES key-gen */
+#define MSC_CAPABLE_3DES_3KEY 0x00002000 /* Support 3 key 3DES */
+#define MSC_CAPABLE_3DES_CBC 0x00004000 /* Supports 3DES CBC mode */
+#define MSC_CAPABLE_3DES_EBC 0x00008000 /* Supports 3DES EBC mode */
+#define MSC_CAPABLE_3DES_ECB 0x00010000 /* Supports 3DES ECB mode */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_IDEA
+ */
+#define MSC_CAPABLE_IDEA_KEYGEN 0x00001000 /* Supports IDEA key-gen */
+#define MSC_CAPABLE_IDEA_CBC 0x00002000 /* Supports IDEA CBC mode */
+#define MSC_CAPABLE_IDEA_ECB 0x00008000 /* Supports IDEA ECB mode */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_AES
+ */
+#define MSC_CAPABLE_AES_KEYGEN 0x00001000 /* Supports AES key-gen */
+#define MSC_CAPABLE_AES_CBC 0x00002000 /* Supports AES CBC mode */
+#define MSC_CAPABLE_AES_ECB 0x00008000 /* Supports AES ECB mode */
+
+ /***********************************
+ Bitmasks for other crypto algorithms
+ will come in future releases
+ ************************************/
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_OBJ_ATTR
+ */
+#define MSC_CAPABLE_OBJ_ZERO 0x00010000 /* Supports zero on DEL */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_PIN_ATTR
+ */
+#define MSC_CAPABLE_PIN_RESET 0x00000100 /* Unblock reset's pin */
+#define MSC_CAPABLE_PIN_LEAVE 0x00000200 /* Unblock leaves pin */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_PIN_CHARSET
+ */
+#define MSC_CAPABLE_PIN_A_Z 0x00000001 /* Supports uppercase A-Z */
+#define MSC_CAPABLE_PIN_a_z 0x00000002 /* Supports lowercase a-z */
+#define MSC_CAPABLE_PIN_0_9 0x00000004 /* Supports numbers 0-9 */
+#define MSC_CAPABLE_PIN_SPACE 0x00000008 /* Supports spaces */
+#define MSC_CAPABLE_PIN_CALC 0x00000010 /* Supports + - / * % .= */
+#define MSC_CAPABLE_PIN_NONALPHA 0x00000020 /* Supports all other
+ * chars */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_PIN_POLICY
+ */
+#define MSC_CAPABLE_PIN_A_Z 0x00000001 /* Requires uppercase A-Z */
+#define MSC_CAPABLE_PIN_a_z 0x00000002 /* Requires lowercase a-z */
+#define MSC_CAPABLE_PIN_0_9 0x00000004 /* Requires numbers 0-9 */
+#define MSC_CAPABLE_PIN_NONALPHA 0x00000020 /* Requires
+ * non-alphanumeric */
+#define MSC_CAPABLE_PIN_HISTORY 0x00001000 /* Checks pin history */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_ID_STATE
+ */
+#define MSC_CAPABLE_ID_STATE 0x00000001 /* maintains logged id
+ * state */
+
+ /*
+ * Bitmask for TAG MSC_TAG_CAPABLE_RANDOM
+ */
+#define MSC_CAPABLE_RANDOM_SEED 0x00000001 /* Uses supplied seed */
+
+ /*
+ * Structure used in MSCGetStatus to return status and capability
+ * information about the inserted token
+ */
+
+ typedef struct
+ {
+ MSCUShort16 appVersion; /* Applet version number */
+ MSCUShort16 swVersion; /* Software version number */
+ MSCULong32 freeMemory; /* Free memory for objects */
+ MSCULong32 totalMemory; /* Total amount of memory */
+ MSCUChar8 usedPINs; /* Number of pins used */
+ MSCUChar8 usedKeys; /* Number of keys used */
+ MSCUShort16 loggedID; /* Bitmask of ID's verified */
+ }
+ MSCStatusInfo, *MSCLPStatusInfo;
+
+ typedef struct
+ {
+ MSCChar8 objectID[MSC_MAXSIZE_OBJID];
+ MSCULong32 objectSize;
+ MSCObjectACL objectACL;
+ }
+ MSCObjectInfo, *MSCLPObjectInfo;
+
+ /*******************************************************************/
+ /*
+ * Connection oriented functions
+ */
+ /*
+ * These functions do not coorespond to internal library funcions
+ */
+ /*
+ * but serve to connect to tokens. You can still use the internal
+ */
+ /*
+ * PC/SC calls to do this. These provide an abstract means.
+ */
+ /*******************************************************************/
+
+ /*
+ * Lists all known tokens on the system
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCListTokens(MSCULong32 listScope, /* defines the scope to
+ * return */
+ MSCLPTokenInfo tokenArray, /* token struct array */
+ MSCPULong32 arrayLength /* Length of array */
+ );
+
+ /*
+ * Establishes a connection to the specified token
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCEstablishConnection(MSCLPTokenInfo tokenStruct, /* The
+ * struct
+ * of
+ * token */
+ MSCULong32 sharingMode, /* Mode of sharing */
+ MSCPUChar8 applicationName, /* The applet ID/Name */
+ MSCULong32 nameSize, /* The ID/Name Size */
+ MSCLPTokenConnection pConnection /* Returned connection */
+ );
+
+ /*
+ * Releases a connection to the specified token
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCReleaseConnection(MSCLPTokenConnection pConnection, /* Connection
+ * handle
+ */
+ MSCULong32 endAction /* Action to perform */
+ );
+
+ /*
+ * Blocks for an event to occur on a token
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCWaitForTokenEvent(MSCLPTokenInfo tokenArray, /* Array of
+ * token
+ * structs */
+ MSCULong32 arraySize, /* Size of the array */
+ MSCULong32 timeoutValue /* Timeout */
+ );
+
+ /*
+ * Cancels a pending MSCWaitForTokenEvent
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCCancelEventWait(void /* No parameters */
+ );
+
+ /*
+ * Registers a callback function for event change
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCCallbackForTokenEvent(MSCLPTokenInfo tokenArray, /* Array
+ * of
+ * token
+ * structs
+ */
+ MSCULong32 arraySize, /* Size of the array */
+ MSCCallBack callBack, /* Callback function */
+ MSCPVoid32 appData /* Application data */
+ );
+
+ /*
+ * Cancels all callback registrations
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCCallbackCancelEvent();
+
+ /*
+ * Locks a transaction to the token
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCBeginTransaction(MSCLPTokenConnection pConnection /* Connection
+ * handle */
+ );
+
+ /*
+ * Releases a locked transaction to the token
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCEndTransaction(MSCLPTokenConnection pConnection, /* Connection
+ * handle */
+ MSCULong32 endAction /* Action to perform on token */
+ );
+
+ /*
+ * Selects applet - Not to be used by applications
+ */
+ MSC_RV MSCSelectAID(MSCLPTokenConnection pConnection,
+ MSCPUChar8 aidValue, MSCULong32 aidSize);
+
+ /*
+ * Pre-personalization function
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCWriteFramework(MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams);
+
+ /*****************************************************************/
+ /*
+ * Core Musclecard functions
+ */
+ /*
+ * These functions coorespond directly to internal library
+ */
+ /*
+ * functions.
+ */
+ /*****************************************************************/
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCGetStatus(MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCGetCapabilities(MSCLPTokenConnection pConnection,
+ MSCULong32 Tag, MSCPUChar8 Value, MSCPULong32 Length);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCExtendedFeature(MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature,
+ MSCPUChar8 outData,
+ MSCULong32 outLength, MSCPUChar8 inData, MSCPULong32 inLength);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCGenerateKeys(MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum,
+ MSCUChar8 pubKeyNum, MSCLPGenKeyParams pParams);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCImportKey(MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL,
+ MSCPUChar8 pKeyBlob,
+ MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCExportKey(MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob,
+ MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams, MSCUChar8 addParamsSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCComputeCrypt(MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit,
+ MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize,
+ MSCPUChar8 pOutputData, MSCPULong32 outputDataSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCExtAuthenticate(MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData,
+ MSCULong32 dataSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCListKeys(MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCCreatePIN(MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize,
+ MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCVerifyPIN(MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCChangePIN(MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode,
+ MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode, MSCUChar8 newPinCodeSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCUnblockPIN(MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode, MSCULong32 unblockCodeSize);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCListPINs(MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCCreateObject(MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 objectSize, MSCLPObjectACL pObjectACL);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCDeleteObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCUChar8 zeroFlag);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCWriteObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offset,
+ MSCPUChar8 pInputData, MSCULong32 dataSize,
+ LPRWEventCallback rwCallback, MSCPVoid32 addParams);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCReadObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCULong32 offset,
+ MSCPUChar8 pOutputData, MSCULong32 dataSize,
+ LPRWEventCallback rwCallback, MSCPVoid32 addParams);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCReadAllocateObject(MSCLPTokenConnection pConnection,
+ MSCString objectID, MSCPUChar8 *pOutputData,
+ MSCPULong32 dataSize,
+ LPRWEventCallback rwCallback, MSCPVoid32 addParams);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCListObjects(MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption, MSCLPObjectInfo pObjectInfo);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCLogoutAll(MSCLPTokenConnection pConnection);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCGetChallenge(MSCLPTokenConnection pConnection,
+ MSCPUChar8 pSeed,
+ MSCUShort16 seedSize,
+ MSCPUChar8 pRandomData, MSCUShort16 randomDataSize);
+
+ /*****************************************************************/
+ /*
+ * Extended Musclecard functions
+ */
+ /*
+ * These functions do not coorespond to internal library funcions
+ */
+ /*
+ * but rather use them to provide some extended functionality.
+ */
+ /*****************************************************************/
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCGetKeyAttributes(MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNumber,
+ MSCLPKeyInfo pKeyInfo);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSC_RV MSCGetObjectAttributes(MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCLPObjectInfo pObjectInfo);
+
+#ifdef WIN32
+ PCSC_API
+#endif
+ char *msc_error(unsigned long int errorCode);
+
+ /*
+ * Was the token reset ?
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSCUChar8 MSCIsTokenReset(MSCLPTokenConnection pConnection);
+
+ /*
+ * Clear the Reset state
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSCUChar8 MSCClearReset(MSCLPTokenConnection pConnection);
+
+ /*
+ * Was the token moved (removed, removed/inserted) ?
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSCUChar8 MSCIsTokenMoved(MSCLPTokenConnection pConnection);
+
+ /*
+ * Did any state change with the token ?
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSCUChar8 MSCIsTokenChanged(MSCLPTokenConnection pConnection);
+
+ /*
+ * Is the token recognized ?
+ */
+#ifdef WIN32
+ PCSC_API
+#endif
+ MSCUChar8 MSCIsTokenKnown(MSCLPTokenConnection pConnection);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __musclecard_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/muscletest.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/muscletest.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/muscletest.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,372 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : test.c
+ Package: card edge
+ Author : David Corcoran
+ Date : 10/04/01
+ License: Copyright (C) 2001 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This tests the virtual card edge
+
+
+********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <winscard.h>
+#include <mscdefines.h>
+#include <musclecard.h>
+
+#define MY_OBJECT_ID "c1"
+#define MY_OBJECT_SIZE 50
+
+#ifdef MSC_ARCH_WIN32
+MSCString pcsc_stringify_error(MSCLong32 Error);
+#endif
+
+int main(int argc, char **argv)
+{
+
+ MSCLong32 rv;
+ MSCTokenConnection pConnection;
+ MSCStatusInfo statusInf;
+ MSCObjectACL objACL;
+ MSCObjectInfo objInfo;
+ MSCUChar8 pRandomData[20];
+ MSCUChar8 pSeed[8];
+ MSCUChar8 defaultPIN[16];
+ MSCUChar8 AID[6] = { 0xA0, 0x00, 0x00, 0x00, 0x01, 0x01 };
+ MSCUChar8 myData[] =
+ { 'M', 'U', 'S', 'C', 'L', 'E', ' ', 'V', 'I', 'R',
+ 'T', 'U', 'A', 'L', ' ', 'C', 'A', 'R', 'D', '.', 0
+ };
+ MSCUChar8 readData[50];
+ MSCLPTokenInfo tokenList;
+ MSCULong32 tokenSize;
+ int i, j;
+
+ printf("********************************************************\n");
+ printf("\n");
+
+ tokenList = 0;
+ tokenSize = 0;
+
+ rv = MSCListTokens(MSC_LIST_SLOTS, tokenList, &tokenSize);
+ if (rv != MSC_SUCCESS)
+ {
+ printf("MSCListTokens returns : %s\n", msc_error(rv));
+ return -1;
+ }
+
+ tokenList = (MSCLPTokenInfo) malloc(sizeof(MSCTokenInfo) * tokenSize);
+
+ rv = MSCListTokens(MSC_LIST_SLOTS, tokenList, &tokenSize);
+ if (rv != MSC_SUCCESS)
+ {
+ printf("MSCListTokens returns : %s\n", msc_error(rv));
+ return -1;
+ }
+
+ for (i = 0; i < tokenSize; i++)
+ {
+ printf("Token #%d\n", i);
+ printf("Token name : %s\n", tokenList[i].tokenName);
+ printf("Slot name : %s\n", tokenList[i].slotName);
+ printf("Token id : ");
+ for (j = 0; j < tokenList[i].tokenIdLength; j++)
+ {
+ printf("%02X", tokenList[i].tokenId[j]);
+ }
+ printf("\n");
+ printf("Token state : %ld\n", tokenList[i].tokenState);
+ printf("\n");
+
+ tokenList[i].tokenState = MSC_STATE_EMPTY;
+ }
+
+ printf("********************************************************\n");
+
+ rv = MSCWaitForTokenEvent(tokenList, tokenSize, MSC_NO_TIMEOUT);
+
+ for (i = 0; i < tokenSize; i++)
+ {
+ printf("Token #%d\n", i);
+ printf("Token name : %s\n", tokenList[i].tokenName);
+ printf("Slot name : %s\n", tokenList[i].slotName);
+ printf("Token id : ");
+ for (j = 0; j < tokenList[i].tokenIdLength; j++)
+ {
+ printf("%02X", tokenList[i].tokenId[j]);
+ }
+ printf("\n");
+ printf("Token state : %ld\n", tokenList[i].tokenState);
+ printf("\n");
+ }
+
+ rv = MSCEstablishConnection(&tokenList[0], MSC_SHARE_SHARED, AID,
+ 6, &pConnection);
+ if (rv != MSC_SUCCESS)
+ {
+ printf("EstablishConn returns : %s\n", msc_error(rv));
+ return -1;
+ }
+
+ rv = MSCBeginTransaction(&pConnection);
+ printf("BeginTransaction returns : %s\n", msc_error(rv));
+
+ rv = MSCGetStatus(&pConnection, &statusInf);
+ printf("GetStatus returns : %s\n", msc_error(rv));
+ printf("Protocol version : %04x\n", statusInf.appVersion);
+ printf("Applet version : %04x\n", statusInf.swVersion);
+ printf("Total object memory : %08ld\n", statusInf.totalMemory);
+ printf("Free object memory : %08ld\n", statusInf.freeMemory);
+ printf("Number of used PINs : %02d\n", statusInf.usedPINs);
+ printf("Number of used Keys : %02d\n", statusInf.usedKeys);
+ printf("Currently logged identities : %04x\n", statusInf.loggedID);
+
+ printf("Please enter the pin value\n");
+ fgets(defaultPIN, sizeof(defaultPIN), stdin);
+
+ rv = MSCVerifyPIN(&pConnection, 0, defaultPIN, strlen(defaultPIN) - 1);
+ printf("Verify default PIN : %s\n", msc_error(rv));
+
+ rv = MSCGetStatus(&pConnection, &statusInf);
+ printf("Currently logged identities : %04x\n", statusInf.loggedID);
+
+ objACL.readPermission = MSC_AUT_ALL;
+ objACL.writePermission = MSC_AUT_ALL;
+ objACL.deletePermission = MSC_AUT_ALL;
+
+ rv = MSCCreateObject(&pConnection, MY_OBJECT_ID, MY_OBJECT_SIZE,
+ &objACL);
+ printf("CreateObject returns : %s\n", msc_error(rv));
+
+ rv = MSCWriteObject(&pConnection, MY_OBJECT_ID, 0, myData,
+ sizeof(myData), 0, 0);
+ printf("WriteObject returns : %s\n", msc_error(rv));
+
+ rv = MSCReadObject(&pConnection, MY_OBJECT_ID, 0, readData, 25, 0, 0);
+ printf("ReadObject returns : %s\n", msc_error(rv));
+
+ if (rv == MSC_SUCCESS)
+ {
+ printf("Object data : %s\n", readData);
+ if (strcmp(readData, myData) == 0)
+ {
+ printf("Data comparison : Successful\n");
+ } else
+ {
+ printf("Data comparison : Data mismatch\n");
+ }
+ }
+
+ rv = MSCListObjects(&pConnection, MSC_SEQUENCE_RESET, &objInfo);
+
+ printf("\n");
+ printf("Listing objects : %s\n", msc_error(rv));
+ printf("------------------------------------------------------\n");
+ printf("%20s %12s %6s %6s %6s\n", "Object ID", "Object Size",
+ "READ", "WRITE", "DELETE");
+ printf(" ----------------- ----------- ---- ----- ------\n");
+
+ if (rv == MSC_SUCCESS)
+ {
+ printf("%20s %12d %04x %04x %04x\n", objInfo.objectID,
+ objInfo.objectSize,
+ objInfo.objectACL.readPermission,
+ objInfo.objectACL.writePermission,
+ objInfo.objectACL.deletePermission);
+ }
+
+ do
+ {
+ rv = MSCListObjects(&pConnection, MSC_SEQUENCE_NEXT, &objInfo);
+ if (rv == MSC_SUCCESS)
+ {
+ printf("%20s %12d %04x %04x %04x\n", objInfo.objectID,
+ objInfo.objectSize,
+ objInfo.objectACL.readPermission,
+ objInfo.objectACL.writePermission,
+ objInfo.objectACL.deletePermission);
+ } else
+ {
+ break;
+ }
+
+ }
+ while (1);
+
+ printf("------------------------------------------------------\n");
+ printf("\n");
+
+ rv = MSCGetStatus(&pConnection, &statusInf);
+ printf("Free object memory : %08ld\n", statusInf.freeMemory);
+
+ rv = MSCDeleteObject(&pConnection, MY_OBJECT_ID, MSC_ZF_DEFAULT);
+ printf("DeleteObject returns : %s\n", msc_error(rv));
+
+ rv = MSCGetStatus(&pConnection, &statusInf);
+ printf("Free object memory : %08ld\n", statusInf.freeMemory);
+
+ rv = MSCGetChallenge(&pConnection, pSeed, 0, pRandomData, 8);
+ printf("GetChallenge returns : %s\n", msc_error(rv));
+ printf("Random data : ");
+
+ for (i = 0; i < 8; i++)
+ {
+ printf("%x ", pRandomData[i]);
+ }
+ printf("\n");
+
+ rv = MSCLogoutAll(&pConnection);
+ printf("Logout all identities : %s\n", msc_error(rv));
+
+ rv = MSCGetStatus(&pConnection, &statusInf);
+ printf("Currently logged identities : %04x\n", statusInf.loggedID);
+
+ rv = MSCEndTransaction(&pConnection, SCARD_LEAVE_CARD);
+ printf("EndTransaction returns : %s\n", msc_error(rv));
+
+ MSCReleaseConnection(&pConnection, SCARD_LEAVE_CARD);
+ printf("ReleaseConn returns : %s\n", msc_error(rv));
+
+ return 0;
+}
+
+#ifdef MSC_ARCH_WIN32
+MSCString pcsc_stringify_error(MSCLong32 Error)
+{
+
+ static char strError[75];
+
+ switch (Error)
+ {
+ case SCARD_S_SUCCESS:
+ strcpy(strError, "Command successful.");
+ break;
+ case SCARD_E_CANCELLED:
+ strcpy(strError, "Command cancelled.");
+ break;
+ case SCARD_E_CANT_DISPOSE:
+ strcpy(strError, "Cannot dispose handle.");
+ break;
+ case SCARD_E_INSUFFICIENT_BUFFER:
+ strcpy(strError, "Insufficient buffer.");
+ break;
+ case SCARD_E_INVALID_ATR:
+ strcpy(strError, "Invalid ATR.");
+ break;
+ case SCARD_E_INVALID_HANDLE:
+ strcpy(strError, "Invalid handle.");
+ break;
+ case SCARD_E_INVALID_PARAMETER:
+ strcpy(strError, "Invalid parameter given.");
+ break;
+ case SCARD_E_INVALID_TARGET:
+ strcpy(strError, "Invalid target given.");
+ break;
+ case SCARD_E_INVALID_VALUE:
+ strcpy(strError, "Invalid value given.");
+ break;
+ case SCARD_E_NO_MEMORY:
+ strcpy(strError, "Not enough memory.");
+ break;
+ case SCARD_F_COMM_ERROR:
+ strcpy(strError, "RPC transport error.");
+ break;
+ case SCARD_F_INTERNAL_ERROR:
+ strcpy(strError, "Unknown internal error.");
+ break;
+ case SCARD_F_UNKNOWN_ERROR:
+ strcpy(strError, "Unknown internal error.");
+ break;
+ case SCARD_F_WAITED_TOO_MSCLong32:
+ strcpy(strError, "Waited too long.");
+ break;
+ case SCARD_E_UNKNOWN_READER:
+ strcpy(strError, "Unknown reader specified.");
+ break;
+ case SCARD_E_TIMEOUT:
+ strcpy(strError, "Command timeout.");
+ break;
+ case SCARD_E_SHARING_VIOLATION:
+ strcpy(strError, "Sharing violation.");
+ break;
+ case SCARD_E_NO_SMARTCARD:
+ strcpy(strError, "No smartcard inserted.");
+ break;
+ case SCARD_E_UNKNOWN_CARD:
+ strcpy(strError, "Unknown card.");
+ break;
+ case SCARD_E_PROTO_MISMATCH:
+ strcpy(strError, "Card protocol mismatch.");
+ break;
+ case SCARD_E_NOT_READY:
+ strcpy(strError, "Subsystem not ready.");
+ break;
+ case SCARD_E_SYSTEM_CANCELLED:
+ strcpy(strError, "System cancelled.");
+ break;
+ case SCARD_E_NOT_TRANSACTED:
+ strcpy(strError, "Transaction failed.");
+ break;
+ case SCARD_E_READER_UNAVAILABLE:
+ strcpy(strError, "Reader/s is unavailable.");
+ break;
+ case SCARD_W_UNSUPPORTED_CARD:
+ strcpy(strError, "Card is not supported.");
+ break;
+ case SCARD_W_UNRESPONSIVE_CARD:
+ strcpy(strError, "Card is unresponsive.");
+ break;
+ case SCARD_W_UNPOWERED_CARD:
+ strcpy(strError, "Card is unpowered.");
+ break;
+ case SCARD_W_RESET_CARD:
+ strcpy(strError, "Card was reset.");
+ break;
+ case SCARD_W_REMOVED_CARD:
+ strcpy(strError, "Card was removed.");
+ break;
+ case SCARD_E_PCI_TOO_SMALL:
+ strcpy(strError, "PCI struct too small.");
+ break;
+ case SCARD_E_READER_UNSUPPORTED:
+ strcpy(strError, "Reader is unsupported.");
+ break;
+ case SCARD_E_DUPLICATE_READER:
+ strcpy(strError, "Reader already exists.");
+ break;
+ case SCARD_E_CARD_UNSUPPORTED:
+ strcpy(strError, "Card is unsupported.");
+ break;
+ case SCARD_E_NO_SERVICE:
+ strcpy(strError, "Service not available.");
+ break;
+ case SCARD_E_SERVICE_STOPPED:
+ strcpy(strError, "Service was stopped.");
+ break;
+
+ };
+
+ return strError;
+}
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdaemon.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdaemon.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdaemon.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,699 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * pcscdaemon.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2005
+ * David Corcoran <corcoran at linuxnet.com>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: pcscdaemon.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This is the main pcscd daemon.
+ *
+ * The function \c main() starts up the communication environment.\n
+ * Then an endless loop is calld to look for Client connections. For each
+ * Client connection a call to \c CreateContextThread() is done.
+ */
+
+#include "config.h"
+#include <time.h>
+#include <syslog.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "debuglog.h"
+#include "winscard_msg.h"
+#include "winscard_svc.h"
+#include "sys_generic.h"
+#include "thread_generic.h"
+#include "hotplug.h"
+#include "readerfactory.h"
+#include "configfile.h"
+#include "powermgt_generic.h"
+
+#include <security_utilities/debugging.h>
+
+char AraKiri = 0;
+static char Init = 1;
+int HPForceReaderPolling = 0;
+
+/*
+ * Some internal functions
+ */
+void SVCServiceRunLoop(void);
+void SVCClientCleanup(psharedSegmentMsg);
+void at_exit(void);
+void clean_temp_files(void);
+void signal_reload(int sig);
+void signal_trap(int);
+void print_version (void);
+void print_usage (char const * const);
+int ProcessHotplugRequest();
+
+PCSCLITE_MUTEX usbNotifierMutex;
+
+#ifdef USE_RUN_PID
+pid_t GetDaemonPid(void);
+pid_t GetDaemonPid(void)
+{
+ FILE *f;
+ pid_t pid;
+
+ /* pids are only 15 bits but 4294967296
+ * (32 bits in case of a new system use it) is on 10 bytes
+ */
+ if ((f = fopen(USE_RUN_PID, "rb")) != NULL)
+ {
+#define PID_ASCII_SIZE 11
+ char pid_ascii[PID_ASCII_SIZE];
+
+ fgets(pid_ascii, PID_ASCII_SIZE, f);
+ fclose(f);
+
+ pid = atoi(pid_ascii);
+ }
+ else
+ {
+ Log2(PCSC_LOG_CRITICAL, "Can't open " USE_RUN_PID ": %s",
+ strerror(errno));
+ return -1;
+ }
+
+ return pid;
+} /* GetDaemonPid */
+#endif
+
+int SendHotplugSignal(void)
+{
+#ifdef USE_RUN_PID
+ pid_t pid;
+
+ pid = GetDaemonPid();
+
+ if (pid != -1)
+ {
+ Log2(PCSC_LOG_INFO, "Send hotplug signal to pcscd (pid=%d)", pid);
+ if (kill(pid, SIGUSR1) < 0)
+ {
+ Log3(PCSC_LOG_CRITICAL, "Can't signal pcscd (pid=%d): %s",
+ pid, strerror(errno));
+ return EXIT_FAILURE ;
+ }
+ }
+#endif
+
+ return EXIT_SUCCESS;
+} /* SendHotplugSignal */
+
+int ProcessHotplugRequest()
+{
+#ifdef USE_RUN_PID
+
+ /* read the pid file to get the old pid and test if the old pcscd is
+ * still running
+ */
+ if (GetDaemonPid() != -1)
+ return SendHotplugSignal();
+
+ Log1(PCSC_LOG_CRITICAL, "file " USE_RUN_PID " does not exist");
+ Log1(PCSC_LOG_CRITICAL, "Perhaps pcscd is not running?");
+#else
+ struct stat tmpStat;
+ if (SYS_Stat(PCSCLITE_CSOCK_NAME, &tmpStat) == 0) // socket file exists, so maybe pcscd is running
+ return SendHotplugSignal();
+ Log1(PCSC_LOG_CRITICAL, "pcscd was not configured with --enable-runpid=FILE");
+#endif
+ Log1(PCSC_LOG_CRITICAL, "Hotplug failed");
+ return EXIT_FAILURE;
+}
+
+/*
+ * Cleans up messages still on the queue when a client dies
+ */
+void SVCClientCleanup(psharedSegmentMsg msgStruct)
+{
+ /*
+ * May be implemented in future releases
+ */
+}
+
+/**
+ * @brief The Server's Message Queue Listener function.
+ *
+ * An endless loop calls the function \c SHMProcessEventsServer() to check for
+ * messages sent by clients.
+ * If the message is valid, \c CreateContextThread() is called to serve this
+ * request.
+ */
+void SVCServiceRunLoop(void)
+{
+ int rsp;
+ LONG rv;
+ DWORD dwClientID; /* Connection ID used to reference the Client */
+
+ rsp = 0;
+ rv = 0;
+
+ /*
+ * Initialize the comm structure
+ */
+ rsp = SHMInitializeCommonSegment();
+
+ if (rsp == -1)
+ {
+ Log1(PCSC_LOG_CRITICAL, "Error initializing pcscd.");
+ exit(-1);
+ }
+
+ /*
+ * Initialize the contexts structure
+ */
+ rv = ContextsInitialize();
+
+ if (rv == -1)
+ {
+ Log1(PCSC_LOG_CRITICAL, "Error initializing pcscd.");
+ exit(-1);
+ }
+
+ /*
+ * Solaris sends a SIGALRM and it is annoying
+ */
+
+ signal(SIGALRM, SIG_IGN);
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGHUP, SIG_IGN); /* needed for Solaris. The signal is sent
+ * when the shell is existed */
+
+ /*
+ * This function always returns zero
+ */
+ rsp = SYS_MutexInit(&usbNotifierMutex);
+
+ /*
+ * Set up the search for USB/PCMCIA devices
+ */
+ HPSearchHotPluggables();
+ HPRegisterForHotplugEvents();
+
+ /*
+ * Set up the power management callback routine
+ */
+// PMRegisterForPowerEvents();
+
+ while (1)
+ {
+ switch (rsp = SHMProcessEventsServer(&dwClientID, 0))
+ {
+
+ case 0:
+ Log2(PCSC_LOG_DEBUG, "A new context thread creation is requested: %d", dwClientID);
+ rv = CreateContextThread(&dwClientID);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log1(PCSC_LOG_ERROR, "Problem during the context thread creation");
+ AraKiri = 1;
+ }
+
+ break;
+
+ case 2:
+ /*
+ * timeout in SHMProcessEventsServer(): do nothing
+ * this is used to catch the Ctrl-C signal at some time when
+ * nothing else happens
+ */
+ break;
+
+ case -1:
+ Log1(PCSC_LOG_ERROR, "Error in SHMProcessEventsServer");
+ break;
+
+ case -2:
+ /* Nothing to do in case of a syscall interrupted
+ * It happens when SIGUSR1 (reload) or SIGINT (Ctrl-C) is received
+ * We just try again */
+ break;
+
+ default:
+ Log2(PCSC_LOG_ERROR, "SHMProcessEventsServer unknown retval: %d",
+ rsp);
+ break;
+ }
+
+ if (AraKiri)
+ {
+ /* stop the hotpug thread and waits its exit */
+// HPStopHotPluggables();
+ SYS_Sleep(1);
+
+ /* now stop all the drivers */
+ RFCleanupReaders(1);
+ }
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int rv;
+ char setToForeground;
+ char HotPlug;
+ char *newReaderConfig;
+ struct stat fStatBuf;
+ int opt;
+#ifdef HAVE_GETOPT_LONG
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"config", 1, 0, 'c'},
+ {"foreground", 0, 0, 'f'},
+ {"help", 0, 0, 'h'},
+ {"version", 0, 0, 'v'},
+ {"apdu", 0, 0, 'a'},
+ {"debug", 0, 0, 'd'},
+ {"info", 0, 0, 0},
+ {"error", 0, 0, 'e'},
+ {"critical", 0, 0, 'C'},
+ {"hotplug", 0, 0, 'H'},
+ {"force-reader-polling", optional_argument, 0, 0},
+ {0, 0, 0, 0}
+ };
+#endif
+#define OPT_STRING "c:fdhvaeCH"
+
+ rv = 0;
+ newReaderConfig = NULL;
+ setToForeground = 0;
+ HotPlug = 0;
+
+ /*
+ * test the version
+ */
+ if (strcmp(PCSCLITE_VERSION_NUMBER, VERSION) != 0)
+ {
+ printf("BUILD ERROR: The release version number PCSCLITE_VERSION_NUMBER\n");
+ printf(" in pcsclite.h (%s) does not match the release version number\n",
+ PCSCLITE_VERSION_NUMBER);
+ printf(" generated in config.h (%s) (see configure.in).\n", VERSION);
+
+ return EXIT_FAILURE;
+ }
+
+ /*
+ * By default we create a daemon (not connected to any output)
+ * The log will go to wherever securityd log output goes.
+ */
+ DebugLogSetLogType(DEBUGLOG_NO_DEBUG);
+
+ /*
+ * Handle any command line arguments
+ */
+#ifdef HAVE_GETOPT_LONG
+ while ((opt = getopt_long (argc, argv, OPT_STRING, long_options, &option_index)) != -1) {
+#else
+ while ((opt = getopt (argc, argv, OPT_STRING)) != -1) {
+#endif
+ switch (opt) {
+#ifdef HAVE_GETOPT_LONG
+ case 0:
+ if (strcmp(long_options[option_index].name,
+ "force-reader-polling") == 0)
+ HPForceReaderPolling = optarg ? abs(atoi(optarg)) : 1;
+ break;
+#endif
+ case 'c':
+ Log2(PCSC_LOG_INFO, "using new config file: %s", optarg);
+ newReaderConfig = optarg;
+ break;
+
+ case 'f':
+ setToForeground = 1;
+ /* debug to stderr instead of default syslog */
+ Log1(PCSC_LOG_INFO,
+ "pcscd set to foreground with debug send to stderr");
+ break;
+
+ case 'd':
+ DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);
+ DebugLogSetLevel(PCSC_LOG_DEBUG);
+ break;
+
+ case 'e':
+ DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);
+ DebugLogSetLevel(PCSC_LOG_ERROR);
+ break;
+
+ case 'C':
+ DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);
+ DebugLogSetLevel(PCSC_LOG_CRITICAL);
+ break;
+
+ case 'h':
+ print_usage (argv[0]);
+ return EXIT_SUCCESS;
+
+ case 'v':
+ print_version ();
+ return EXIT_SUCCESS;
+
+ case 'a':
+ DebugLogSetCategory(DEBUG_CATEGORY_APDU);
+ break;
+
+ case 'H':
+ /* debug to stderr instead of default syslog */
+ DebugLogSetLogType(DEBUGLOG_STDERR_DEBUG);
+ HotPlug = 1;
+ break;
+
+ default:
+ print_usage (argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ }
+
+ if (argv[optind])
+ {
+ printf("Unknown option: %s\n\n", argv[optind]);
+ print_usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ /*
+ If this run of pcscd has the hotplug option, just send a signal to the
+ running one and exit
+ */
+
+ if (HotPlug)
+ return ProcessHotplugRequest();
+
+ /*
+ * test the presence of /var/run/pcsc.comm
+ */
+
+ rv = SYS_Stat(PCSCLITE_CSOCK_NAME, &fStatBuf);
+
+ if (rv == 0)
+ {
+#ifdef USE_RUN_PID
+ pid_t pid;
+
+ /* read the pid file to get the old pid and test if the old pcscd is
+ * still running
+ */
+ pid = GetDaemonPid();
+
+ if (pid != -1)
+ {
+ if (kill(pid, 0) == 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "Another pcscd (pid: %d) seems to be running.", pid);
+ Log1(PCSC_LOG_CRITICAL,
+ "Remove " USE_RUN_PID " if pcscd is not running to clear this message.");
+ return EXIT_FAILURE;
+ }
+ else
+ /* the old pcscd is dead. Do some cleanup */
+ clean_temp_files();
+ }
+#else
+ {
+ Log1(PCSC_LOG_CRITICAL,
+ "file " PCSCLITE_CSOCK_NAME " already exists.");
+ Log1(PCSC_LOG_CRITICAL,
+ "Maybe another pcscd is running?");
+ Log1(PCSC_LOG_CRITICAL,
+ "Remove " PCSCLITE_CSOCK_NAME "if pcscd is not running to clear this message.");
+ return EXIT_FAILURE;
+ }
+#endif
+ }
+
+ /*
+ * If this is set to one the user has asked it not to fork
+ */
+ if (!setToForeground)
+ {
+ if (SYS_Daemon(0, 0))
+ Log2(PCSC_LOG_CRITICAL, "SYS_Daemon() failed: %s",
+ strerror(errno));
+ }
+
+ /*
+ * cleanly remove /tmp/pcsc when exiting
+ */
+ signal(SIGQUIT, signal_trap);
+ signal(SIGTERM, signal_trap);
+ signal(SIGINT, signal_trap);
+ signal(SIGHUP, signal_trap);
+
+#ifdef USE_RUN_PID
+ /*
+ * Record our pid to make it easier
+ * to kill the correct pcscd
+ */
+ {
+ FILE *f;
+
+ if ((f = fopen(USE_RUN_PID, "wb")) != NULL)
+ {
+ fprintf(f, "%u\n", (unsigned) getpid());
+ fclose(f);
+ }
+ }
+#endif
+
+ /*
+ * If PCSCLITE_IPC_DIR does not exist then create it
+ */
+ rv = SYS_Stat(PCSCLITE_IPC_DIR, &fStatBuf);
+ if (rv < 0)
+ {
+ rv = SYS_Mkdir(PCSCLITE_IPC_DIR, S_ISVTX | S_IRWXO | S_IRWXG | S_IRWXU);
+ if (rv != 0)
+ {
+ Log2(PCSC_LOG_CRITICAL,
+ "cannot create " PCSCLITE_IPC_DIR ": %s", strerror(errno));
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* cleanly remove /var/run/pcsc.* files when exiting */
+ if (atexit(at_exit))
+ Log2(PCSC_LOG_CRITICAL, "atexit() failed: %s", strerror(errno));
+
+ /*
+ * Allocate memory for reader structures
+ */
+ RFAllocateReaderSpace();
+
+ /*
+ * Grab the information from the reader.conf
+ */
+ if (newReaderConfig)
+ {
+ rv = RFStartSerialReaders(newReaderConfig);
+ if (rv != 0)
+ {
+ Log3(PCSC_LOG_CRITICAL, "invalid file %s: %s", newReaderConfig,
+ strerror(errno));
+ at_exit();
+ }
+ }
+ else
+ {
+ rv = RFStartSerialReaders(PCSCLITE_READER_CONFIG);
+
+#if 0
+ if (rv == 1)
+ {
+ Log1(PCSC_LOG_INFO,
+ "warning: no " PCSCLITE_READER_CONFIG " found");
+ /*
+ * Token error in file
+ */
+ }
+ else
+#endif
+ if (rv == -1)
+ at_exit();
+ }
+
+ /*
+ * Set the default globals
+ */
+ g_rgSCardT0Pci.dwProtocol = SCARD_PROTOCOL_T0;
+ g_rgSCardT1Pci.dwProtocol = SCARD_PROTOCOL_T1;
+ g_rgSCardRawPci.dwProtocol = SCARD_PROTOCOL_RAW;
+
+ Log1(PCSC_LOG_INFO, "pcsc-lite " VERSION " daemon ready.");
+
+ /*
+ * post initialistion
+ */
+ Init = 0;
+
+ /*
+ * signal_trap() does just set a global variable used by the main loop
+ */
+ signal(SIGQUIT, signal_trap);
+ signal(SIGTERM, signal_trap);
+ signal(SIGINT, signal_trap);
+ signal(SIGHUP, signal_trap);
+
+ signal(SIGUSR1, signal_reload);
+
+ SVCServiceRunLoop();
+
+ Log1(PCSC_LOG_ERROR, "SVCServiceRunLoop returned");
+ return EXIT_FAILURE;
+}
+
+void at_exit(void)
+{
+ Log1(PCSC_LOG_INFO, "cleaning " PCSCLITE_IPC_DIR);
+
+ clean_temp_files();
+
+ SYS_Exit(EXIT_SUCCESS);
+}
+
+void clean_temp_files(void)
+{
+ int rv;
+
+ rv = SYS_Unlink(PCSCLITE_CSOCK_NAME);
+ if (rv != 0)
+ Log2(PCSC_LOG_ERROR, "Cannot unlink " PCSCLITE_CSOCK_NAME ": %s",
+ strerror(errno));
+
+#ifdef USE_RUN_PID
+ rv = SYS_Unlink(USE_RUN_PID);
+ if (rv != 0)
+ Log2(PCSC_LOG_ERROR, "Cannot unlink " USE_RUN_PID ": %s",
+ strerror(errno));
+#endif
+}
+
+void signal_reload(int sig)
+{
+ static int rescan_ongoing = 0;
+
+ if (AraKiri)
+ return;
+
+ Log1(PCSC_LOG_INFO, "Reload serial configuration");
+ if (rescan_ongoing)
+ {
+ Log1(PCSC_LOG_INFO, "Rescan already ongoing");
+ return;
+ }
+
+ rescan_ongoing = 0;
+
+ HPReCheckSerialReaders();
+
+ rescan_ongoing = 0;
+ Log1(PCSC_LOG_INFO, "End reload serial configuration");
+} /* signal_reload */
+
+void signal_trap(int sig)
+{
+ /* the signal handler is called several times for the same Ctrl-C */
+ if (AraKiri == 0)
+ {
+ Log1(PCSC_LOG_INFO, "Preparing for suicide");
+ AraKiri = 1;
+
+ /* if still in the init/loading phase the AraKiri will not be
+ * seen by the main event loop
+ */
+ if (Init)
+ {
+ Log1(PCSC_LOG_INFO, "Suicide during init");
+ at_exit();
+ }
+ }
+}
+
+void print_version (void)
+{
+ printf("%s version %s.\n", PACKAGE, VERSION);
+ printf("Copyright (C) 1999-2002 by David Corcoran <corcoran at linuxnet.com>.\n");
+ printf("Copyright (C) 2001-2005 by Ludovic Rousseau <ludovic.rousseau at free.fr>.\n");
+ printf("Copyright (C) 2003-2004 by Damien Sauveron <sauveron at labri.fr>.\n");
+ printf("Portions Copyright (C) 2000-2007 by Apple Inc.\n");
+ printf("Report bugs to <sclinux at linuxnet.com>.\n");
+}
+
+void print_usage (char const * const progname)
+{
+ printf("Usage: %s options\n", progname);
+ printf("Options:\n");
+#ifdef HAVE_GETOPT_LONG
+ printf(" -a, --apdu log APDU commands and results\n");
+ printf(" -c, --config path to reader.conf\n");
+ printf(" -f, --foreground run in foreground (no daemon),\n");
+ printf(" send logs to stderr instead of syslog\n");
+ printf(" -h, --help display usage information\n");
+ printf(" -H, --hotplug ask the daemon to rescan the available readers\n");
+ printf(" -v, --version display the program version number\n");
+ printf(" -d, --debug display lower level debug messages\n");
+ printf(" --info display info level debug messages (default level)\n");
+ printf(" -e --error display error level debug messages\n");
+ printf(" -C --critical display critical only level debug messages\n");
+ printf(" --force-reader-polling ignore the IFD_GENERATE_HOTPLUG reader capability\n");
+#else
+ printf(" -a log APDU commands and results\n");
+ printf(" -c path to reader.conf\n");
+ printf(" -f run in foreground (no daemon), send logs to stderr instead of syslog\n");
+ printf(" -d display debug messages. Output may be:\n");
+ printf(" -h display usage information\n");
+ printf(" -H ask the daemon to rescan the avaiable readers\n");
+ printf(" -v display the program version number\n");
+#endif
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1131 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+//
+// pcscmonitor - use PCSC to monitor smartcard reader/card state for securityd
+//
+// PCSCDMonitor is the "glue" between PCSC and the securityd objects representing
+// smartcard-related things. Its job is to manage the daemon and translate real-world
+// events (such as card and device insertions) into the securityd object web.
+//
+// PCSCDMonitor uses multiple inheritance to the hilt. It is (among others)
+// (*) A notification listener, to listen to pcscd state notifications
+// (*) A MachServer::Timer, to handle timed actions
+// (*) A NotificationPort::Receiver, to get IOKit notifications of device insertions
+//
+
+#include "pcscdmonitor.h"
+#include <security_utilities/logging.h>
+#include <security_utilities/refcount.h>
+#include <IOKit/usb/IOUSBLib.h>
+#include <IOKit/IOMessage.h>
+//#include <Kernel/IOKit/pccard/IOPCCardBridge.h>
+//#include <Kernel/IOKit/pccard/cs.h>
+
+#ifndef _IOKIT_IOPCCARDBRIDGE_H
+// Avoid kernel header include
+#define kIOPCCardVersionOneMatchKey "VersionOneInfo"
+#define kIOPCCardFunctionNameMatchKey "FunctionName"
+#define kIOPCCardFunctionIDMatchKey "FunctionID"
+#define kIOPCCardVendorIDMatchKey "VendorID"
+#define kIOPCCardDeviceIDMatchKey "DeviceID"
+#define kIOPCCardFunctionExtensionMatchKey "FunctionExtension"
+#define kIOPCCardMemoryDeviceNameMatchKey "MemoryDeviceName"
+
+// this should be unique across the entire system
+#define sub_iokit_pccard err_sub(21)
+#define kIOPCCardCSEventMessage iokit_family_msg(sub_iokit_pccard, 1)
+#endif /* _IOKIT_IOPCCARDBRIDGE_H */
+
+// _LINUX_CS_H
+#define CS_EVENT_CARD_INSERTION 0x000004
+#define CS_EVENT_CARD_REMOVAL 0x000008
+#define CS_EVENT_EJECTION_REQUEST 0x010000
+
+// Locally defined string constants for IOKit values
+
+#define kzIOUSBSerialNumberKey "Serial Number"
+#define kzIOUSBVendorNameKey "USB Vendor Name"
+#define kzIOUSBProductNameKey "USB Product Name"
+#define kzIOUSBLocationIDKey "locationID"
+#define kzIOUSBbInterfaceClassKey "bInterfaceClass"
+#define kzIOUSBbDeviceClassKey "bDeviceClass"
+
+#define kzIOPCCardIONameKey "IOName"
+#define kzIOPCCardIODeviceMemoryKey "IODeviceMemory"
+#define kzIOPCCardParentKey "parent"
+#define kzIOPCCardAddressKey "address"
+
+#define kzIOPCCard16DeviceClassName "IOPCCard16Device"
+
+//
+// Fixed configuration parameters
+//
+static const Time::Interval PCSCD_IDLE_SHUTDOWN(120); // kill daemon if no devices present
+
+// Apple built-in iSight Device VendorID/ProductID: 0x05AC/0x8501
+
+static const uint32_t kVendorProductMask = 0x0000FFFF;
+static const uint32_t kVendorIDApple = 0x05AC;
+static const uint16_t kProductIDBuiltInISight = 0x8501;
+
+static void dumpdictentry(const void *key, const void *value, void *context);
+
+#pragma mark -------------------- Class Methods --------------------
+
+//
+// Construct a PCSCDMonitor.
+// We strongly assume there's only one of us around here.
+//
+// Note that this constructor may well run before the server loop has started.
+// Don't call anything here that requires an active server loop (like Server::active()).
+// In fact, you should push all the hard work into a timer, so as not to hold up the
+// general startup process.
+//
+
+PCSCDMonitor::PCSCDMonitor(PCSCD::Server &server, PCSCD::DriverBundles &drivers) :
+ MachPlusPlus::MachServer::Timer(true), // "heavy" timer task
+ server(server),
+ drivers(drivers),
+ mAddDeviceCallback(NULL), mRemoveDeviceCallback(NULL),
+ mWillSleepCallback(NULL), mIsWakingCallback(NULL),
+ mTimerAction(&PCSCDMonitor::initialSetup),
+ mGoingToSleep(false),
+ mTerminationNoticeReceiver(*this),
+ mSleepWakePeriod(false),
+ mWakeConditionVariable(mWakeConditionLock)
+{
+ // do all the smartcard-related work once the event loop has started
+ secdebug("pcsc", "PCSCDMonitor server is %p", &server);
+ server.setTimer(this, Time::now()); // ASAP
+ // timer only used now to call initialSetup
+ mDevices.erase(mDevices.begin(),mDevices.end());
+}
+
+//
+// Power event notifications
+//
+void PCSCDMonitor::systemWillSleep()
+{
+ StLock<Mutex> _(mLock);
+ secdebug("pcsc", "setting sleep marker (%ld readers as of now)", mDevices.size());
+ mGoingToSleep = true;
+ server.clearTimer(this);
+ if (mWillSleepCallback)
+ {
+ uint32_t rx = (*mWillSleepCallback)();
+ secdebug("pcsc", " WillSleepCallback returned %d", rx);
+ }
+ setSystemIsAwakeCondition(false);
+}
+
+void PCSCDMonitor::systemIsWaking()
+{
+ StLock<Mutex> _(mLock);
+ secdebug("pcsc", "------------------ Waking from sleep ... ------------------ ");
+ secdebug("pcsc", "clearing sleep marker (%ld readers as of now)", mDevices.size());
+ mGoingToSleep = false;
+ // rescan here
+ if (mIsWakingCallback)
+ {
+ uint32_t rx = (*mIsWakingCallback)();
+ secdebug("pcsc", " IsWakingCallback returned %d", rx);
+ }
+ setSystemIsAwakeCondition(true);
+}
+
+void PCSCDMonitor::setSystemIsAwakeCondition(bool isAwake)
+{
+ secdebug("pcsc", " setSystemIsAwakeCondition %d", isAwake);
+ if (isAwake)
+ {
+ sleepWakePeriod(false);
+ mWakeConditionVariable.broadcast();
+ }
+ else
+ sleepWakePeriod(true);
+}
+
+bool PCSCDMonitor::isSleepWakePeriod() const
+{
+ StLock<Mutex> _(mSleepWakePeriodLock);
+ return mSleepWakePeriod;
+}
+
+void PCSCDMonitor::sleepWakePeriod(bool isASleepWakePeriod)
+{
+ StLock<Mutex> _(mSleepWakePeriodLock);
+ mSleepWakePeriod = isASleepWakePeriod;
+}
+
+void PCSCDMonitor::systemAwakeAndReadyCheck()
+{
+// const long sleepTimeMSec = 100; // 0.1s
+
+ StLock<Mutex> _(mWakeConditionLock);
+ while (isSleepWakePeriod())
+ {
+ secdebug("pcsc", "...### thread paused before waking ###...");
+ mWakeConditionVariable.wait();
+ secdebug("pcsc", "...### thread resume after waking ###...");
+ }
+}
+
+void PCSCDMonitor::action()
+{
+ // Timer action
+ StLock<Mutex> _(mLock);
+ secdebug("pcsc", "Calling PCSCDMonitor::action()");
+ (this->*mTimerAction)();
+ mTimerAction = &PCSCDMonitor::noDeviceTimeout;
+}
+
+void PCSCDMonitor::scheduleTimer(bool enable)
+{
+ // Update the timeout timer as requested (and indicated by context)
+}
+
+//
+// Perform the initial PCSC subsystem initialization.
+// This runs (shortly) after securityd is fully functional and the
+// server loop has started.
+//
+void PCSCDMonitor::initialSetup()
+{
+ secdebug("pcsc", "Calling PCSCDMonitor::initialSetup()");
+ // receive Mach-based IOKit notifications through mIOKitNotifier
+ server.add(mIOKitNotifier);
+
+ // receive power event notifications (through our IOPowerWatcher personality)
+ server.add(this);
+
+ AddIOKitNotifications();
+
+ PCSCDMonitor::postNotification(SecurityServer::kNotificationPCSCInitialized);
+}
+
+void PCSCDMonitor::AddIOKitNotifications()
+{
+ try
+ {
+ // ask for IOKit notifications for all new USB devices and process present ones
+ IOKit::DeviceMatch usbSelector(kIOUSBInterfaceClassName);
+ IOKit::DeviceMatch pcCardSelector(kzIOPCCard16DeviceClassName);
+ mIOKitNotifier.add(usbSelector, *this, kIOMatchedNotification); // this will scan existing USB devices
+ // mIOKitNotifier.add(usbSelector, mTerminationNoticeReceiver, kIOTerminatedNotification); // ditto for PC Card devices
+ mIOKitNotifier.add(pcCardSelector, *this, kIOMatchedNotification); // ditto for PC Card devices
+ mIOKitNotifier.add(pcCardSelector, mTerminationNoticeReceiver, kIOTerminatedNotification); // ditto for PC Card devices
+
+ // catch custom non-composite USB devices - they don't have IOServices attached
+ IOKit::DeviceMatch customUsbSelector(::IOServiceMatching(kIOUSBDeviceClassName));
+ mIOKitNotifier.add(customUsbSelector, *this, kIOMatchedNotification); // ditto for custom USB devices
+ // mIOKitNotifier.add(customUsbSelector, mTerminationNoticeReceiver, kIOTerminatedNotification);
+ }
+ catch (...)
+ {
+ secdebug("pcscd", "trouble adding IOKit notifications (ignored)");
+ }
+}
+
+void PCSCDMonitor::RemoveIOKitNotifications()
+{
+}
+
+
+void PCSCDMonitor::rescanExistingDevices()
+{
+ kern_return_t kr;
+ mach_port_t masterPort = ((IOKit::NotificationPort)mIOKitNotifier).port();
+// mach_port_t masterPort = port();
+ io_iterator_t iterator;
+
+ // Process existing USB devices
+ IOKit::DeviceMatch usbSelector(kIOUSBInterfaceClassName);
+ kr = IOServiceGetMatchingServices(masterPort, usbSelector, &iterator);
+ IOKit::DeviceIterator usbdev(iterator);
+ ioChange(usbdev);
+
+ // Process existing PC Card devices
+ IOKit::DeviceMatch pcCardSelector(kzIOPCCard16DeviceClassName);
+ kr = IOServiceGetMatchingServices(masterPort, pcCardSelector, &iterator);
+ IOKit::DeviceIterator pcdev(iterator);
+ ioChange(pcdev);
+
+ // catch custom non-composite USB devices - they don't have IOServices attached
+ IOKit::DeviceMatch customUsbSelector(::IOServiceMatching(kIOUSBDeviceClassName));
+ kr = IOServiceGetMatchingServices(masterPort, customUsbSelector, &iterator);
+ IOKit::DeviceIterator customusbdev(iterator);
+ ioChange(customusbdev);
+}
+
+void PCSCDMonitor::postNotification(const SecurityServer::NotificationEvent event)
+{
+ // send a change notification to securityd
+ // Either kNotificationPCSCStateChange or kNotificationPCSCInitialized
+ using namespace SecurityServer;
+ ClientSession session(Allocator::standard(), Allocator::standard());
+ try {
+ session.postNotification(kNotificationDomainPCSC, event, CssmData());
+ secdebug("pcscd", "notification sent");
+ } catch (const MachPlusPlus::Error &err) {
+ switch (err.error) {
+ case BOOTSTRAP_UNKNOWN_SERVICE: // securityd not yet available; this is not an error
+ secdebug("pcscd", "securityd not up; no notification sent");
+ break;
+#if !defined(NDEBUG)
+ // for debugging only, support a securityd restart. This is NOT thread-safe
+ case MACH_SEND_INVALID_DEST:
+ secdebug("pcscd", "resetting securityd connection for debugging");
+ session.reset();
+ try {
+ session.postNotification(kNotificationDomainPCSC,
+ kNotificationPCSCStateChange, CssmData());
+ } catch (...) {
+ secdebug("pcscd", "re-send attempt failed, punting");
+ }
+ break;
+#endif //NDEBUG
+ default:
+ secdebug("pcscd", "exception trying to send notification (ignored)");
+ }
+ } catch (...) {
+ secdebug("pcscd", "trouble sending security notification (ignored)");
+ }
+}
+
+//
+// This function is called (as a timer function) when there haven't been any (recognized)
+// smartcard devicees in the system for a while.
+//
+void PCSCDMonitor::noDeviceTimeout()
+{
+ secdebug("pcsc", "killing pcscd (no smartcard devices present for %g seconds)",
+ PCSCD_IDLE_SHUTDOWN.seconds());
+}
+
+void PCSCDMonitor::addInterestNotification()
+{
+ secdebug("pcsc", "Adding interest notification for service 0x%04X (this=%p)", mServiceOfInterest,this);
+ mIOKitNotifier.addInterestNotification(*this, mServiceOfInterest);
+}
+
+void PCSCDMonitor::scheduleAddInterestNotification(io_service_t serviceOfInterest)
+{
+ StLock<Mutex> _(mLock);
+ secdebug("pcsc", "Scheduling interest notification for service 0x%04X (this=%p)", serviceOfInterest, this);
+ mServiceOfInterest = serviceOfInterest;
+ mTimerAction = &PCSCDMonitor::addInterestNotification;
+ server.setTimer(this, Time::now()); // ASAP
+}
+
+//
+// IOKit device event notification.
+// Here we listen for newly inserted devices
+//
+void PCSCDMonitor::ioChange(IOKit::DeviceIterator &iterator)
+{
+ secdebug("pcsc", "Processing device event notification");
+ int def=0, pos=0, total=0;
+ // Always drain this iterator
+ while (IOKit::Device dev = iterator())
+ {
+ ++total;
+ displayPropertiesOfDevice(dev);
+ switch (deviceSupport(dev))
+ {
+ case definite:
+ ++def;
+ addDevice(dev);
+ break;
+ case possible:
+ ++pos;
+ addDevice(dev);
+ break;
+ case impossible:
+ break;
+ }
+ }
+
+ dumpDevices();
+ secdebug("pcsc", "Relevant devices: %d definite, %d possible, %d total", def, pos, total);
+}
+
+// IOKit device event notification.
+// Here we listen for newly removed devices
+//
+void PCSCDMonitor::ioServiceChange(void *refCon, io_service_t service,
+ natural_t messageType, void *messageArgument)
+{
+ secdebug("pcsc", "Processing ioServiceChange notice: 0x%08X [refCon=0x%08X, service=0x%08X, arg=0x%08X]",
+ messageType, (uint32_t)refCon, service, (uint32_t)messageArgument);
+
+ if (mGoingToSleep && isSleepWakePeriod()) // waking up but still drowsy
+ {
+ secdebug("pcsc", " ignoring ioServiceChange notice during wake up phase");
+ return;
+ }
+
+ PCSCDMonitor::displayPropertiesOfDevice(service);
+ // This is called since we asked for kIOGeneralInterest notices
+ // Usually it is the "device removed" notification
+ switch (messageType)
+ {
+ case kIOMessageServiceIsTerminated: // We get these when device is removed
+ {
+ uint32_t address;
+ if (deviceAddress(service, address))
+ {
+ secdebug("pcsc", " device removed notice: 0x%04X address: 0x%08X", service, address);
+ this->removeDevice(service, address);
+ }
+ else
+ secdebug("pcsc", " device removed notice, but failed to find address for service: 0x%04X", service);
+ }
+ break;
+ case kIOMessageServiceWasClosed: // We get these when the system sleeps
+ {
+#ifndef NDEBUG
+ uint32_t address;
+ deviceAddress(service, address);
+ secdebug("pcsc", " service was closed notice: 0x%04X address: 0x%08X", service, address);
+#endif
+ }
+ break;
+ case kIOPCCardCSEventMessage: // 0xE0054001 - not handled by mach_error_string
+ secdebug("pcsc", " pccard event message: service: 0x%04X, type: 0x%08X",
+ service, (unsigned int)messageArgument);
+ // Card Services Events are defined in IOKit/pccard/cs.h
+ switch ((unsigned int)messageArgument)
+ {
+ case CS_EVENT_EJECTION_REQUEST:
+ secdebug("pcsc", " pccard event message: ejection request");
+ break;
+
+ case CS_EVENT_CARD_REMOVAL:
+ {
+ uint32_t address;
+ if (deviceMemoryAddress(service, address))
+ {
+ secdebug("pcsc", " device removed notice: 0x%04X address: 0x%08X", service, address);
+ this->removeDevice(service, address);
+ }
+ else
+ secdebug("pcsc", " device removed notice, but failed to find address for service: 0x%04X", service);
+ break;
+ }
+ }
+ break;
+ default:
+ secdebug("pcsc", " processing device general notice: 0x%08X", messageType);
+ break;
+ }
+}
+
+void PCSCDMonitor::addDevice(const IOKit::Device &dev)
+{
+ DeviceMap::iterator it;
+ if (!findDevice(dev,it)) // new device
+ {
+ io_service_t service = dev.ioObject();
+
+ RefPointer<PCSCD::Device> newDevice = new PCSCD::Device(service);
+ uint32_t address = 0;
+
+ if (deviceAddress(dev, address))
+ {
+ newDevice->setAddress(address);
+ secdebug("scsel", " Device address: 0x%08X [service: 0x%04X]", address, service);
+ setDeviceProperties(dev, *newDevice);
+ if (drivers.find(*newDevice))
+ {
+ secdebug("driver", " found matching driver for %s: %s", newDevice->name().c_str(), newDevice->path().c_str());
+ setDebugPropertiesForDevice(dev, newDevice);
+ insert(make_pair(address, newDevice));
+ if (mAddDeviceCallback)
+ {
+ // kPCSCLITE_HP_BASE_PORT
+ uint32_t rx = (*mAddDeviceCallback)(newDevice->name().c_str(), address, newDevice->path().c_str(), newDevice->name().c_str());
+ secdebug("pcsc", " AddDeviceCallback returned %d", rx);
+ if (rx != SCARD_S_SUCCESS && rx != SCARD_E_DUPLICATE_READER)
+ {
+ DeviceMap::iterator it = mDevices.find(address);
+ if (it != mDevices.end()) // found it
+ remove(it); // remove from reader map
+ return;
+ }
+ }
+ PCSCDMonitor::postNotification(SecurityServer::kNotificationPCSCStateChange);
+ secdebug("pcsc", " added to device map, address: 0x%08X, service: 0x%04X, [class @:%p]", address, service, newDevice.get());
+ }
+ else
+ secdebug("driver", " no matching driver found for %s: %s", newDevice->name().c_str(), newDevice->path().c_str());
+ }
+ else
+ secdebug("pcsc", " device added notice, but failed to find address for service: 0x%04X", service);
+ }
+ else
+ {
+ PCSCD::Device *theDevice = static_cast<PCSCD::Device *>(it->second);
+ secdebug("scsel", " Already in map: Device address: 0x%08X [service: 0x%04X]",
+ theDevice->address(), dev.ioObject());
+ setDeviceProperties(dev, *theDevice);
+ setDebugPropertiesForDevice(dev, theDevice);
+ }
+
+ // We always try to add the interest notification. It may be that
+ // we added the device during a callback for a particular plane,
+ // but we didn't have the right information then to add the notification
+ io_service_t servicex = dev.ioObject();
+ mIOKitNotifier.addInterestNotification(*this, servicex);
+ dumpDevices();
+}
+
+bool PCSCDMonitor::findDevice(const IOKit::Device &dev, DeviceMap::iterator &it)
+{
+ uint32_t address = 0;
+ deviceAddress(dev, address);
+ it = mDevices.find(address);
+ return (it != mDevices.end());
+}
+
+bool PCSCDMonitor::findDeviceByName(const IOKit::Device &dev, DeviceMap::iterator &outit)
+{
+ CFRef<CFStringRef> ioName = dev.property<CFStringRef>(kzIOPCCardIONameKey);
+ if (!ioName)
+ return false;
+
+ std::string devname = cfString(ioName);
+ for (DeviceMap::iterator it = mDevices.begin(); it != mDevices.end(); ++it)
+ {
+ PCSCD::Device *theDevice = static_cast<PCSCD::Device *>(it->second);
+ if (theDevice->name() == devname)
+ {
+ outit = it;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void PCSCDMonitor::updateDevice(const IOKit::Device &dev)
+{
+ DeviceMap::iterator it;
+ if (findDevice(dev,it))
+ {
+ PCSCD::Device *theDevice = static_cast<PCSCD::Device *>(it->second);
+ setDeviceProperties(dev, *theDevice);
+ if (drivers.find(*theDevice))
+ secdebug("driver", " found matching driver for %s: %s", theDevice->name().c_str(), theDevice->path().c_str());
+ setDebugPropertiesForDevice(dev, theDevice);
+ }
+}
+
+bool PCSCDMonitor::hasLegacyDriver(const IOKit::Device &dev)
+{
+ PCSCD::Device tmpDevice(0); //dev.ioObject() - fake it
+ uint32_t address = 0;
+ if (deviceAddress(dev, address))
+ tmpDevice.setAddress(address);
+ setDeviceProperties(dev, tmpDevice);
+ if (drivers.find(tmpDevice))
+ {
+ secdebug("driver", " found matching driver for legacy device: %s", tmpDevice.path().c_str());
+ return true;
+ }
+
+ return false;
+}
+
+bool PCSCDMonitor::deviceIsPCCard(const IOKit::Device &dev)
+{
+ if (CFRef<CFStringRef> ioName = dev.property<CFStringRef>(kzIOPCCardIONameKey))
+ if (cfString(ioName).find("pccard", 0, 1) == 0)
+ return true;
+
+ return false;
+}
+
+bool PCSCDMonitor::deviceIsPCCard(io_service_t service)
+{
+ if (CFRef<CFStringRef> ioName = static_cast<CFStringRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOPCCardIONameKey), kCFAllocatorDefault, 0)))
+ if (cfString(ioName).find("pccard", 0, 1) == 0)
+ return true;
+
+ return false;
+}
+
+void PCSCDMonitor::getVendorAndProductID(const IOKit::Device &dev, uint32_t &vendorID, uint32_t &productID, bool &isPCCard)
+{
+ vendorID = productID = 0;
+ isPCCard = deviceIsPCCard(dev);
+
+ if (!isPCCard)
+ {
+ if (CFRef<CFNumberRef> cfVendorID = dev.property<CFNumberRef>(kUSBVendorID))
+ vendorID = cfNumber(cfVendorID);
+
+ if (CFRef<CFNumberRef> cfProductID = dev.property<CFNumberRef>(kUSBProductID))
+ productID = cfNumber(cfProductID);
+ }
+ else
+ {
+ if (CFRef<CFNumberRef> cfVendorID = dev.property<CFNumberRef>(kIOPCCardVendorIDMatchKey))
+ vendorID = cfNumber(cfVendorID);
+
+ if (CFRef<CFNumberRef> cfProductID = dev.property<CFNumberRef>(kIOPCCardDeviceIDMatchKey))
+ productID = cfNumber(cfProductID);
+
+ // One special case for legacy OmniKey CardMan 4040 support
+ CFRef<CFStringRef> ioName = dev.property<CFStringRef>(kzIOPCCardIONameKey);
+ if (ioName && CFEqual(ioName, CFSTR("pccard-no-cis")))
+ {
+ vendorID = 0x0223;
+ productID = 0x0200;
+ }
+ }
+}
+
+void PCSCDMonitor::setDeviceProperties(const IOKit::Device &dev, PCSCD::Device &device)
+{
+ uint32_t vendorID, productID;
+ bool isPCCard;
+
+ getVendorAndProductID(dev, vendorID, productID, isPCCard);
+
+ device.setIsPCCard(isPCCard);
+
+ if (CFRef<CFNumberRef> cfInterface = dev.property<CFNumberRef>(kzIOUSBbInterfaceClassKey))
+ device.setInterfaceClass(cfNumber(cfInterface));
+
+ if (CFRef<CFNumberRef> cfDevice = dev.property<CFNumberRef>(kzIOUSBbDeviceClassKey))
+ device.setDeviceClass(cfNumber(cfDevice));
+
+ device.setVendorid(vendorID);
+ device.setProductid(productID);
+
+ if (CFRef<CFStringRef> ioName = dev.property<CFStringRef>(kzIOPCCardIONameKey))
+ device.setName(cfString(ioName));
+}
+
+bool PCSCDMonitor::isExcludedDevice(const IOKit::Device &dev)
+{
+ uint32_t vendorID, productID;
+ bool isPCCard;
+
+ getVendorAndProductID(dev, vendorID, productID, isPCCard);
+
+ return ((vendorID & kVendorProductMask) == kVendorIDApple && (productID & kVendorProductMask) == kProductIDBuiltInISight);
+}
+
+void PCSCDMonitor::setDebugPropertiesForDevice(const IOKit::Device &dev, PCSCD::Device * newDevice)
+{
+ /*
+ Many of these properties are only defined on the "IOUSBDevice" plane, so
+ will be non-empty on the third iteration.
+ */
+ std::string vendorName, productName, serialNumber;
+
+ if (CFRef<CFStringRef> cfVendorString = dev.property<CFStringRef>(kzIOUSBVendorNameKey))
+ vendorName = cfString(cfVendorString);
+
+ if (CFRef<CFStringRef> cfProductString = dev.property<CFStringRef>(kzIOUSBProductNameKey))
+ productName = cfString(cfProductString);
+
+ if (CFRef<CFStringRef> cfSerialString = dev.property<CFStringRef>(kzIOUSBSerialNumberKey))
+ serialNumber = cfString(cfSerialString);
+
+ if (deviceIsPCCard(dev))
+ {
+ if (CFRef<CFArrayRef> cfVersionOne = dev.property<CFArrayRef>(kIOPCCardVersionOneMatchKey))
+ if (CFArrayGetCount(cfVersionOne) > 1)
+ {
+ CFStringRef cfVendorString = (CFStringRef)CFArrayGetValueAtIndex(cfVersionOne, 0);
+ if (cfVendorString)
+ vendorName = cfString(cfVendorString);
+
+ CFStringRef cfProductString = (CFStringRef)CFArrayGetValueAtIndex(cfVersionOne, 1);
+ if (cfProductString)
+ productName = cfString(cfProductString);
+ }
+ }
+
+ newDevice->setDebugParams(vendorName, productName, serialNumber);
+
+// secdebug("scsel", " deviceSupport: vendor/product: 0x%04X/0x%04X, vendor: %s, product: %s, serial: %s", vendorid, productid,
+// vendorName.c_str(), productName.c_str(), serialNumber.c_str());
+}
+
+void PCSCDMonitor::removeDevice(io_service_t service, uint32_t address)
+{
+ secdebug("pcsc", " Size of mDevices: %ld, service: 0x%04X", mDevices.size(), service);
+ if (!mDevices.empty())
+ {
+ secdebug("pcsc", " device removed notice: 0x%04X address: 0x%08X", service, address);
+ DeviceMap::iterator it = mDevices.find(address);
+ if (it != mDevices.end()) // found it
+ {
+ if (mRemoveDeviceCallback)
+ {
+ uint32_t rx = (*mRemoveDeviceCallback)((it->second)->name().c_str(), address);
+ secdebug("pcsc", " RemoveDeviceCallback returned %d", rx);
+ }
+ remove(it); // remove from reader map
+ }
+ else
+ secdebug("pcsc", " service: 0x%04X at address 0x%04X not found ??", service, address);
+ }
+ dumpDevices();
+ ::IOObjectRelease(service); // we don't want notifications here until re-added
+}
+
+void PCSCDMonitor::removeDeviceByName(const IOKit::Device &dev)
+{
+ io_service_t service = dev.ioObject();
+ secdebug("pcsc", " Size of mDevices: %ld, service: 0x%04X", mDevices.size(), service);
+ if (!mDevices.empty())
+ {
+ uint32_t address = 0;
+ deviceAddress(dev, address);
+ DeviceMap::iterator it;
+ if (findDeviceByName(dev, it)) // found it
+ {
+ if (mRemoveDeviceCallback)
+ {
+ uint32_t rx = (*mRemoveDeviceCallback)((it->second)->name().c_str(), address);
+ secdebug("pcsc", " RemoveDeviceCallback returned %d", rx);
+ }
+ remove(it); // remove from reader map
+ }
+ else
+ secdebug("pcsc", " service: 0x%04X at address 0x%04X not found ??", service, address);
+ }
+ dumpDevices();
+ ::IOObjectRelease(service); // we don't want notifications here until re-added
+}
+
+void PCSCDMonitor::removeAllDevices()
+{
+ secdebug("pcsc", ">>>>>> removeAllDevices: Size of mDevices: %ld", mDevices.size());
+ for (DeviceMap::iterator it = mDevices.begin(); it != mDevices.end(); ++it)
+ {
+ PCSCD::Device *dev = static_cast<PCSCD::Device *>(it->second);
+ uint32_t address = 0;
+ // PCSCDMonitor::deviceAddress(*dev, &address);
+ address = dev->address();
+ io_service_t service = dev->ioObject();
+ if (mRemoveDeviceCallback)
+ {
+ uint32_t rx = (*mRemoveDeviceCallback)(dev->name().c_str(), address);
+ secdebug("pcsc", " RemoveDeviceCallback returned %d", rx);
+ }
+ ::IOObjectRelease(service); // we don't want notifications here until re-added
+ remove(it); // remove from reader map
+ }
+ secdebug("pcsc", ">>>>>> removeAllDevices [end]: Size of mDevices: %ld", mDevices.size());
+}
+
+
+//
+// Check an IOKit device that's just come online to see if it's
+// a smartcard device of some sort.
+//
+PCSCDMonitor::DeviceSupport PCSCDMonitor::deviceSupport(const IOKit::Device &dev)
+{
+#ifndef NDEBUG
+ try
+ {
+ secdebug("scsel", "path: %s", dev.path().c_str()); // this can fail sometimes
+ }
+ catch (...)
+ {
+ secdebug("scsel", " exception while displaying device path - ignoring error");
+ }
+#endif
+
+ try
+ {
+ // composite USB device with interface class
+ if (CFRef<CFNumberRef> cfInterface = dev.property<CFNumberRef>(kzIOUSBbInterfaceClassKey))
+ switch (uint32_t clas = cfNumber(cfInterface))
+ {
+ case kUSBChipSmartCardInterfaceClass: // CCID smartcard reader - go
+ secdebug("scsel", " CCID smartcard reader recognized");
+ return definite;
+ case kUSBVendorSpecificInterfaceClass:
+ if (isExcludedDevice(dev))
+ {
+ secdebug("scsel", " interface class %d is not a smartcard device (excluded)", clas);
+ return impossible;
+ }
+ secdebug("scsel", " Vendor-specific interface - possible match");
+ return possible;
+ default:
+ if ((clas == 0) && hasLegacyDriver(dev))
+ {
+ secdebug("scsel", " Vendor-specific legacy driver - possible match");
+ return possible;
+ }
+ secdebug("scsel", " interface class %d is not a smartcard device", clas);
+ return impossible;
+ }
+
+ // noncomposite USB device
+ if (CFRef<CFNumberRef> cfDevice = dev.property<CFNumberRef>(kzIOUSBbDeviceClassKey))
+ if (cfNumber(cfDevice) == kUSBVendorSpecificClass)
+ {
+ if (isExcludedDevice(dev))
+ {
+ secdebug("scsel", " device class %d is not a smartcard device (excluded)", cfNumber(cfDevice));
+ return impossible;
+ }
+ secdebug("scsel", " Vendor-specific device - possible match");
+ return possible;
+ }
+
+ // PCCard (aka PCMCIA aka ...) interface (don't know how to recognize a reader here)
+ if (deviceIsPCCard(dev))
+ {
+ secdebug("scsel", " PCCard - possible match");
+ return possible;
+ }
+
+ return impossible;
+ }
+ catch (...)
+ {
+ secdebug("scsel", " exception while examining device - ignoring it");
+ return impossible;
+ }
+}
+
+#pragma mark -------------------- Static Methods --------------------
+
+bool PCSCDMonitor::deviceAddress(io_service_t service, uint32_t &address)
+{
+ if (CFRef<CFNumberRef> cfLocationID = static_cast<CFNumberRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOUSBLocationIDKey), kCFAllocatorDefault, 0)))
+ {
+ address = cfNumber(cfLocationID);
+ return true;
+ }
+
+ // don't bother to test if it is a pc card, just try looking
+ return deviceMemoryAddress(service, address);
+}
+
+bool PCSCDMonitor::deviceAddress(const IOKit::Device &dev, uint32_t &address)
+{
+ if (CFRef<CFNumberRef> cfLocationID = dev.property<CFNumberRef>(kzIOUSBLocationIDKey))
+ {
+ address = cfNumber(cfLocationID);
+ return true;
+ }
+
+ // don't bother to test if it is a pc card, just try looking
+ return deviceMemoryAddress(dev, address);
+}
+
+bool PCSCDMonitor::deviceMemoryAddress(const IOKit::Device &dev, uint32_t &address)
+{
+// CFRef<CFStringRef> ioName = dev.property<CFStringRef>(kzIOPCCardIONameKey);
+ CFRef<CFArrayRef> cfDeviceMemory = dev.property<CFArrayRef>(kzIOPCCardIODeviceMemoryKey);
+ return deviceMemoryAddressCore(cfDeviceMemory, dev.path(), address);
+}
+
+bool PCSCDMonitor::deviceMemoryAddress(io_service_t service, uint32_t &address)
+{
+// CFRef<CFStringRef> ioName = static_cast<CFStringRef>(::IORegistryEntryCreateCFProperty(
+// service, CFSTR(kzIOPCCardIONameKey), kCFAllocatorDefault, 0));
+ CFRef<CFArrayRef> cfDeviceMemory = static_cast<CFArrayRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOPCCardIODeviceMemoryKey), kCFAllocatorDefault, 0));
+ return deviceMemoryAddressCore(cfDeviceMemory, "", address);
+}
+
+bool PCSCDMonitor::deviceMemoryAddressCore(CFArrayRef cfDeviceMemory, std::string path, uint32_t &address)
+{
+ address = 0;
+ try
+ {
+ if (cfDeviceMemory)
+ {
+ if (CFRef<CFDictionaryRef> cfTempMem = (CFDictionaryRef)CFRetain(CFArrayGetValueAtIndex(cfDeviceMemory, 0)))
+ {
+ // CFDictionaryApplyFunction(cfTempMem, dumpdictentry, NULL);
+ if (CFRef<CFArrayRef> cfParent = (CFArrayRef)CFRetain(CFDictionaryGetValue(cfTempMem, CFSTR(kzIOPCCardParentKey))))
+ if (CFRef<CFDictionaryRef> cfTempMem2 = (CFDictionaryRef)CFRetain(CFArrayGetValueAtIndex(cfParent, 0)))
+ if (CFRef<CFNumberRef> cfAddress = (CFNumberRef)CFRetain(CFDictionaryGetValue((CFDictionaryRef)cfTempMem2, CFSTR(kzIOPCCardAddressKey))))
+ {
+ address = cfNumber(cfAddress);
+ secdebug("scsel", " address from device memory address property: 0x%08X", address);
+ return true;
+ }
+ }
+ }
+ else
+ if (!path.empty())
+ {
+ // std::string name = cfString(ioName);
+ // address = CFHash (ioName);
+ // address = 0xF2000000;
+ addressFromPath(path, address);
+ secdebug("scsel", " extracted address: 0x%08X for device [%s]", address, path.c_str());
+ return true;
+ }
+ }
+ catch (...)
+ {
+ secdebug("scsel", " exception while examining deviceMemoryAddress property");
+ }
+ return false;
+}
+
+bool PCSCDMonitor::addressFromPath(std::string path, uint32_t &address)
+{
+ /*
+ Try to extract the address from the path if the other keys are not present.
+ An example path is:
+
+ IOService:/MacRISC2PE/pci at f2000000/AppleMacRiscPCI/cardbus at 13/IOPCCardBridge/pccard2bd,1003 at 0,0
+
+ where e.g. the address is f2000000, the vendor is 0x2bd, and the product id is 0x1003
+ */
+ address = 0;
+ #define HEX_TO_INT(x) ((x) >= '0' &&(x) <= '9' ? (x) - '0' : (x) - ('a' - 10))
+
+ try
+ {
+ secdebug("scsel", "path: %s", path.c_str()); // this can fail sometimes
+
+ std::string lhs("/pci@");
+ std::string rhs("/");
+
+ std::string::size_type start = path.find(lhs)+lhs.length();
+ std::string::size_type end = path.find(rhs, start);
+
+ std::string addressString(path, start, end-start);
+
+ // now addressString should contain something like f2000000
+ uint32_t tmp = 0;
+ const char *px = addressString.c_str();
+ size_t len = strlen(px);
+ for (unsigned int ix=0;ix<len;ix++,px++)
+ {
+ tmp<<=4;
+ tmp += HEX_TO_INT(*px);
+ }
+
+ address = tmp;
+
+ secdebug("scsel", " address 0x%08X extracted from path", address);
+ }
+ catch (...)
+ {
+ secdebug("scsel", " exception while displaying device path - ignoring error");
+ return false;
+ }
+
+ return true;
+}
+
+#pragma mark -------------------- Termination Notice Receiver --------------------
+
+TerminationNoticeReceiver::~TerminationNoticeReceiver()
+{
+}
+
+void TerminationNoticeReceiver::ioChange(IOKit::DeviceIterator &iterator)
+{
+ secdebug("pcsc", "[TerminationNoticeReceiver] Processing ioChange notification");
+ // Always drain this iterator
+ while (IOKit::Device dev = iterator())
+ {
+ PCSCDMonitor::displayPropertiesOfDevice(dev);
+ parent().removeDeviceByName(dev);
+ }
+}
+
+void TerminationNoticeReceiver::ioServiceChange(void *refCon, io_service_t service,
+ natural_t messageType, void *messageArgument)
+{
+ secdebug("pcsc", " [TerminationNoticeReceiver] processing ioServiceChange notice: 0x%08X [refCon=0x%08X, service=0x%08X, arg=0x%08X]",
+ messageType, (uint32_t)refCon, service, (uint32_t)messageArgument);
+ parent().ioServiceChange(refCon, service, messageType, messageArgument);
+}
+
+#pragma mark -------------------- Debug Routines --------------------
+
+void PCSCDMonitor::displayPropertiesOfDevice(const IOKit::Device &dev)
+{
+ /*
+ Many of these properties are only defined on the "IOUSBDevice" plane, so
+ will be non-empty on the third iteration.
+ */
+ try
+ {
+ std::string vendorName, productName, serialNumber, name;
+
+ uint32_t vendorID, productID;
+ bool isPCCard;
+
+ CFRef<CFStringRef> ioName = dev.property<CFStringRef>(kzIOPCCardIONameKey);
+ if (ioName)
+ name = cfString(ioName);
+
+ getVendorAndProductID(dev, vendorID, productID, isPCCard);
+
+ if (CFRef<CFStringRef> cfSerialString = dev.property<CFStringRef>(kzIOUSBSerialNumberKey))
+ serialNumber = cfString(cfSerialString);
+
+ if (isPCCard)
+ {
+ if (CFRef<CFArrayRef> cfVersionOne = dev.property<CFArrayRef>(kIOPCCardVersionOneMatchKey))
+ if (CFArrayGetCount(cfVersionOne) > 1)
+ {
+ CFStringRef cfVendorString = (CFStringRef)CFArrayGetValueAtIndex(cfVersionOne, 0);
+ if (cfVendorString)
+ vendorName = cfString(cfVendorString);
+
+ CFStringRef cfProductString = (CFStringRef)CFArrayGetValueAtIndex(cfVersionOne, 1);
+ if (cfProductString)
+ productName = cfString(cfProductString);
+ }
+
+ uint32_t address;
+ deviceMemoryAddress(dev, address);
+ }
+ else
+ {
+ if (CFRef<CFStringRef> cfVendorString = dev.property<CFStringRef>(kzIOUSBVendorNameKey))
+ vendorName = cfString(cfVendorString);
+
+ if (CFRef<CFStringRef> cfProductString = dev.property<CFStringRef>(kzIOUSBProductNameKey))
+ productName = cfString(cfProductString);
+ }
+
+ secdebug("scsel", "--- properties: service: 0x%04X, name: %s, vendor/product: 0x%04X/0x%04X, vendor: %s, product: %s, serial: %s",
+ dev.ioObject(), name.c_str(), vendorID, productID,
+ vendorName.c_str(), productName.c_str(), serialNumber.c_str());
+ }
+ catch (...)
+ {
+ secdebug("scsel", " exception in displayPropertiesOfDevice - ignoring error");
+ }
+}
+
+void PCSCDMonitor::displayPropertiesOfDevice(io_service_t service)
+{
+ kern_return_t kr;
+ CFMutableDictionaryRef properties = NULL;
+
+ // get a copy of the in kernel registry object
+ kr = IORegistryEntryCreateCFProperties(service, &properties, kCFAllocatorDefault, 0);
+ if (kr != KERN_SUCCESS)
+ {
+ printf("IORegistryEntryCreateCFProperties failed with %x\n", kr);
+ }
+ else
+ if (properties)
+ {
+// CFShow(properties);
+ CFRelease(properties);
+ }
+
+ try
+ {
+ std::string vendorName, productName, serialNumber, name;
+
+ uint32_t vendorID, productID;
+ bool isPCCard;
+
+ CFRef<CFStringRef> ioName = static_cast<CFStringRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOPCCardIONameKey), kCFAllocatorDefault, 0));
+ if (ioName)
+ name = cfString(ioName);
+
+// getVendorAndProductID(dev, vendorID, productID, isPCCard);
+
+ CFRef<CFStringRef> cfSerialString = static_cast<CFStringRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOUSBSerialNumberKey), kCFAllocatorDefault, 0));
+ if (cfSerialString)
+ serialNumber = cfString(cfSerialString);
+
+ if (isPCCard)
+ {
+ CFRef<CFArrayRef> cfVersionOne = static_cast<CFArrayRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kIOPCCardVersionOneMatchKey), kCFAllocatorDefault, 0));
+ if (cfVersionOne && (CFArrayGetCount(cfVersionOne) > 1))
+ {
+ CFStringRef cfVendorString = (CFStringRef)CFArrayGetValueAtIndex(cfVersionOne, 0);
+ if (cfVendorString)
+ vendorName = cfString(cfVendorString);
+
+ CFStringRef cfProductString = (CFStringRef)CFArrayGetValueAtIndex(cfVersionOne, 1);
+ if (cfProductString)
+ productName = cfString(cfProductString);
+ }
+
+ uint32_t address;
+ deviceMemoryAddress(service, address);
+ }
+ else
+ {
+ CFRef<CFStringRef> cfVendorString = static_cast<CFStringRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOUSBVendorNameKey), kCFAllocatorDefault, 0));
+ if (cfVendorString)
+ vendorName = cfString(cfVendorString);
+
+ CFRef<CFStringRef> cfProductString = static_cast<CFStringRef>(::IORegistryEntryCreateCFProperty(
+ service, CFSTR(kzIOUSBProductNameKey), kCFAllocatorDefault, 0));
+ if (cfProductString)
+ productName = cfString(cfProductString);
+ }
+
+ secdebug("scsel", "--- properties: service: 0x%04X, name: %s, vendor/product: 0x%04X/0x%04X, vendor: %s, product: %s, serial: %s",
+ service, name.c_str(), vendorID, productID,
+ vendorName.c_str(), productName.c_str(), serialNumber.c_str());
+ }
+ catch (...)
+ {
+ secdebug("scsel", " exception in displayPropertiesOfDevice - ignoring error");
+ }
+}
+
+void PCSCDMonitor::dumpDevices()
+{
+ secdebug("pcsc", "------------------ Device Map ------------------");
+ for (DeviceMap::iterator it = mDevices.begin();it!=mDevices.end();++it)
+ {
+ PCSCD::Device *dev = static_cast<PCSCD::Device *>(it->second);
+ dev->dump();
+ }
+ secdebug("pcsc", "------------------------------------------------");
+}
+
+static void dumpdictentry(const void *key, const void *value, void *context)
+{
+ secdebug("dumpd", " dictionary key: %s, val: %p, CFGetTypeID: %d", cfString((CFStringRef)key).c_str(), value, (int)CFGetTypeID(value));
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdmonitor.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+//
+// pcscmonitor - use PCSC to monitor smartcard reader/card state for securityd
+//
+#ifndef _H_PCSCDMONITOR
+#define _H_PCSCDMONITOR
+
+#include <security_utilities/powerwatch.h>
+#include <security_utilities/pcsc++.h>
+#include <security_utilities/refcount.h>
+#include <security_utilities/iodevices.h>
+#include <security_utilities/threading.h>
+#include <securityd_client/ssclient.h>
+
+#include "pcscdserver.h"
+#include "PCSCDevice.h"
+#include "PCSCDriverBundles.h"
+
+typedef int32_t (*addDeviceCallback)(const char *name, uint32_t address, const char *pathLibrary, const char *pathDevice);
+typedef int32_t (*removeDeviceCallback)(const char *name, uint32_t address);
+typedef int32_t (*willSleepCallback)();
+typedef int32_t (*isWakingCallback)();
+
+#if defined(__cplusplus)
+
+class PCSCDMonitor;
+
+class TerminationNoticeReceiver : public IOKit::NotificationPort::Receiver
+{
+public:
+ TerminationNoticeReceiver(PCSCDMonitor &parent) : mParent(parent) {}
+ virtual ~TerminationNoticeReceiver();
+
+ virtual void ioChange(IOKit::DeviceIterator &iterator);
+ virtual void ioServiceChange(void *refCon, io_service_t service, //IOServiceInterestCallback
+ natural_t messageType, void *messageArgument);
+
+ virtual PCSCDMonitor &parent() { return mParent; }
+
+private:
+ PCSCDMonitor &mParent;
+};
+
+//
+// A PCSCMonitor uses PCSC to monitor the state of smartcard readers and
+// tokens (cards) in the system, and dispatches messages and events to the
+// various related players in securityd. There should be at most one of these
+// objects active within securityd.
+//
+class PCSCDMonitor :
+ private MachPlusPlus::MachServer::Timer,
+ private IOKit::NotificationPort::Receiver,
+ private MachPlusPlus::PowerWatcher
+{
+public:
+
+ friend class TerminationNoticeReceiver;
+
+ PCSCDMonitor(PCSCD::Server &server, PCSCD::DriverBundles &drivers);
+ void setCallbacks(addDeviceCallback theAddDeviceCallback, removeDeviceCallback theRemoveDeviceCallback,
+ willSleepCallback theWillSleepCallback, isWakingCallback theIsWakingCallback)
+ { mAddDeviceCallback = theAddDeviceCallback; mRemoveDeviceCallback = theRemoveDeviceCallback;
+ mWillSleepCallback = theWillSleepCallback; mIsWakingCallback = theIsWakingCallback; }
+
+ static void postNotification(const SecurityServer::NotificationEvent event);
+
+ void systemAwakeAndReadyCheck();
+
+protected:
+
+ PCSCD::Server &server;
+ PCSCD::DriverBundles &drivers;
+ addDeviceCallback mAddDeviceCallback;
+ removeDeviceCallback mRemoveDeviceCallback;
+ willSleepCallback mWillSleepCallback;
+ isWakingCallback mIsWakingCallback;
+
+protected:
+ // MachServer::Timer
+ void action();
+
+ // NotificationPort::Receiver
+ void ioChange(IOKit::DeviceIterator &iterator);
+ void ioServiceChange(void *refCon, io_service_t service, natural_t messageType, void *messageArgument);
+
+ // PowerWatcher
+ void systemWillSleep();
+ void systemIsWaking();
+
+protected:
+ void scheduleTimer(bool enable);
+ void initialSetup();
+ void noDeviceTimeout();
+
+ enum DeviceSupport
+ {
+ impossible, // certain this is not a smartcard
+ definite, // definitely a smartcard device
+ possible // perhaps... we're not sure
+ };
+ DeviceSupport deviceSupport(const IOKit::Device &dev);
+
+ void addDevice(const IOKit::Device &dev);
+ void removeDevice(io_service_t service, uint32_t address);
+ void removeDeviceByName(const IOKit::Device &dev);
+ bool hasLegacyDriver(const IOKit::Device &dev);
+ bool isExcludedDevice(const IOKit::Device &dev);
+ void scheduleAddInterestNotification(io_service_t serviceOfInterest);
+ void addInterestNotification();
+ void removeAllDevices();
+ void AddIOKitNotifications();
+ void RemoveIOKitNotifications();
+ void rescanExistingDevices();
+
+ typedef std::map<uint32_t, RefPointer<PCSCD::Device> > DeviceMap;
+ DeviceMap mDevices;
+
+ mutable Mutex mDeviceMapLock;
+
+ void insert(pair<uint32_t, RefPointer<PCSCD::Device> > devicepair) { StLock<Mutex> _(mDeviceMapLock); mDevices.insert(devicepair); }
+ void remove(DeviceMap::iterator it) { StLock<Mutex> _(mDeviceMapLock); mDevices.erase(it); }
+
+private:
+ void (PCSCDMonitor::*mTimerAction)(); // what to do when our timer fires
+ bool mGoingToSleep; // between sleep and wakeup; special timer handling
+
+ mutable Mutex mLock;
+
+ IOKit::MachPortNotificationPort mIOKitNotifier; // IOKit connection
+ TerminationNoticeReceiver mTerminationNoticeReceiver;
+
+ io_object_t mRemoveNotification;
+ io_service_t mServiceOfInterest;
+
+ bool mSleepWakePeriod;
+ mutable Mutex mSleepWakePeriodLock;
+ mutable Mutex mWakeConditionLock;
+ Condition mWakeConditionVariable;
+ bool isSleepWakePeriod() const;
+ void sleepWakePeriod(bool isASleepWakePeriod);
+ void setSystemIsAwakeCondition(bool isAwake);
+
+ bool findDevice(const IOKit::Device &dev, DeviceMap::iterator &it);
+ bool findDeviceByName(const IOKit::Device &dev, DeviceMap::iterator &outit);
+ void updateDevice(const IOKit::Device &dev);
+ void setDeviceProperties(const IOKit::Device &dev, PCSCD::Device &device);
+
+ static void getVendorAndProductID(const IOKit::Device &dev, uint32_t &vendorID, uint32_t &productID, bool &isPCCard);
+ static bool deviceIsPCCard(const IOKit::Device &dev);
+ static bool deviceIsPCCard(io_service_t service);
+ static bool deviceAddress(io_service_t service, uint32_t &address);
+ static bool deviceAddress(const IOKit::Device &dev, uint32_t &address);
+ static bool deviceMemoryAddress(const IOKit::Device &dev, uint32_t &address);
+ static bool deviceMemoryAddress(io_service_t service, uint32_t &address);
+ static bool deviceMemoryAddressCore(CFArrayRef cfDeviceMemory, std::string path, uint32_t &address);
+ static bool addressFromPath(std::string path, uint32_t &address);
+
+ // debug
+ void setDebugPropertiesForDevice(const IOKit::Device &dev, PCSCD::Device* newDevice);
+ static void displayPropertiesOfDevice(const IOKit::Device &dev);
+ static void displayPropertiesOfDevice(io_service_t service);
+ void dumpDevices();
+};
+
+#endif /* __cplusplus__ */
+
+#endif //_H_PCSCDMONITOR
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+// server - pcscd main server object
+//
+#include "pcscdserver.h"
+#include <mach/mach_error.h>
+
+using namespace Security;
+using namespace MachPlusPlus;
+
+namespace PCSCD {
+
+Server::Server(const char *bootstrapName) : MachServer(bootstrapName),
+ mBootstrapName(bootstrapName)
+{
+ // Construct the server object
+ // engage the subsidiary port handler for sleep notifications
+ add(sleepWatcher);
+}
+
+Server::~Server()
+{
+ // Clean up the server object
+}
+
+void Server::run()
+{
+ // Run the server. This will not return until the server is forced to exit.
+ MachServer::run(0x10000,
+ MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) |
+ MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT));
+}
+
+//
+// Handle thread overflow. MachServer will call this if it has hit its thread
+// limit and yet still needs another thread.
+//
+void Server::threadLimitReached(UInt32 limit)
+{
+// Syslog::notice("pcscd has reached its thread limit (%ld) - service deadlock is possible",
+// limit);
+}
+
+void Server::notifyDeadName(Port port)
+{
+ // Handling dead-port notifications.
+ // This receives DPNs for all kinds of ports we're interested in.
+ StLock<Mutex> _(mLock);
+ secdebug("SSports", "port %d is dead", port.port());
+
+ // well, what IS IT?!
+ secdebug("server", "spurious dead port notification for port %d", port.port());
+}
+
+//
+// Handling no-senders notifications.
+// This is currently only used for (subsidiary) service ports
+//
+void Server::notifyNoSenders(Port port, mach_port_mscount_t)
+{
+ secdebug("SSports", "port %d no senders", port.port());
+// Session::destroy(port);
+}
+
+void Server::notifyIfDead(MachPlusPlus::Port port, bool doNotify) const
+{
+ secdebug("SSports", "port %d is dead", port.port());
+ MachServer::notifyIfDead(port, doNotify);
+}
+
+void Server::notifyIfUnused(MachPlusPlus::Port port, bool doNotify) const
+{
+ secdebug("SSports", "port %d is dead", port.port());
+ MachServer::notifyIfUnused(port, doNotify);
+}
+
+void Server::SleepWatcher::systemWillSleep()
+{
+ // Notifier for system sleep events
+ secdebug("SS", "sleep notification received");
+// Session::processSystemSleep();
+ secdebug("server", "distributing sleep event to %ld clients", mPowerClients.size());
+ for (set<PowerWatcher *>::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++)
+ (*it)->systemWillSleep();
+}
+
+void Server::SleepWatcher::systemIsWaking()
+{
+ secdebug("server", "distributing wakeup event to %ld clients", mPowerClients.size());
+ for (set<PowerWatcher *>::const_iterator it = mPowerClients.begin(); it != mPowerClients.end(); it++)
+ (*it)->systemIsWaking();
+}
+
+void Server::SleepWatcher::add(PowerWatcher *client)
+{
+ assert(mPowerClients.find(client) == mPowerClients.end());
+ mPowerClients.insert(client);
+}
+
+void Server::SleepWatcher::remove(PowerWatcher *client)
+{
+ assert(mPowerClients.find(client) != mPowerClients.end());
+ mPowerClients.erase(client);
+}
+
+boolean_t Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)
+{
+ // The primary server run-loop function
+ secdebug("SSreq", "Server::handle(mach_msg_header_t *in, mach_msg_header_t *out)");
+ return false;
+}
+
+
+} // end namespace PCSCD
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscdserver.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+// pcscdserver - stripped down securityd main server object
+//
+#ifndef _H_PCSCDSERVER
+#define _H_PCSCDSERVER
+
+#include <security_utilities/machserver.h>
+#include <security_utilities/powerwatch.h>
+#include <map>
+
+#if defined(__cplusplus)
+
+namespace PCSCD {
+//
+// The server object itself. This is the "go to" object for anyone who wants
+// to access the server's global state. It runs the show.
+// There is only one Server, and its name is Server::active().
+//
+
+class Server : public MachPlusPlus::MachServer
+{
+public:
+ Server(const char *bootstrapName);
+ ~Server();
+
+ // run the server until it shuts down
+ void run();
+
+ //
+ // Retrieve pieces of the Server's object web.
+ // These are all static methods that use the active() Server of this thread.
+ //
+ static Server &active() { return safer_cast<Server &>(MachServer::active()); }
+ static const char *bootstrapName() { return active().mBootstrapName.c_str(); }
+
+protected:
+ // implementation methods of MachServer
+ boolean_t handle(mach_msg_header_t *in, mach_msg_header_t *out);
+ void notifyDeadName(MachPlusPlus::Port port);
+ void notifyNoSenders(MachPlusPlus::Port port, mach_port_mscount_t);
+ void threadLimitReached(UInt32 count);
+ // request port status notifications (override virtual methods below to receive)
+ virtual void notifyIfDead(MachPlusPlus::Port port, bool doNotify = true) const;
+ virtual void notifyIfUnused(MachPlusPlus::Port port, bool doNotify = true) const;
+
+private:
+ class SleepWatcher : public MachPlusPlus::PortPowerWatcher
+ {
+ public:
+ void systemWillSleep();
+ void systemIsWaking();
+
+ void add(PowerWatcher *client);
+ void remove(PowerWatcher *client);
+
+ private:
+ set<PowerWatcher *> mPowerClients;
+ };
+
+ SleepWatcher sleepWatcher;
+
+public:
+ using MachServer::add;
+ using MachServer::remove;
+ void add(MachPlusPlus::PowerWatcher *client) { StLock<Mutex> _(mLock); sleepWatcher.add(client); }
+ void remove(MachPlusPlus::PowerWatcher *client) { StLock<Mutex> _(mLock); sleepWatcher.remove(client); }
+
+private:
+ // mach bootstrap registration name
+ std::string mBootstrapName;
+ mutable Mutex mLock;
+};
+
+} // end namespace PCSCD
+
+#endif /* __cplusplus__ */
+
+#endif //_H_PCSCDSERVER
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscexport.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscexport.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcscexport.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,62 @@
+/*
+ * This handles GCC attributes
+ *
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2005
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: misc.h 2188 2006-10-19 11:29:29Z rousseau $
+ */
+
+#ifndef __misc_h__
+#define __misc_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*
+ * Declare the function as internal to the library: the function name is
+ * not exported and can't be used by a program linked to the library
+ *
+ * see http://gcc.gnu.org/onlinedocs/gcc-3.3.5/gcc/Function-Attributes.html#Function-Attributes
+ * see http://www.nedprod.com/programs/gccvisibility.html
+ */
+#if defined __GNUC__ && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3))
+#define INTERNAL __attribute__ ((visibility("hidden")))
+/*
+#define PCSC_API __attribute__ ((visibility("default")))
+We don't want to change how this was defined in previous versions*/
+#define PCSC_API
+#else
+#define INTERNAL
+#define PCSC_API
+#endif
+#define EXTERNAL PCSC_API
+
+#if defined __GNUC__
+
+/* GNU Compiler Collection (GCC) */
+#define CONSTRUCTOR __attribute__ ((constructor))
+#define DESTRUCTOR __attribute__ ((destructor))
+
+#else
+
+/* SUN C compiler does not use __attribute__ but #pragma init (function)
+ * We can't use a # inside a #define so it is not possible to use
+ * #define CONSTRUCTOR_DECLARATION(x) #pragma init (x)
+ * The #pragma is used directly where needed */
+
+/* any other */
+#define CONSTRUCTOR
+#define DESTRUCTOR
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __misc_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcsclite.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcsclite.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/pcsclite.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,291 @@
+/*
+ * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: pcsclite.h.in 2124 2006-08-07 14:18:52Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps a list of defines for pcsc-lite.
+ */
+
+#ifndef __pcsclite_h__
+#define __pcsclite_h__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef int32_t SCARDCONTEXT;
+typedef SCARDCONTEXT *PSCARDCONTEXT;
+typedef SCARDCONTEXT *LPSCARDCONTEXT;
+typedef int32_t SCARDHANDLE;
+typedef SCARDHANDLE *PSCARDHANDLE;
+typedef SCARDHANDLE *LPSCARDHANDLE;
+
+#define MAX_ATR_SIZE 33 /**< Maximum ATR size */
+
+/* Set structure elements aligment on bytes
+ * http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html */
+#ifdef __APPLE__
+#pragma pack(1)
+#else
+#pragma pack(push, 1)
+#endif
+
+typedef struct
+{
+ const char *szReader;
+ void *pvUserData;
+ uint32_t dwCurrentState;
+ uint32_t dwEventState;
+ uint32_t cbAtr;
+ unsigned char rgbAtr[MAX_ATR_SIZE];
+}
+SCARD_READERSTATE_A;
+
+typedef SCARD_READERSTATE_A SCARD_READERSTATE, *PSCARD_READERSTATE_A,
+ *LPSCARD_READERSTATE_A;
+
+typedef struct _SCARD_IO_REQUEST
+{
+ uint32_t dwProtocol; /* Protocol identifier */
+ uint32_t cbPciLength; /* Protocol Control Inf Length */
+}
+SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
+
+typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST;
+
+extern SCARD_IO_REQUEST g_rgSCardT0Pci, g_rgSCardT1Pci,
+ g_rgSCardRawPci;
+
+/* restore default structure elements alignment */
+#ifdef __APPLE__
+#pragma pack()
+#else
+#pragma pack(pop)
+#endif
+
+#define SCARD_PCI_T0 (&g_rgSCardT0Pci)
+#define SCARD_PCI_T1 (&g_rgSCardT1Pci)
+#define SCARD_PCI_RAW (&g_rgSCardRawPci)
+
+#define SCARD_S_SUCCESS 0x00000000
+#define SCARD_E_CANCELLED 0x80100002
+#define SCARD_E_CANT_DISPOSE 0x8010000E
+#define SCARD_E_INSUFFICIENT_BUFFER 0x80100008
+#define SCARD_E_INVALID_ATR 0x80100015
+#define SCARD_E_INVALID_HANDLE 0x80100003
+#define SCARD_E_INVALID_PARAMETER 0x80100004
+#define SCARD_E_INVALID_TARGET 0x80100005
+#define SCARD_E_INVALID_VALUE 0x80100011
+#define SCARD_E_NO_MEMORY 0x80100006
+#define SCARD_F_COMM_ERROR 0x80100013
+#define SCARD_F_INTERNAL_ERROR 0x80100001
+#define SCARD_F_UNKNOWN_ERROR 0x80100014
+#define SCARD_F_WAITED_TOO_LONG 0x80100007
+#define SCARD_E_UNKNOWN_READER 0x80100009
+#define SCARD_E_TIMEOUT 0x8010000A
+#define SCARD_E_SHARING_VIOLATION 0x8010000B
+#define SCARD_E_NO_SMARTCARD 0x8010000C
+#define SCARD_E_UNKNOWN_CARD 0x8010000D
+#define SCARD_E_PROTO_MISMATCH 0x8010000F
+#define SCARD_E_NOT_READY 0x80100010
+#define SCARD_E_SYSTEM_CANCELLED 0x80100012
+#define SCARD_E_NOT_TRANSACTED 0x80100016
+#define SCARD_E_READER_UNAVAILABLE 0x80100017
+
+#define SCARD_W_UNSUPPORTED_CARD 0x80100065
+#define SCARD_W_UNRESPONSIVE_CARD 0x80100066
+#define SCARD_W_UNPOWERED_CARD 0x80100067
+#define SCARD_W_RESET_CARD 0x80100068
+#define SCARD_W_REMOVED_CARD 0x80100069
+
+#define SCARD_E_PCI_TOO_SMALL 0x80100019
+#define SCARD_E_READER_UNSUPPORTED 0x8010001A
+#define SCARD_E_DUPLICATE_READER 0x8010001B
+#define SCARD_E_CARD_UNSUPPORTED 0x8010001C
+#define SCARD_E_NO_SERVICE 0x8010001D
+#define SCARD_E_SERVICE_STOPPED 0x8010001E
+
+#define SCARD_SCOPE_USER 0x0000 /**< Scope in user space */
+#define SCARD_SCOPE_TERMINAL 0x0001 /**< Scope in terminal */
+#define SCARD_SCOPE_SYSTEM 0x0002 /**< Scope in system */
+
+#define SCARD_PROTOCOL_UNSET 0x0000 /**< protocol not set */
+#define SCARD_PROTOCOL_T0 0x0001 /**< T=0 active protocol. */
+#define SCARD_PROTOCOL_T1 0x0002 /**< T=1 active protocol. */
+#define SCARD_PROTOCOL_RAW 0x0004 /**< Raw active protocol. */
+#define SCARD_PROTOCOL_T15 0x0008 /**< T=15 protocol. */
+
+#define SCARD_PROTOCOL_ANY (SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1) /**< IFD determines prot. */
+
+#define SCARD_SHARE_EXCLUSIVE 0x0001 /**< Exclusive mode only */
+#define SCARD_SHARE_SHARED 0x0002 /**< Shared mode only */
+#define SCARD_SHARE_DIRECT 0x0003 /**< Raw mode only */
+
+#define SCARD_LEAVE_CARD 0x0000 /**< Do nothing on close */
+#define SCARD_RESET_CARD 0x0001 /**< Reset on close */
+#define SCARD_UNPOWER_CARD 0x0002 /**< Power down on close */
+#define SCARD_EJECT_CARD 0x0003 /**< Eject on close */
+
+#define SCARD_UNKNOWN 0x0001 /**< Unknown state */
+#define SCARD_ABSENT 0x0002 /**< Card is absent */
+#define SCARD_PRESENT 0x0004 /**< Card is present */
+#define SCARD_SWALLOWED 0x0008 /**< Card not powered */
+#define SCARD_POWERED 0x0010 /**< Card is powered */
+#define SCARD_NEGOTIABLE 0x0020 /**< Ready for PTS */
+#define SCARD_SPECIFIC 0x0040 /**< PTS has been set */
+
+#define SCARD_STATE_UNAWARE 0x0000 /**< App wants status */
+#define SCARD_STATE_IGNORE 0x0001 /**< Ignore this reader */
+#define SCARD_STATE_CHANGED 0x0002 /**< State has changed */
+#define SCARD_STATE_UNKNOWN 0x0004 /**< Reader unknown */
+#define SCARD_STATE_UNAVAILABLE 0x0008 /**< Status unavailable */
+#define SCARD_STATE_EMPTY 0x0010 /**< Card removed */
+#define SCARD_STATE_PRESENT 0x0020 /**< Card inserted */
+#define SCARD_STATE_ATRMATCH 0x0040 /**< ATR matches card */
+#define SCARD_STATE_EXCLUSIVE 0x0080 /**< Exclusive Mode */
+#define SCARD_STATE_INUSE 0x0100 /**< Shared Mode */
+#define SCARD_STATE_MUTE 0x0200 /**< Unresponsive card */
+#define SCARD_STATE_UNPOWERED 0x0400 /**< Unpowered card */
+
+/** PC/SC Lite specific extensions */
+#define SCARD_W_INSERTED_CARD 0x8010006A
+#define SCARD_E_UNSUPPORTED_FEATURE 0x8010001F
+
+#define SCARD_SCOPE_GLOBAL 0x0003 /**< Scope is global */
+
+#define SCARD_RESET 0x0001 /**< Card was reset */
+#define SCARD_INSERTED 0x0002 /**< Card was inserted */
+#define SCARD_REMOVED 0x0004 /**< Card was removed */
+
+#define BLOCK_STATUS_RESUME 0x00FF /**< Normal resume */
+#define BLOCK_STATUS_BLOCKING 0x00FA /**< Function is blocking */
+
+#define PCSCLITE_CONFIG_DIR "/etc"
+
+#ifndef USE_IPCDIR
+#define PCSCLITE_IPC_DIR "/var/run"
+#else
+#define PCSCLITE_IPC_DIR USE_IPCDIR
+#endif
+
+#define PCSCLITE_READER_CONFIG PCSCLITE_CONFIG_DIR "/reader.conf"
+#define PCSCLITE_PUBSHM_FILE PCSCLITE_IPC_DIR "/pcscd.pub"
+#define PCSCLITE_CSOCK_NAME PCSCLITE_IPC_DIR "/pcscd.comm"
+
+#define PCSCLITE_SVC_IDENTITY 0x01030000 /**< Service ID */
+
+#ifndef INFINITE
+#define INFINITE 0xFFFFFFFF /**< Infinite timeout */
+#endif
+#define PCSCLITE_INFINITE_TIMEOUT 4320000 /**< 50 day infinite t/o */
+
+#define PCSCLITE_VERSION_NUMBER "1.4.0" /**< Current version */
+#define PCSCLITE_CLIENT_ATTEMPTS 120 /**< Attempts to reach sv */
+#define PCSCLITE_MCLIENT_ATTEMPTS 20 /**< Attempts to reach sv */
+#define PCSCLITE_STATUS_POLL_RATE 400000 /**< Status polling rate */
+#define PCSCLITE_MSG_KEY_LEN 16 /**< App ID key length */
+#define PCSCLITE_RW_ATTEMPTS 100 /**< Attempts to rd/wrt */
+
+/** Maximum applications */
+#define PCSCLITE_MAX_APPLICATIONS 16
+/** Maximum contexts by application */
+#define PCSCLITE_MAX_APPLICATION_CONTEXTS 16
+/** Maximum of applications contexts that pcscd can accept */
+#define PCSCLITE_MAX_APPLICATIONS_CONTEXTS \
+ PCSCLITE_MAX_APPLICATIONS * PCSCLITE_MAX_APPLICATION_CONTEXTS
+/** Maximum channels on a reader context */
+#define PCSCLITE_MAX_READER_CONTEXT_CHANNELS 16
+/** Maximum channels on an application context */
+#define PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS 16
+/** Maximum readers context (a slot is count as a reader) */
+#define PCSCLITE_MAX_READERS_CONTEXTS 16
+
+/* PCSCLITE_MAX_READERS is deprecated
+ * use PCSCLITE_MAX_READERS_CONTEXTS instead */
+/* extern int PCSCLITE_MAX_READERS __attribute__ ((deprecated)); */
+
+#define PCSCLITE_MAX_THREADS 16 /**< Stat change threads */
+#define PCSCLITE_STATUS_WAIT 200000 /**< Status Change Sleep */
+#define PCSCLITE_TRANSACTION_TIMEOUT 40 /**< Transaction timeout */
+#define MAX_READERNAME 52
+#define MAX_LIBNAME 100
+#define MAX_DEVICENAME 255
+
+#ifndef SCARD_ATR_LENGTH
+#define SCARD_ATR_LENGTH MAX_ATR_SIZE /**< Maximum ATR size */
+#endif
+
+/* These are deprecated */
+#define PCSCLITE_MAX_CHANNELS 16 /* Maximum channels */
+#define PCSCLITE_MAX_CONTEXTS 16 /* Maximum readers */
+#define PCSCLITE_MAX_COMSIZE 64 /* Maximum arg size */
+
+/*
+ * Enhanced messaging has been added to accomodate newer devices which have
+ * more advanced capabilites, such as dedicated secure co-processors which
+ * can stream and encrypt data over USB. In order to used enhanced messaging
+ * you must define PCSCLITE_ENHANCED_MESSAGING in the framework(library),
+ * the daemon, and your application
+ */
+
+/*
+ * The message and buffer sizes must be multiples of 16.
+ * The max message size must be at least large enough
+ * to accomodate the transmit_struct
+ */
+
+#ifndef PCSCLITE_ENHANCED_MESSAGING
+#define PCSCLITE_MAX_MESSAGE_SIZE 2048 /**< Transport msg len */
+#define MAX_BUFFER_SIZE 264 /**< Maximum Tx/Rx Buffer for short APDU */
+#define PCSCLITE_SERVER_ATTEMPTS 5 /**< Attempts to reach cl */
+#else
+#define PCSCLITE_MAX_MESSAGE_SIZE (1<<17) /* enhanced (128K) msg len */
+#define MAX_BUFFER_SIZE (1<<15) /* enhanced (32K) Tx/Rx Buffer */
+#define PCSCLITE_SERVER_ATTEMPTS 200 /* To allow larger data reads/writes */
+#endif
+
+#define MAX_BUFFER_SIZE_EXTENDED (4 + 3 + (1<<16) + 3) /**< enhanced (64K + APDU + Lc + Le) Tx/Rx Buffer */
+
+/*
+ * Gets a stringified error response
+ */
+char *pcsc_stringify_error(int32_t err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_generic.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_generic.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_generic.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : powermgt_generic.h
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 04/22/02
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This handles power management routines.
+
+$Id: powermgt_generic.h,v 1.2 2003/02/13 20:06:28 ghoo Exp $
+
+********************************************************************/
+
+#ifndef __powermgt_generic_h__
+#define __powermgt_generic_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+/*
+ * Registers for Power Management callbacks
+ */
+
+ULONG PMRegisterForPowerEvents();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_macosx.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_macosx.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/powermgt_macosx.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+cc test2.c -o pm_callback -Wall -Wno-four-char-constants -framework IOKit -framework CoreFoundation
+*/
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <mach/mach_port.h>
+#include <mach/mach_interface.h>
+#include <mach/mach_init.h>
+
+#include <IOKit/pwr_mgt/IOPMLib.h>
+#include <IOKit/IOMessage.h>
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "debuglog.h"
+#include "readerfactory.h"
+#include "thread_generic.h"
+#include "hotplug.h"
+
+
+static io_connect_t root_port;
+static IONotificationPortRef notify;
+static io_object_t anIterator;
+
+PCSCLITE_THREAD_T pmgmtThread;
+extern PCSCLITE_MUTEX usbNotifierMutex;
+
+void PMPowerRegistrationThread();
+
+
+void PMPowerEventCallback(void * x,io_service_t y,natural_t messageType,void * messageArgument)
+{
+
+ switch ( messageType ) {
+ case kIOMessageCanSystemSleep:
+ IOAllowPowerChange(root_port,(long)messageArgument);
+ break;
+ case kIOMessageSystemWillSleep:
+ DebugLogA("PMPowerEventCallback: system will sleep");
+ SYS_MutexLock(&usbNotifierMutex);
+ // see WrapRFSuspendAllReaders
+ // RFSuspendAllReaders();
+ IOAllowPowerChange(root_port,(long)messageArgument);
+ DebugLogA("PMPowerEventCallback: system allowed to sleep");
+ break;
+ case kIOMessageSystemHasPoweredOn:
+ DebugLogA("PMPowerEventCallback: system has powered on");
+ // see WrapRFSuspendAllReaders
+ // HPSearchHotPluggables();
+ // RFAwakeAllReaders();
+ SYS_MutexUnLock(&usbNotifierMutex);
+ break;
+ case kIOMessageSystemWillPowerOn:
+ DebugLogA("PMPowerEventCallback: system will power on");
+ break;
+ default:
+ DebugLogB("PMPowerEventCallback: unknown event: %d", messageType);
+ break;
+ }
+
+}
+
+void PMPowerRegistrationThread() {
+
+ root_port = IORegisterForSystemPower (0,¬ify,PMPowerEventCallback,&anIterator);
+
+ if ( root_port == 0 ) {
+ printf("IORegisterForSystemPower failed\n");
+ return;
+ }
+
+ CFRunLoopAddSource(CFRunLoopGetCurrent(),
+ IONotificationPortGetRunLoopSource(notify),
+ kCFRunLoopDefaultMode);
+
+ CFRunLoopRun();
+}
+
+ULONG PMRegisterForPowerEvents()
+{
+ LONG rv;
+ DebugLogA("PMRegisterForPowerEvents");
+ rv = SYS_ThreadCreate(&pmgmtThread, THREAD_ATTR_DEFAULT, (LPVOID) PMPowerRegistrationThread, NULL);
+ return 0;
+}
+
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,185 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * prothandler.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 2004
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: prothandler.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles protocol defaults, PTS, etc.
+ */
+
+#include "config.h"
+#include <string.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "ifdhandler.h"
+#include "debuglog.h"
+#include "readerfactory.h"
+#include "prothandler.h"
+#include "atrhandler.h"
+#include "ifdwrapper.h"
+#include "eventhandler.h"
+
+/*
+ * Function: PHGetDefaultProtocol Purpose : To get the default protocol
+ * used immediately after reset. This protocol is returned from the
+ * function.
+ */
+
+UCHAR PHGetDefaultProtocol(const unsigned char *pucAtr, DWORD dwLength)
+{
+ SMARTCARD_EXTENSION sSmartCard;
+
+ /*
+ * Zero out everything
+ */
+ memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION));
+
+ if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength))
+ return sSmartCard.CardCapabilities.CurrentProtocol;
+ else
+ return 0x00;
+}
+
+/*
+ * Function: PHGetAvailableProtocols Purpose : To get the protocols
+ * supported by the card. These protocols are returned from the function
+ * as bit masks.
+ */
+
+UCHAR PHGetAvailableProtocols(const unsigned char *pucAtr, DWORD dwLength)
+{
+ SMARTCARD_EXTENSION sSmartCard;
+
+ /*
+ * Zero out everything
+ */
+ memset(&sSmartCard, 0x00, sizeof(SMARTCARD_EXTENSION));
+
+ if (ATRDecodeAtr(&sSmartCard, pucAtr, dwLength))
+ return sSmartCard.CardCapabilities.AvailableProtocols;
+ else
+ return 0x00;
+}
+
+/*
+ * Function: PHSetProtocol Purpose : To determine which protocol to use.
+ * SCardConnect has a DWORD dwPreferredProtocols that is a bitmask of what
+ * protocols to use. Basically, if T=N where N is not zero will be used
+ * first if it is available in ucAvailable. Otherwise it will always
+ * default to T=0.
+ *
+ * IFDSetPTS() is _always_ called so that the driver can initialise its data
+ */
+
+DWORD PHSetProtocol(struct ReaderContext * rContext,
+ DWORD dwPreferred, UCHAR ucAvailable, UCHAR ucDefault)
+{
+ DWORD protocol;
+ LONG rv;
+ UCHAR ucChosen;
+
+ /* App has specified no protocol */
+ if (dwPreferred == 0)
+ return SET_PROTOCOL_WRONG_ARGUMENT;
+
+ /* requested protocol is not available */
+ if (! (dwPreferred & ucAvailable))
+ {
+ /* Note:
+ * dwPreferred must be either SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
+ * if dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1 the test
+ * (SCARD_PROTOCOL_T0 == dwPreferred) will not work as expected
+ * and the debug message will not be correct.
+ *
+ * This case may only occur if
+ * dwPreferred == SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1
+ * and ucAvailable == 0 since we have (dwPreferred & ucAvailable) == 0
+ * and the case ucAvailable == 0 should never occur (the card is at
+ * least T=0 or T=1)
+ */
+ Log2(PCSC_LOG_ERROR, "Protocol T=%d requested but unsupported by the card",
+ (SCARD_PROTOCOL_T0 == dwPreferred) ? 0 : 1);
+ return SET_PROTOCOL_WRONG_ARGUMENT;
+ }
+
+ /* set default value */
+ protocol = ucDefault;
+
+ /* keep only the available protocols */
+ dwPreferred &= ucAvailable;
+
+ /* we try to use T=1 first */
+ if (dwPreferred & SCARD_PROTOCOL_T1)
+ ucChosen = SCARD_PROTOCOL_T1;
+ else
+ if (dwPreferred & SCARD_PROTOCOL_T0)
+ ucChosen = SCARD_PROTOCOL_T0;
+ else
+ /* App wants unsupported protocol */
+ return SET_PROTOCOL_WRONG_ARGUMENT;
+
+ Log2(PCSC_LOG_INFO, "Attempting PTS to T=%d",
+ (SCARD_PROTOCOL_T0 == ucChosen ? 0 : 1));
+ rv = IFDSetPTS(rContext, ucChosen, 0x00, 0x00, 0x00, 0x00);
+
+ if (IFD_SUCCESS == rv)
+ protocol = ucChosen;
+ else
+ if (IFD_NOT_SUPPORTED == rv)
+ Log2(PCSC_LOG_INFO, "PTS not supported by driver, using T=%d",
+ (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
+ else
+ if (IFD_PROTOCOL_NOT_SUPPORTED == rv)
+ Log2(PCSC_LOG_INFO, "PTS protocol not supported, using T=%d",
+ (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
+ else
+ {
+ Log3(PCSC_LOG_INFO, "PTS failed (%d), using T=%d", rv,
+ (SCARD_PROTOCOL_T0 == protocol) ? 0 : 1);
+
+ /* ISO 7816-3:1997 ch. 7.2 PPS protocol page 14
+ * - If the PPS exchange is unsuccessful, then the interface device
+ * shall either reset or reject the card.
+ */
+ return SET_PROTOCOL_PPS_FAILED;
+ }
+
+ return protocol;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/prothandler.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * prothandler.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 2004
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: prothandler.h 1421 2005-04-12 12:09:21Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles protocol defaults, PTS, etc.
+ */
+
+#ifndef __prothandler_h__
+#define __prothandler_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ UCHAR PHGetDefaultProtocol(const unsigned char *, DWORD);
+ UCHAR PHGetAvailableProtocols(const unsigned char *, DWORD);
+ DWORD PHSetProtocol(struct ReaderContext *, DWORD, UCHAR, UCHAR);
+
+#define SET_PROTOCOL_WRONG_ARGUMENT -1
+#define SET_PROTOCOL_PPS_FAILED -2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __prothandler_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * reader.cpp
+ * SmartCardServices
+*/
+
+#include "reader.h"
+#include "eventhandler.h"
+#include "pcsclite.h"
+#include <security_utilities/debugging.h>
+
+static PCSCD::Readers *mReaders;
+
+namespace PCSCD {
+
+
+Readers::Readers()
+{
+}
+
+Readers::~Readers()
+{
+}
+
+bool Readers::find(const char *name, XReaderContext &rc) const
+{
+ return false;
+}
+
+bool Readers::find(uint32_t port, const char *name, XReaderContext &rc) const
+{
+ return false;
+}
+
+bool Readers::find(uint32_t id, XReaderContext &rc) const
+{
+ return false;
+}
+
+
+} // end namespace PCSCD
+
+#pragma mark ---------- C Interface ----------
+
+LONG XRFAllocateReaderSpace(DWORD dwAllocNum)
+{
+ try
+ {
+ mReaders = new PCSCD::Readers();
+ }
+ catch (...)
+ {
+ secdebug("pcscd", "failed to allocate Readers");
+ return -1;
+ }
+ return EHInitializeEventStructures();
+}
+
+LONG XRFReaderInfo(LPSTR lpcReader, PREADER_CONTEXT *sReader)
+{
+ // Find a reader given a name
+ PCSCD::XReaderContext rc; //>>>> use iterator instead
+ if (!sReader)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (!mReaders->find(lpcReader, rc))
+ return SCARD_E_UNKNOWN_READER;
+
+ *sReader = &rc; //>>>> WRONG - temporary var
+ return SCARD_S_SUCCESS;
+}
+
+LONG XRFReaderInfoNamePort(DWORD dwPort, LPSTR lpcReader, PREADER_CONTEXT *sReader)
+{
+ // Find a reader given a name
+ PCSCD::XReaderContext rc;
+ if (!sReader)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (!mReaders->find(dwPort, lpcReader, rc))
+ return SCARD_E_UNKNOWN_READER;
+
+ *sReader = &rc; //>>>> WRONG - temporary var
+ return SCARD_S_SUCCESS;
+}
+
+LONG XRFReaderInfoById(DWORD dwIdentity, PREADER_CONTEXT * sReader)
+{
+ // Find a reader given a handle
+ PCSCD::XReaderContext rc;
+ if (!sReader)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (!mReaders->find(dwIdentity, rc))
+ return SCARD_E_INVALID_VALUE;
+
+ *sReader = &rc; //>>>> WRONG - temporary var
+ return SCARD_S_SUCCESS;
+}
+
+LONG XRFCheckSharing(DWORD hCard)
+{
+ PCSCD::XReaderContext rc;
+ if (!mReaders->find(hCard, rc))
+ return SCARD_E_INVALID_VALUE;
+
+ return (rc.dwLockId == 0 || rc.dwLockId == hCard)?SCARD_S_SUCCESS:SCARD_E_SHARING_VIOLATION;
+}
+
+LONG XRFLockSharing(DWORD hCard)
+{
+ PCSCD::XReaderContext rc;
+ if (!mReaders->find(hCard, rc))
+ return SCARD_E_INVALID_VALUE;
+
+ if (rc.dwLockId != 0 && rc.dwLockId != hCard)
+ {
+ secdebug("pcscd", "XRFLockSharing: Lock ID invalid: %d", rc.dwLockId);
+ return SCARD_E_SHARING_VIOLATION;
+ }
+
+ EHSetSharingEvent(&rc, 1);
+ rc.dwLockId = hCard;
+ return SCARD_S_SUCCESS;
+}
+
+LONG XRFUnlockSharing(DWORD hCard)
+{
+ PCSCD::XReaderContext rc;
+ if (!mReaders->find(hCard, rc))
+ return SCARD_E_INVALID_VALUE;
+
+ if (rc.dwLockId != 0 && rc.dwLockId != hCard)
+ {
+ secdebug("pcscd", "XRFUnlockSharing: Lock ID invalid: %d", rc.dwLockId);
+ return SCARD_E_SHARING_VIOLATION;
+ }
+
+ EHSetSharingEvent(&rc, 0);
+ rc.dwLockId = 0;
+ return SCARD_S_SUCCESS;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/reader.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * reader.h
+ * SmartCardServices
+ */
+
+#ifndef _H_PCSCD_READER
+#define _H_PCSCD_READER
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "readerfactory.h"
+#include <security_utilities/refcount.h>
+#include <security_cdsa_utilities/handleobject.h>
+#include <map>
+
+#if 0
+ struct ReaderContext
+ {
+ char lpcReader[MAX_READERNAME]; /* Reader Name */
+ char lpcLibrary[MAX_LIBNAME]; /* Library Path */
+ PCSCLITE_THREAD_T pthThread; /* Event polling thread */
+ PCSCLITE_MUTEX_T mMutex; /* Mutex for this connection */
+ RDR_CAPABILITIES psCapabilites; /* Structure of reader
+ capabilities */
+ PROT_OPTIONS psProtOptions; /* Structure of protocol options */
+ RDR_CLIHANDLES psHandles[PCSCLITE_MAX_CONTEXTS];
+ /* Structure of connected handles */
+ FCT_MAP psFunctions; /* Structure of function pointers */
+ UCHAR ucAtr[MAX_ATR_SIZE]; /* Atr for inserted card */
+ DWORD dwAtrLen; /* Size of the ATR */
+ LPVOID vHandle; /* Dlopen handle */
+ DWORD dwVersion; /* IFD Handler version number */
+ DWORD dwPort; /* Port ID */
+ DWORD dwProtocol; /* Currently used protocol */
+ DWORD dwSlot; /* Current Reader Slot */
+ DWORD dwBlockStatus; /* Current blocking status */
+ DWORD dwStatus; /* Current Status Mask */
+ DWORD dwLockId; /* Lock Id */
+ DWORD dwIdentity; /* Shared ID High Nibble */
+ DWORD dwContexts; /* Number of open contexts */
+ DWORD dwPublicID; /* Public id of public state struct */
+ PDWORD dwFeeds; /* Number of shared client to lib */
+ };
+#endif
+
+#if defined(__cplusplus)
+
+namespace PCSCD {
+
+//
+// The server object itself. This is the "go to" object for anyone who wants
+// to access the server's global state. It runs the show.
+// There is only one Server, and its name is Server::active().
+//
+
+//
+// A PODWrapper for the PCSC READER_CONTEXT structure
+//
+class XReaderContext : public PodWrapper<XReaderContext, READER_CONTEXT>
+{
+public:
+ void set(const char *name, unsigned long known = SCARD_STATE_UNAWARE);
+
+ const char *name() const { return lpcReader; }
+// void name(const char *s) { szReader = s; }
+
+// unsigned long lastKnown() const { return dwStatus; }
+ void lastKnown(unsigned long s);
+
+ unsigned long state() const { return 0; } //fix
+ bool state(unsigned long it) const { return state() & it; }
+ bool changed() const { return state(SCARD_STATE_CHANGED); }
+
+// template <class T>
+// T * &userData() { return reinterpret_cast<T * &>(pvUserData); }
+
+ // DataOid access to the ATR data
+// const void *data() const { return ucAtr; }
+// size_t length() const { return dwAtrLen; }
+ void setATR(const void *atr, size_t size);
+
+ IFDUMP(void dump());
+};
+
+
+class Reader : public HandleObject, public RefCount
+{
+public:
+ Reader(const char *bootstrapName);
+ ~Reader();
+private:
+ // mach bootstrap registration name
+ std::string mBootstrapName;
+ mutable Mutex mLock;
+};
+
+class Readers
+{
+public:
+ Readers();
+ ~Readers();
+
+ typedef std::map<uint32_t, RefPointer<PCSCD::Reader> > ReaderMap;
+ ReaderMap mReaders;
+
+ bool find(uint32_t id, XReaderContext &rc) const;
+ bool find(const char *name, XReaderContext &rc) const;
+ bool find(uint32_t port, const char *name, XReaderContext &rc) const;
+
+ mutable Mutex mReaderMapLock;
+
+ void insert(pair<uint32_t, RefPointer<PCSCD::Reader> > readerpair) { StLock<Mutex> _(mReaderMapLock); mReaders.insert(readerpair); }
+ void remove(ReaderMap::iterator it) { StLock<Mutex> _(mReaderMapLock); mReaders.erase(it); }
+
+private:
+ mutable Mutex mLock;
+};
+
+} // end namespace PCSCD
+
+#endif /* __cplusplus__ */
+
+#endif //_H_PCSCD_READER
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1469 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * readerfactory.c
+ * SmartCardServices
+ */
+
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : readerfactory.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 7/27/99
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This keeps track of a list of currently
+ available reader structures.
+
+$Id: readerfactory.c,v 1.3 2004/10/14 20:33:35 mb Exp $
+
+********************************************************************/
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/errno.h>
+#include <fcntl.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "ifdhandler.h"
+#include "debuglog.h"
+#include "thread_generic.h"
+#include "readerfactory.h"
+#include "dyn_generic.h"
+#include "sys_generic.h"
+#include "eventhandler.h"
+#include "ifdwrapper.h"
+#include "readerState.h"
+
+#include <security_utilities/debugging.h>
+
+#ifndef PCSCLITE_HP_BASE_PORT
+#define PCSCLITE_HP_BASE_PORT 0x200000
+#endif /* PCSCLITE_HP_BASE_PORT */
+
+static LONG RFLoadReader(PREADER_CONTEXT);
+static LONG RFUnBindFunctions(PREADER_CONTEXT);
+static LONG RFUnloadReader(PREADER_CONTEXT);
+
+static PREADER_CONTEXT sReadersContexts[PCSCLITE_MAX_READERS_CONTEXTS];
+static DWORD dwNumReadersContexts = 0;
+static DWORD lastLockID = 0;
+static PCSCLITE_MUTEX_T sReadersContextsLock = NULL;
+
+static int ReaderContextConstructor(PREADER_CONTEXT ctx, LPCSTR lpcReader,
+ DWORD dwPort, LPCSTR lpcLibrary, LPCSTR lpcDevice);
+static void ReaderContextDestructor(PREADER_CONTEXT ctx);
+static void ReaderContextFree(PREADER_CONTEXT ctx);
+static void ReaderContextClear(PREADER_CONTEXT ctx);
+static int ReaderContextInsert(PREADER_CONTEXT ctx);
+static int ReaderContextRemove(PREADER_CONTEXT ctx);
+static int ReaderContextCheckDuplicateReader(LPCSTR lpcReader, DWORD dwPort);
+static int ReaderSlotCount(PREADER_CONTEXT ctx);
+static BOOL ReaderDriverIsThreadSafe(PREADER_CONTEXT ctx, BOOL testSlot);
+static BOOL ReaderNameMatchForIndex(DWORD dwPort, LPCSTR lpcReader, int index);
+static void ReaderContextDuplicateSlot(PREADER_CONTEXT ctxBase, PREADER_CONTEXT ctxSlot, int slotNumber, BOOL baseIsThreadSafe);
+static int ReaderCheckForClone(PREADER_CONTEXT ctx, LPCSTR lpcReader,
+ DWORD dwPort, LPCSTR lpcLibrary);
+
+
+LONG RFAllocateReaderSpace()
+{
+ int i;
+
+ sReadersContextsLock = (PCSCLITE_MUTEX_T) malloc(sizeof(PCSCLITE_MUTEX));
+ SYS_MutexInit(sReadersContextsLock);
+
+ /*
+ * Allocate each reader structure
+ */
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ sReadersContexts[i] = (PREADER_CONTEXT) calloc(1, sizeof(READER_CONTEXT));
+
+ /*
+ * Create public event structures
+ */
+ return EHInitializeEventStructures();
+}
+
+LONG RFAddReader(LPSTR lpcReader, DWORD dwPort, LPSTR lpcLibrary, LPSTR lpcDevice)
+{
+ int slotCount;
+ LONG rv = SCARD_E_NO_MEMORY;
+ int slot;
+ PREADER_CONTEXT baseContext = NULL;
+
+ if ((lpcReader == NULL) || (lpcLibrary == NULL) || (lpcDevice == NULL))
+ return SCARD_E_INVALID_VALUE;
+
+ /* Reader name too long? */
+ if (strlen(lpcReader) >= MAX_READERNAME)
+ {
+ Log3(PCSC_LOG_ERROR, "Reader name too long: %d chars instead of max %d",
+ strlen(lpcReader), MAX_READERNAME);
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ /* Library name too long? */
+ if (strlen(lpcLibrary) >= MAX_LIBNAME)
+ {
+ Log3(PCSC_LOG_ERROR, "Library name too long: %d chars instead of max %d",
+ strlen(lpcLibrary), MAX_LIBNAME);
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ /* Device name too long? */
+ if (strlen(lpcDevice) >= MAX_DEVICENAME)
+ {
+ Log3(PCSC_LOG_ERROR, "Device name too long: %d chars instead of max %d",
+ strlen(lpcDevice), MAX_DEVICENAME);
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ rv = ReaderContextCheckDuplicateReader(lpcReader, dwPort);
+ if (rv)
+ return rv;
+
+ // Make sure we have an empty slot to put the reader structure
+ rv = ReaderContextInsert(NULL);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ // Allocate a temporary reader context struct
+ baseContext = (PREADER_CONTEXT) calloc(1, sizeof(READER_CONTEXT));
+
+ rv = ReaderContextConstructor(baseContext, lpcReader, dwPort, lpcLibrary, lpcDevice);
+ if (rv != SCARD_S_SUCCESS)
+ goto xit;
+
+ rv = ReaderCheckForClone(baseContext, lpcReader, dwPort, lpcLibrary);
+ if (rv != SCARD_S_SUCCESS)
+ goto xit;
+
+ rv = RFInitializeReader(baseContext);
+ if (rv != SCARD_S_SUCCESS)
+ goto xit;
+
+ rv = ReaderContextInsert(baseContext);
+ if (rv != SCARD_S_SUCCESS)
+ goto xit;
+
+ rv = EHSpawnEventHandler(baseContext);
+ if (rv != SCARD_S_SUCCESS)
+ goto xit;
+
+ slotCount = ReaderSlotCount(baseContext);
+ if (slotCount <= 1)
+ return SCARD_S_SUCCESS;
+
+ /*
+ * Check the number of slots and create a different
+ * structure for each one accordingly
+ */
+
+ BOOL baseIsThreadSafe = ReaderDriverIsThreadSafe(baseContext, 1);
+
+ for (slot = 1; slot < slotCount; slot++)
+ {
+ // Make sure we have an empty slot to put the reader structure
+ // If not, we remove the whole reader
+ rv = ReaderContextInsert(NULL);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ rv = RFRemoveReader(lpcReader, dwPort);
+ return rv;
+ }
+
+ // Allocate a temporary reader context struct
+ PREADER_CONTEXT ctxSlot = (PREADER_CONTEXT) calloc(1, sizeof(READER_CONTEXT));
+
+ rv = ReaderContextConstructor(ctxSlot, lpcReader, dwPort, lpcLibrary, lpcDevice);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ ReaderContextDestructor(ctxSlot);
+ free(ctxSlot);
+ return rv;
+ }
+
+ ReaderContextDuplicateSlot(baseContext, ctxSlot, slot, baseIsThreadSafe);
+
+ rv = RFInitializeReader(ctxSlot);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log2(PCSC_LOG_ERROR, "%s init failed.", lpcReader);
+ ReaderContextDestructor(ctxSlot);
+ free(ctxSlot);
+ return rv;
+ }
+
+ rv = ReaderContextInsert(ctxSlot);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = EHSpawnEventHandler(ctxSlot);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+ EHSpawnEventHandler(ctxSlot);
+ }
+
+xit:
+ if (rv != SCARD_S_SUCCESS)
+ {
+ // Cannot connect to reader, so exit gracefully
+ Log3(PCSC_LOG_ERROR, "RFAddReader: %s init failed: %d", lpcReader, rv);
+ ReaderContextDestructor(baseContext);
+ free(baseContext);
+ }
+
+ return rv;
+}
+
+LONG RFRemoveReader(LPSTR lpcReader, DWORD dwPort)
+{
+ LONG rv;
+ PREADER_CONTEXT tmpContext = NULL;
+
+ if (lpcReader == 0)
+ return SCARD_E_INVALID_VALUE;
+
+ secdebug("pcscd", "RFRemoveReader: removing %s", lpcReader);
+ while ((rv = RFReaderInfoNamePort(dwPort, lpcReader, &tmpContext)) == SCARD_S_SUCCESS)
+ {
+ // Try to destroy the thread
+ rv = EHDestroyEventHandler(tmpContext);
+
+ rv = RFUnInitializeReader(tmpContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ ReaderContextRemove(tmpContext);
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFSetReaderName(PREADER_CONTEXT rContext, LPCSTR readerName,
+ LPCSTR libraryName, DWORD dwPort, DWORD dwSlot)
+{
+ LONG parent = -1; /* reader number of the parent of the clone */
+ DWORD valueLength;
+ int currentDigit = -1;
+ int supportedChannels = 0;
+ int usedDigits[PCSCLITE_MAX_READERS_CONTEXTS] = {0,};
+ int i;
+
+ if ((0 == dwSlot) && (dwNumReadersContexts != 0))
+ {
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if (sReadersContexts[i] == NULL)
+ continue;
+ if ((sReadersContexts[i])->vHandle != 0)
+ {
+ if (strcmp((sReadersContexts[i])->lpcLibrary, libraryName) == 0)
+ {
+ UCHAR tagValue[1];
+ LONG ret;
+
+ /*
+ * Ask the driver if it supports multiple channels
+ */
+ valueLength = sizeof(tagValue);
+ ret = IFDGetCapabilities((sReadersContexts[i]),
+ TAG_IFD_SIMULTANEOUS_ACCESS,
+ &valueLength, tagValue);
+
+ if ((ret == IFD_SUCCESS) && (valueLength == 1) &&
+ (tagValue[0] > 1))
+ {
+ supportedChannels = tagValue[0];
+ Log2(PCSC_LOG_INFO,
+ "Support %d simultaneous readers", tagValue[0]);
+ }
+ else
+ supportedChannels = 1;
+
+ /*
+ * Check to see if it is a hotplug reader and
+ * different
+ */
+ if (((((sReadersContexts[i])->dwPort & 0xFFFF0000) ==
+ PCSCLITE_HP_BASE_PORT)
+ && ((sReadersContexts[i])->dwPort != dwPort))
+ || (supportedChannels > 1))
+ {
+ char *lpcReader = sReadersContexts[i]->lpcReader;
+
+ /*
+ * tells the caller who the parent of this
+ * clone is so it can use it's shared
+ * resources like mutex/etc.
+ */
+ parent = i;
+
+ /*
+ * If the same reader already exists and it is
+ * hotplug then we must look for others and
+ * enumerate the readername
+ */
+ currentDigit = strtol(lpcReader + strlen(lpcReader) - 5, NULL, 16);
+
+ /*
+ * This spot is taken
+ */
+ usedDigits[currentDigit] = 1;
+ }
+ }
+ }
+ }
+
+ }
+
+ /* default value */
+ i = 0;
+
+ /* Other identical readers exist on the same bus */
+ if (currentDigit != -1)
+ {
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ /* get the first free digit */
+ if (usedDigits[i] == 0)
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ Log2(PCSC_LOG_ERROR, "Max number of readers reached: %d", PCSCLITE_MAX_READERS_CONTEXTS);
+ return -2;
+ }
+
+ if (i >= supportedChannels)
+ {
+ Log3(PCSC_LOG_ERROR, "Driver %s does not support more than "
+ "%d reader(s). Maybe the driver should support "
+ "TAG_IFD_SIMULTANEOUS_ACCESS", libraryName, supportedChannels);
+ return -2;
+ }
+ }
+
+ sprintf(rContext->lpcReader, "%s %02X %02X", readerName, i, dwSlot);
+
+ /*
+ * Set the slot in 0xDDDDCCCC
+ */
+ rContext->dwSlot = (i << 16) + dwSlot;
+
+ return parent;
+}
+
+LONG RFReaderInfo(LPSTR lpcReader, PREADER_CONTEXT * sReader)
+{
+ int i;
+ LONG rv = SCARD_E_UNKNOWN_READER;
+
+ if (lpcReader == 0)
+ return SCARD_E_UNKNOWN_READER;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if ((sReadersContexts[i]!=NULL) && ((sReadersContexts[i])->vHandle != 0))
+ {
+ if (strcmp(lpcReader, (sReadersContexts[i])->lpcReader) == 0)
+ {
+ *sReader = sReadersContexts[i];
+ rv = SCARD_S_SUCCESS;
+ break;
+ }
+ }
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ return rv;
+}
+
+LONG RFReaderInfoNamePort(DWORD dwPort, LPSTR lpcReader,
+ PREADER_CONTEXT * sReader)
+{
+ int ix;
+ LONG rv = SCARD_E_INVALID_VALUE;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (ix = 0; ix < PCSCLITE_MAX_READERS_CONTEXTS; ix++)
+ {
+ if ((sReadersContexts[ix]!=NULL) && ((sReadersContexts[ix])->vHandle != 0) &&
+ ReaderNameMatchForIndex(dwPort, lpcReader, ix))
+ {
+ *sReader = sReadersContexts[ix];
+ rv = SCARD_S_SUCCESS;
+ break;
+ }
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ return rv;
+}
+
+LONG RFReaderInfoById(DWORD dwIdentity, PREADER_CONTEXT * sReader)
+{
+ int i;
+ LONG rv = SCARD_E_INVALID_VALUE;
+
+ /*
+ * Strip off the lower nibble and get the identity
+ */
+ dwIdentity = dwIdentity >> (sizeof(DWORD) / 2) * 8;
+ dwIdentity = dwIdentity << (sizeof(DWORD) / 2) * 8;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if ((sReadersContexts[i]!=NULL) && (dwIdentity == (sReadersContexts[i])->dwIdentity))
+ {
+ *sReader = sReadersContexts[i];
+ rv = SCARD_S_SUCCESS;
+ break;
+ }
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ return rv;
+}
+
+static LONG RFLoadReader(PREADER_CONTEXT rContext)
+{
+ if (rContext->vHandle != 0)
+ {
+ Log1(PCSC_LOG_ERROR, "Warning library pointer not NULL");
+ /*
+ * Another reader exists with this library loaded
+ */
+ return SCARD_S_SUCCESS;
+ }
+
+ return DYN_LoadLibrary(&rContext->vHandle, rContext->lpcLibrary);
+}
+
+LONG RFBindFunctions(PREADER_CONTEXT rContext)
+{
+ int rv1, rv2, rv3;
+ void *f;
+
+ /*
+ * Use this function as a dummy to determine the IFD Handler version
+ * type 1.0/2.0/3.0. Suppress error messaging since it can't be 1.0,
+ * 2.0 and 3.0.
+ */
+
+ Log1(PCSC_LOG_INFO, "Binding driver functions");
+
+// DebugLogSuppress(DEBUGLOG_IGNORE_ENTRIES);
+
+ rv1 = DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
+ rv2 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannel");
+ rv3 = DYN_GetAddress(rContext->vHandle, &f, "IFDHCreateChannelByName");
+
+// DebugLogSuppress(DEBUGLOG_LOG_ENTRIES);
+
+ if (rv1 != SCARD_S_SUCCESS && rv2 != SCARD_S_SUCCESS && rv3 != SCARD_S_SUCCESS)
+ {
+ /*
+ * Neither version of the IFD Handler was found - exit
+ */
+ Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
+
+ exit(1);
+ } else if (rv1 == SCARD_S_SUCCESS)
+ {
+ /*
+ * Ifd Handler 1.0 found
+ */
+ rContext->dwVersion = IFD_HVERSION_1_0;
+ } else if (rv3 == SCARD_S_SUCCESS)
+ {
+ /*
+ * Ifd Handler 3.0 found
+ */
+ rContext->dwVersion = IFD_HVERSION_3_0;
+ }
+ else
+ {
+ /*
+ * Ifd Handler 2.0 found
+ */
+ rContext->dwVersion = IFD_HVERSION_2_0;
+ }
+
+ /*
+ * The following binds version 1.0 of the IFD Handler specs
+ */
+
+ if (rContext->dwVersion == IFD_HVERSION_1_0)
+ {
+ Log1(PCSC_LOG_INFO, "Loading IFD Handler 1.0");
+
+#define GET_ADDRESS_OPTIONALv1(field, function, code) \
+{ \
+ void *f1 = NULL; \
+ if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFD_" #function)) \
+ { \
+ code \
+ } \
+ rContext->psFunctions.psFunctions_v1.pvf ## field = f1; \
+}
+
+#define GET_ADDRESSv1(field, function) \
+ GET_ADDRESS_OPTIONALv1(field, function, \
+ Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #function ); \
+ exit(1); )
+
+ DYN_GetAddress(rContext->vHandle, &f, "IO_Create_Channel");
+ rContext->psFunctions.psFunctions_v1.pvfCreateChannel = f;
+
+ if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f,
+ "IO_Close_Channel"))
+ {
+ Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing");
+ exit(1);
+ }
+ rContext->psFunctions.psFunctions_v1.pvfCloseChannel = f;
+
+ GET_ADDRESSv1(GetCapabilities, Get_Capabilities)
+ GET_ADDRESSv1(SetCapabilities, Set_Capabilities)
+ GET_ADDRESSv1(PowerICC, Power_ICC)
+ GET_ADDRESSv1(TransmitToICC, Transmit_to_ICC)
+ GET_ADDRESSv1(ICCPresence, Is_ICC_Present)
+
+ GET_ADDRESS_OPTIONALv1(SetProtocolParameters, Set_Protocol_Parameters, )
+ }
+ else if (rContext->dwVersion == IFD_HVERSION_2_0)
+ {
+ /*
+ * The following binds version 2.0 of the IFD Handler specs
+ */
+
+#define GET_ADDRESS_OPTIONALv2(s, code) \
+{ \
+ void *f1 = NULL; \
+ if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) \
+ { \
+ code \
+ } \
+ rContext->psFunctions.psFunctions_v2.pvf ## s = f1; \
+}
+
+#define GET_ADDRESSv2(s) \
+ GET_ADDRESS_OPTIONALv2(s, \
+ Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
+ exit(1); )
+
+ Log1(PCSC_LOG_INFO, "Loading IFD Handler 2.0");
+
+ GET_ADDRESSv2(CreateChannel)
+ GET_ADDRESSv2(CloseChannel)
+ GET_ADDRESSv2(GetCapabilities)
+ GET_ADDRESSv2(SetCapabilities)
+ GET_ADDRESSv2(PowerICC)
+ GET_ADDRESSv2(TransmitToICC)
+ GET_ADDRESSv2(ICCPresence)
+ GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
+
+ GET_ADDRESSv2(Control)
+ }
+ else if (rContext->dwVersion == IFD_HVERSION_3_0)
+ {
+ /*
+ * The following binds version 3.0 of the IFD Handler specs
+ */
+
+#define GET_ADDRESS_OPTIONALv3(s, code) \
+{ \
+ void *f1 = NULL; \
+ if (SCARD_S_SUCCESS != DYN_GetAddress(rContext->vHandle, &f1, "IFDH" #s)) \
+ { \
+ code \
+ } \
+ rContext->psFunctions.psFunctions_v3.pvf ## s = f1; \
+}
+
+#define GET_ADDRESSv3(s) \
+ GET_ADDRESS_OPTIONALv3(s, \
+ Log1(PCSC_LOG_CRITICAL, "IFDHandler functions missing: " #s ); \
+ exit(1); )
+
+ Log1(PCSC_LOG_INFO, "Loading IFD Handler 3.0");
+
+ GET_ADDRESSv2(CreateChannel)
+ GET_ADDRESSv2(CloseChannel)
+ GET_ADDRESSv2(GetCapabilities)
+ GET_ADDRESSv2(SetCapabilities)
+ GET_ADDRESSv2(PowerICC)
+ GET_ADDRESSv2(TransmitToICC)
+ GET_ADDRESSv2(ICCPresence)
+ GET_ADDRESS_OPTIONALv2(SetProtocolParameters, )
+
+ GET_ADDRESSv3(CreateChannelByName)
+ GET_ADDRESSv3(Control)
+ }
+ else
+ {
+ /*
+ * Who knows what could have happenned for it to get here.
+ */
+ Log1(PCSC_LOG_CRITICAL, "IFD Handler not 1.0/2.0 or 3.0");
+ exit(1);
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+static LONG RFUnBindFunctions(PREADER_CONTEXT rContext)
+{
+ /*
+ * Zero out everything
+ */
+
+ Log1(PCSC_LOG_INFO, "Unbinding driver functions");
+ memset(&rContext->psFunctions, 0, sizeof(rContext->psFunctions));
+
+ return SCARD_S_SUCCESS;
+}
+
+static LONG RFUnloadReader(PREADER_CONTEXT rContext)
+{
+ /*
+ * Make sure no one else is using this library
+ */
+
+ Log1(PCSC_LOG_INFO, "Unloading reader driver.");
+ if (*rContext->pdwFeeds == 1)
+ {
+ Log1(PCSC_LOG_INFO, "--- closing dynamic library");
+ DYN_CloseLibrary(&rContext->vHandle);
+ }
+
+ rContext->vHandle = 0;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFCheckSharing(DWORD hCard)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ if (rContext->dwLockId == 0 || rContext->dwLockId == hCard)
+ return SCARD_S_SUCCESS;
+ else
+ {
+ secdebug("pcscd", "RFCheckSharing: sharing violation, dwLockId: 0x%02X", rContext->dwLockId);
+ return SCARD_E_SHARING_VIOLATION;
+ }
+}
+
+LONG RFLockSharing(DWORD hCard)
+{
+ PREADER_CONTEXT rContext = NULL;
+
+ RFReaderInfoById(hCard, &rContext);
+
+ if (RFCheckSharing(hCard) == SCARD_S_SUCCESS)
+ {
+ EHSetSharingEvent(rContext, 1);
+ rContext->dwLockId = hCard;
+ }
+ else
+ return SCARD_E_SHARING_VIOLATION;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFUnlockSharing(DWORD hCard)
+{
+ PREADER_CONTEXT rContext = NULL;
+ LONG rv;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFCheckSharing(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ EHSetSharingEvent(rContext, 0);
+ rContext->dwLockId = 0;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFUnblockContext(SCARDCONTEXT hContext)
+{
+ int i;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ if (sReadersContexts[i])
+ (sReadersContexts[i])->dwBlockStatus = hContext;
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFUnblockReader(PREADER_CONTEXT rContext)
+{
+ rContext->dwBlockStatus = BLOCK_STATUS_RESUME;
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFInitializeReader(PREADER_CONTEXT rContext)
+{
+ LONG rv;
+
+ /*
+ * Spawn the event handler thread
+ */
+ Log3(PCSC_LOG_INFO, "Attempting startup of %s using %s",
+ rContext->lpcReader, rContext->lpcLibrary);
+
+ /******************************************/
+ /*
+ * This section loads the library
+ */
+ /******************************************/
+ rv = RFLoadReader(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log2(PCSC_LOG_ERROR, "RFLoadReader failed: %X", rv);
+ return rv;
+ }
+
+ /*******************************************/
+ /*
+ * This section binds the functions
+ */
+ /*******************************************/
+ rv = RFBindFunctions(rContext);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log2(PCSC_LOG_ERROR, "RFBindFunctions failed: %X", rv);
+ RFUnloadReader(rContext);
+ return rv;
+ }
+
+ /*******************************************/
+ /*
+ * This section tries to open the port
+ */
+ /*******************************************/
+
+ rv = IFDOpenIFD(rContext);
+
+ if (rv != IFD_SUCCESS)
+ {
+ Log3(PCSC_LOG_CRITICAL, "Open Port %X Failed (%s)",
+ rContext->dwPort, rContext->lpcDevice);
+ RFUnBindFunctions(rContext);
+ RFUnloadReader(rContext);
+ return SCARD_E_INVALID_TARGET;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFUnInitializeReader(PREADER_CONTEXT rContext)
+{
+ Log2(PCSC_LOG_INFO, "Attempting shutdown of %s.",
+ rContext->lpcReader);
+
+ /*
+ * Close the port, unbind the functions, and unload the library
+ */
+
+ /*
+ * If the reader is getting uninitialized then it is being unplugged
+ * so I can't send a IFDPowerICC call to it
+ *
+ * IFDPowerICC( rContext, IFD_POWER_DOWN, Atr, &AtrLen );
+ */
+ IFDCloseIFD(rContext);
+ RFUnBindFunctions(rContext);
+ RFUnloadReader(rContext);
+
+ return SCARD_S_SUCCESS;
+}
+
+SCARDHANDLE RFCreateReaderHandle(PREADER_CONTEXT rContext)
+{
+ USHORT randHandle;
+
+ /*
+ * Create a random handle with 16 bits check to see if it already is
+ * used.
+ */
+ randHandle = SYS_Random(SYS_GetSeed(), 10, 65000);
+
+ while (1)
+ {
+ int i;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if ((sReadersContexts[i]!=NULL) && ((sReadersContexts[i])->vHandle != 0))
+ {
+ int j;
+
+ for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
+ {
+ if ((rContext->dwIdentity + randHandle) ==
+ (sReadersContexts[i])->psHandles[j].hCard)
+ {
+ /*
+ * Get a new handle and loop again
+ */
+ randHandle = SYS_Random(randHandle, 10, 65000);
+ continue;
+ }
+ }
+ }
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ /*
+ * Once the for loop is completed w/o restart a good handle was
+ * found and the loop can be exited.
+ */
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ break;
+ }
+
+ return rContext->dwIdentity + randHandle;
+}
+
+LONG RFFindReaderHandle(SCARDHANDLE hCard)
+{
+ int i;
+ LONG rv = SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if ((sReadersContexts[i]!=NULL) && ((sReadersContexts[i])->vHandle != 0))
+ {
+ int j;
+
+ for (j = 0; j < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; j++)
+ {
+ if (hCard == (sReadersContexts[i])->psHandles[j].hCard)
+ {
+ rv = SCARD_S_SUCCESS;
+ goto xit;
+ }
+ }
+ }
+ }
+xit:
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ return rv;
+}
+
+LONG RFDestroyReaderHandle(SCARDHANDLE hCard)
+{
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFAddReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
+ {
+ if (rContext->psHandles[i].hCard == 0)
+ {
+ rContext->psHandles[i].hCard = hCard;
+ rContext->psHandles[i].dwEventStatus = 0;
+ break;
+ }
+ }
+
+ if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
+ /* List is full */
+ return SCARD_E_INSUFFICIENT_BUFFER;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFRemoveReaderHandle(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
+ {
+ if (rContext->psHandles[i].hCard == hCard)
+ {
+ rContext->psHandles[i].hCard = 0;
+ rContext->psHandles[i].dwEventStatus = 0;
+ break;
+ }
+ }
+
+ if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
+ /* Not Found */
+ return SCARD_E_INVALID_HANDLE;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFSetReaderEventState(PREADER_CONTEXT rContext, DWORD dwEvent)
+{
+ int i;
+
+ /*
+ * Set all the handles for that reader to the event
+ */
+ for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
+ {
+ if (rContext->psHandles[i].hCard != 0)
+ rContext->psHandles[i].dwEventStatus = dwEvent;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFCheckReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
+ {
+ if (rContext->psHandles[i].hCard == hCard)
+ {
+ if (rContext->psHandles[i].dwEventStatus == SCARD_REMOVED)
+ return SCARD_W_REMOVED_CARD;
+ else
+ {
+ if (rContext->psHandles[i].dwEventStatus == SCARD_RESET)
+ return SCARD_W_RESET_CARD;
+ else
+ {
+ if (rContext->psHandles[i].dwEventStatus == 0)
+ return SCARD_S_SUCCESS;
+ else
+ return SCARD_E_INVALID_VALUE;
+ }
+ }
+ }
+ }
+
+ return SCARD_E_INVALID_HANDLE;
+}
+
+LONG RFClearReaderEventState(PREADER_CONTEXT rContext, SCARDHANDLE hCard)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; i++)
+ {
+ if (rContext->psHandles[i].hCard == hCard)
+ rContext->psHandles[i].dwEventStatus = 0;
+ }
+
+ if (i == PCSCLITE_MAX_READER_CONTEXT_CHANNELS)
+ /* Not Found */
+ return SCARD_E_INVALID_HANDLE;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG RFCheckReaderStatus(PREADER_CONTEXT rContext)
+{
+ LONG rx = 0;
+ rx = ((rContext == NULL) || (rContext->readerState == NULL) ||
+ (SharedReaderState_State(rContext->readerState) & SCARD_UNKNOWN))?SCARD_E_READER_UNAVAILABLE:SCARD_S_SUCCESS;
+ return rx;
+}
+
+void RFCleanupReaders(int shouldExit)
+{
+ int i;
+
+ Log1(PCSC_LOG_INFO, "entering cleaning function");
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if ((sReadersContexts[i]!=NULL) && (sReadersContexts[i]->vHandle != 0))
+ {
+ LONG rv;
+ char lpcStripReader[MAX_READERNAME];
+
+ Log2(PCSC_LOG_INFO, "Stopping reader: %s",
+ sReadersContexts[i]->lpcReader);
+
+ strncpy(lpcStripReader, (sReadersContexts[i])->lpcReader,
+ sizeof(lpcStripReader));
+ /*
+ * strip the 6 last char ' 00 00'
+ */
+ lpcStripReader[strlen(lpcStripReader) - 6] = '\0';
+
+ rv = RFRemoveReader(lpcStripReader, sReadersContexts[i]->dwPort);
+
+ if (rv != SCARD_S_SUCCESS)
+ Log2(PCSC_LOG_ERROR, "RFRemoveReader error: 0x%08X", rv);
+ }
+ }
+
+ secdebug("pcscd", "RFCleanupReaders: exiting cleaning function");
+ /*
+ * exit() will call at_exit()
+ */
+
+ if (shouldExit)
+ exit(0);
+}
+
+int RFStartSerialReaders(const char *readerconf)
+{
+ return DBUpdateReaders(readerconf);
+}
+
+void RFReCheckReaderConf(void)
+{
+}
+
+void RFSuspendAllReaders()
+{
+ int ix;
+ secdebug("pcscd", "RFSuspendAllReaders");
+ Log1(PCSC_LOG_DEBUG, "zzzzz zzzzz zzzzz zzzzz RFSuspendAllReaders zzzzz zzzzz zzzzz zzzzz ");
+
+ // @@@ We still need code to mark state first as "trying to sleep", in case
+ // not all of it gets done before we sleep
+ for (ix = 0; ix < PCSCLITE_MAX_READERS_CONTEXTS; ix++)
+ {
+ if ((sReadersContexts[ix]!=NULL) && ((sReadersContexts[ix])->vHandle != 0))
+ {
+ EHDestroyEventHandler(sReadersContexts[ix]);
+ IFDCloseIFD(sReadersContexts[ix]);
+ }
+ }
+}
+
+void RFAwakeAllReaders(void)
+{
+ LONG rv = IFD_SUCCESS;
+ int i;
+
+ secdebug("pcscd", "RFAwakeAllReaders");
+ Log1(PCSC_LOG_DEBUG, "----- ----- ----- ----- RFAwakeAllReaders ----- ----- ----- ----- ");
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if (sReadersContexts[i]==NULL)
+ continue;
+ /* If the library is loaded and the event handler is not running */
+ if ( ((sReadersContexts[i])->vHandle != 0) &&
+ ((sReadersContexts[i])->pthThread == 0) )
+ {
+ int jx;
+ int alreadyInitializedFlag = 0;
+
+ // If a clone of this already did the initialization,
+ // set flag so we don't do again
+ for (jx=0; jx < i; jx++)
+ {
+ if (((sReadersContexts[jx])->vHandle == (sReadersContexts[i])->vHandle)&&
+ ((sReadersContexts[jx])->dwPort == (sReadersContexts[i])->dwPort))
+ {
+ alreadyInitializedFlag = 1;
+ }
+ }
+
+ if (!alreadyInitializedFlag)
+ {
+ SYS_USleep(100000L); // 0.1s (in microseconds)
+ rv = IFDOpenIFD(sReadersContexts[i]);
+ }
+
+ RFSetReaderEventState(sReadersContexts[i], SCARD_RESET);
+ if (rv != IFD_SUCCESS)
+ {
+ Log3(PCSC_LOG_ERROR, "Open Port %X Failed (%s)",
+ (sReadersContexts[i])->dwPort, (sReadersContexts[i])->lpcDevice);
+ Log2(PCSC_LOG_ERROR, " with error 0x%08X", rv);
+ continue;
+ }
+
+ EHSpawnEventHandler(sReadersContexts[i]);
+ }
+ }
+}
+
+#pragma mark ---------- Context Share Lock Tracking ----------
+
+void ReaderContextLock(PREADER_CONTEXT rContext)
+{
+ if (rContext)
+ {
+ secdebug("pcscd", "===> ReaderContextLock [was: %02X]", rContext->dwLockId);
+ rContext->dwLockId = 0xFFFF;
+ lastLockID = -3; // something different
+ }
+}
+
+void ReaderContextUnlock(PREADER_CONTEXT rContext)
+{
+ if (rContext)
+ {
+ secdebug("pcscd", "<=== ReaderContextUnlock [was: %02X]", rContext->dwLockId);
+ rContext->dwLockId = 0;
+ lastLockID = -2; // something different
+ }
+}
+
+int ReaderContextIsLocked(PREADER_CONTEXT rContext)
+{
+ if (rContext)
+ {
+ if (rContext->dwLockId && (rContext->dwLockId != lastLockID)) // otherwise too many messages
+ {
+ lastLockID = rContext->dwLockId;
+ secdebug("pcscd", ".... ReaderContextLock state: %02X", rContext->dwLockId);
+ }
+ return (rContext->dwLockId == 0xFFFF)?1:0;
+ }
+ else
+ return 0;
+}
+
+#pragma mark ---------- Reader Context Management ----------
+
+static int ReaderContextConstructor(PREADER_CONTEXT ctx, LPCSTR lpcReader,
+ DWORD dwPort, LPCSTR lpcLibrary, LPCSTR lpcDevice)
+{
+ // We assume the struct was created with a calloc, so we don't call ReaderContextClear
+ if (!ctx)
+ return SCARD_E_NO_MEMORY;
+
+ strlcpy(ctx->lpcLibrary, lpcLibrary, sizeof(ctx->lpcLibrary));
+ strlcpy(ctx->lpcDevice, lpcDevice, sizeof(ctx->lpcDevice));
+ ctx->dwPort = dwPort;
+
+ /*
+ Initialize pdwFeeds to 1, otherwise multiple cloned readers will cause
+ pcscd to crash when RFUnloadReader unloads the driver library
+ and there are still devices attached using it
+ */
+ ctx->pdwFeeds = malloc(sizeof(DWORD));
+ *ctx->pdwFeeds = 1;
+
+ ctx->mMutex = (PCSCLITE_MUTEX_T) malloc(sizeof(PCSCLITE_MUTEX));
+ SYS_MutexInit(ctx->mMutex);
+
+ ctx->pdwMutex = malloc(sizeof(DWORD));
+ *ctx->pdwMutex = 1;
+
+ return SCARD_S_SUCCESS;
+}
+
+static int ReaderCheckForClone(PREADER_CONTEXT ctx, LPCSTR lpcReader,
+ DWORD dwPort, LPCSTR lpcLibrary)
+{
+ // Check and set the readername to see if it must be enumerated
+ // A parentNode of -2 or less indicates fatal error
+
+ LONG parentNode = RFSetReaderName(ctx, lpcReader, lpcLibrary, dwPort, 0);
+ if (parentNode < -1)
+ return SCARD_E_NO_MEMORY;
+
+ // If a clone to this reader exists take some values from that clone
+ if ((parentNode >= 0) && (parentNode < PCSCLITE_MAX_READERS_CONTEXTS)
+ && sReadersContexts[parentNode])
+ {
+ SYS_MutexLock(sReadersContextsLock);
+ ctx->pdwFeeds = (sReadersContexts[parentNode])->pdwFeeds;
+ *ctx->pdwFeeds += 1;
+ ctx->vHandle = (sReadersContexts[parentNode])->vHandle;
+ ctx->mMutex = (sReadersContexts[parentNode])->mMutex;
+ ctx->pdwMutex = (sReadersContexts[parentNode])->pdwMutex;
+ SYS_MutexUnLock(sReadersContextsLock);
+
+ if (0 && ReaderDriverIsThreadSafe(sReadersContexts[parentNode], 0))
+ {
+ ctx->mMutex = 0;
+ ctx->pdwMutex = NULL;
+ }
+ else
+ *ctx->pdwMutex += 1;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+static void ReaderContextDestructor(PREADER_CONTEXT ctx)
+{
+ ReaderContextFree(ctx);
+}
+
+static void ReaderContextFree(PREADER_CONTEXT ctx)
+{
+ if (!ctx)
+ return;
+
+ // Destroy and free the mutex
+ if (ctx->pdwMutex)
+ {
+ if (*ctx->pdwMutex == 1)
+ {
+ SYS_MutexDestroy(ctx->mMutex);
+ free(ctx->mMutex);
+ }
+ *ctx->pdwMutex -= 1;
+ }
+
+ // Destroy and free the mutex counter
+ if (ctx->pdwMutex && (*ctx->pdwMutex == 0))
+ {
+ free(ctx->pdwMutex);
+ ctx->pdwMutex = NULL;
+ }
+
+ if (ctx->pdwFeeds)
+ {
+ *ctx->pdwFeeds -= 1;
+ if (*ctx->pdwFeeds == 0)
+ {
+ free(ctx->pdwFeeds);
+ ctx->pdwFeeds = NULL;
+ }
+ }
+
+ // zero out everything else
+ ReaderContextClear(ctx);
+}
+
+static void ReaderContextClear(PREADER_CONTEXT ctx)
+{
+ // This assumes that ReaderContextFree has already been called if necessary
+ if (ctx)
+ memset(ctx, 0, sizeof(READER_CONTEXT));
+}
+
+static int ReaderContextInsert(PREADER_CONTEXT ctx)
+{
+ // Find an empty slot to put the reader structure, and copy it in
+ // If NULL is passed in, just return whether a spot is available or not
+
+ int ix, rv = SCARD_E_NO_MEMORY;
+
+ SYS_MutexLock(sReadersContextsLock);
+ for (ix = 0; ix < PCSCLITE_MAX_READERS_CONTEXTS; ix++)
+ {
+ if ((sReadersContexts[ix] == NULL) || (sReadersContexts[ix])->vHandle == 0)
+ {
+ if (ctx)
+ {
+ if (sReadersContexts[ix])
+ free(sReadersContexts[ix]);
+ sReadersContexts[ix] = ctx;
+ (sReadersContexts[ix])->dwIdentity = (ix + 1) << (sizeof(DWORD) / 2) * 8;
+ dwNumReadersContexts += 1;
+ }
+ rv = SCARD_S_SUCCESS;
+ break;
+ }
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+ return rv;
+}
+
+static int ReaderContextRemove(PREADER_CONTEXT ctx)
+{
+ int ix, rv = SCARD_E_UNKNOWN_READER;
+ PREADER_CONTEXT ctxToRemove = NULL;
+ DWORD dwPort = ctx->dwPort;
+ LPSTR lpcReader = ctx->lpcReader;
+ SYS_MutexLock(sReadersContextsLock);
+ for (ix = 0; ix < PCSCLITE_MAX_READERS_CONTEXTS; ix++)
+ {
+ if (!ReaderNameMatchForIndex(dwPort, lpcReader, ix))
+ continue;
+
+ ctxToRemove = sReadersContexts[ix];
+ sReadersContexts[ix] = NULL;
+ dwNumReadersContexts -= 1;
+ rv = SCARD_S_SUCCESS;
+ break;
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+ // We can do this cleanup outside the lock
+ if (ctxToRemove)
+ {
+ ReaderContextDestructor(ctxToRemove);
+ free(ctxToRemove);
+ }
+ return rv;
+}
+
+static int ReaderContextCheckDuplicateReader(LPCSTR lpcReader, DWORD dwPort)
+{
+ // Readers with the same name and same port cannot be used
+
+ if (dwNumReadersContexts == 0)
+ return SCARD_S_SUCCESS;
+
+ int ix, rv = SCARD_S_SUCCESS;
+ SYS_MutexLock(sReadersContextsLock);
+ for (ix = 0; ix < PCSCLITE_MAX_READERS_CONTEXTS; ix++)
+ {
+ if ((sReadersContexts[ix]==NULL) || ((sReadersContexts[ix])->vHandle == 0))
+ continue;
+
+ if (ReaderNameMatchForIndex(dwPort, lpcReader, ix))
+ {
+ Log1(PCSC_LOG_ERROR, "Duplicate reader found.");
+ rv = SCARD_E_DUPLICATE_READER;
+ break;
+ }
+ }
+ SYS_MutexUnLock(sReadersContextsLock);
+ return rv;
+}
+
+static int ReaderSlotCount(PREADER_CONTEXT ctx)
+{
+ // Call on the driver to see if there are multiple slots
+ // If we encounter errors, pretend it is just a single slot reader
+
+ UCHAR ucGetData[1];
+ DWORD dwGetSize = sizeof(ucGetData);
+ int rv = IFDGetCapabilities(ctx, TAG_IFD_SLOTS_NUMBER, &dwGetSize, ucGetData);
+
+ //Reader does not have this defined, so assume a single slot
+ if (rv != IFD_SUCCESS || dwGetSize != 1 || ucGetData[0] == 0)
+ return 1;
+
+ // Reader has this defined and it only has one slot
+ if (rv == IFD_SUCCESS && dwGetSize == 1 && ucGetData[0] == 1)
+ return 1;
+
+ return (int)ucGetData[0];
+}
+
+static BOOL ReaderDriverIsThreadSafe(PREADER_CONTEXT ctx, BOOL testSlot)
+{
+ // Call on the driver to see if it is thread safe
+ UCHAR ucThread[1];
+ DWORD dwGetSize = sizeof(ucThread);
+ int rv = IFDGetCapabilities(ctx, testSlot?TAG_IFD_SLOT_THREAD_SAFE:TAG_IFD_THREAD_SAFE,
+ &dwGetSize, ucThread);
+ if (rv == IFD_SUCCESS && dwGetSize == 1 && ucThread[0] == 1)
+ {
+ Log1(PCSC_LOG_INFO, "Driver is thread safe");
+ return 1;
+ }
+ else
+ {
+ Log1(PCSC_LOG_INFO, "Driver is not thread safe");
+ return 0;
+ }
+}
+
+static BOOL ReaderNameMatchForIndex(DWORD dwPort, LPCSTR lpcReader, int index)
+{
+ // "index" is index in sReadersContexts
+ char lpcStripReader[MAX_READERNAME];
+ int tmplen;
+
+ if (sReadersContexts[index]==NULL)
+ return 0;
+
+ strncpy(lpcStripReader, (sReadersContexts[index])->lpcReader, sizeof(lpcStripReader));
+ tmplen = strlen(lpcStripReader);
+ lpcStripReader[tmplen - 6] = 0;
+
+ return ((strcmp(lpcReader, lpcStripReader) == 0) && (dwPort == (sReadersContexts[index])->dwPort))?1:0;
+}
+
+static void ReaderContextDuplicateSlot(PREADER_CONTEXT ctxBase, PREADER_CONTEXT ctxSlot, int slotNumber, BOOL baseIsThreadSafe)
+{
+ // Copy the previous reader name and set the slot number
+ // The slot number for the base is 0
+
+ int ix;
+ char *tmpReader = ctxSlot->lpcReader;
+ strlcpy(tmpReader, ctxBase->lpcReader, sizeof(ctxSlot->lpcReader));
+ sprintf(tmpReader + strlen(tmpReader) - 2, "%02X", slotNumber);
+
+ strlcpy(ctxSlot->lpcLibrary, ctxBase->lpcLibrary, sizeof(ctxSlot->lpcLibrary));
+ strlcpy(ctxSlot->lpcDevice, ctxBase->lpcDevice, sizeof(ctxSlot->lpcDevice));
+
+ ctxSlot->dwVersion = ctxBase->dwVersion;
+ ctxSlot->dwPort = ctxBase->dwPort;
+ ctxSlot->vHandle = ctxBase->vHandle;
+ ctxSlot->mMutex = ctxBase->mMutex;
+ ctxSlot->pdwMutex = ctxBase->pdwMutex;
+ ctxSlot->dwSlot = ctxBase->dwSlot + slotNumber;
+
+ ctxSlot->pdwFeeds = ctxBase->pdwFeeds;
+
+ *ctxSlot->pdwFeeds += 1;
+
+ ctxSlot->dwBlockStatus = 0;
+ ctxSlot->dwContexts = 0;
+ ctxSlot->dwLockId = 0;
+ ctxSlot->readerState = NULL;
+ ctxSlot->dwIdentity = (slotNumber + 1) << (sizeof(DWORD) / 2) * 8;
+
+ for (ix = 0; ix < PCSCLITE_MAX_READER_CONTEXT_CHANNELS; ix++)
+ ctxSlot->psHandles[ix].hCard = 0;
+
+ if (!ctxSlot->pdwMutex)
+ ctxSlot->pdwMutex = malloc(sizeof(DWORD));
+ if (baseIsThreadSafe)
+ {
+ ctxSlot->mMutex = malloc(sizeof(PCSCLITE_MUTEX));
+ SYS_MutexInit(ctxSlot->mMutex);
+ *ctxSlot->pdwMutex = 1;
+ }
+ else
+ *ctxSlot->pdwMutex += 1;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerfactory.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * readerfactory.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ * Copyright (C) 2004
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: readerfactory.h 2330 2007-01-11 16:54:16Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps track of a list of currently available reader structures.
+ */
+
+#ifndef __readerfactory_h__
+#define __readerfactory_h__
+
+#include <inttypes.h>
+
+#include "thread_generic.h"
+#include "ifdhandler.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct
+ {
+ char *pcFriendlyname;
+ char *pcDevicename;
+ char *pcLibpath;
+ int dwChannelId;
+ } SerialReader;
+
+ struct FctMap_V1
+ {
+ RESPONSECODE (*pvfCreateChannel)(DWORD);
+ RESPONSECODE (*pvfCloseChannel)(void);
+ RESPONSECODE (*pvfGetCapabilities)(DWORD, PUCHAR);
+ RESPONSECODE (*pvfSetCapabilities)(DWORD, PUCHAR);
+ RESPONSECODE (*pvfSetProtocolParameters)(DWORD, UCHAR, UCHAR, UCHAR,
+ UCHAR);
+ RESPONSECODE (*pvfPowerICC)(DWORD);
+ RESPONSECODE (*pvfTransmitToICC)(SCARD_IO_HEADER, PUCHAR, DWORD,
+ PUCHAR, PDWORD, PSCARD_IO_HEADER);
+ RESPONSECODE (*pvfICCPresence)(void);
+ };
+
+ typedef struct FctMap_V1 FCT_MAP_V1, *PFCT_MAP_V1;
+
+ struct FctMap_V2
+ {
+ /* shared with API 3.0 */
+ RESPONSECODE (*pvfCreateChannel)(DWORD, DWORD);
+ RESPONSECODE (*pvfCloseChannel)(DWORD);
+ RESPONSECODE (*pvfGetCapabilities)(DWORD, DWORD, PDWORD, PUCHAR);
+ RESPONSECODE (*pvfSetCapabilities)(DWORD, DWORD, DWORD, PUCHAR);
+ RESPONSECODE (*pvfSetProtocolParameters)(DWORD, DWORD, UCHAR, UCHAR,
+ UCHAR, UCHAR);
+ RESPONSECODE (*pvfPowerICC)(DWORD, DWORD, PUCHAR, PDWORD);
+ RESPONSECODE (*pvfTransmitToICC)(DWORD, SCARD_IO_HEADER, PUCHAR,
+ DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER);
+ RESPONSECODE (*pvfICCPresence)(DWORD);
+
+ /* API v2.0 only */
+ RESPONSECODE (*pvfControl)(DWORD, PUCHAR, DWORD, PUCHAR, PDWORD);
+ };
+
+ typedef struct FctMap_V2 FCT_MAP_V2, *PFCT_MAP_V2;
+
+ struct FctMap_V3
+ {
+ /* the common fields SHALL be in the same order as in FctMap_V2 */
+ RESPONSECODE (*pvfCreateChannel)(DWORD, DWORD);
+ RESPONSECODE (*pvfCloseChannel)(DWORD);
+ RESPONSECODE (*pvfGetCapabilities)(DWORD, DWORD, PDWORD, PUCHAR);
+ RESPONSECODE (*pvfSetCapabilities)(DWORD, DWORD, DWORD, PUCHAR);
+ RESPONSECODE (*pvfSetProtocolParameters)(DWORD, DWORD, UCHAR, UCHAR,
+ UCHAR, UCHAR);
+ RESPONSECODE (*pvfPowerICC)(DWORD, DWORD, PUCHAR, PDWORD);
+ RESPONSECODE (*pvfTransmitToICC)(DWORD, SCARD_IO_HEADER, PUCHAR,
+ DWORD, PUCHAR, PDWORD, PSCARD_IO_HEADER);
+ RESPONSECODE (*pvfICCPresence)(DWORD);
+
+ /* API V3.0 only */
+ RESPONSECODE (*pvfControl)(DWORD, DWORD, LPCVOID, DWORD, LPVOID,
+ DWORD, LPDWORD);
+ RESPONSECODE (*pvfCreateChannelByName)(DWORD, LPSTR);
+ };
+
+ typedef struct FctMap_V3 FCT_MAP_V3, *PFCT_MAP_V3;
+
+ /*
+ * The following is not currently used but in place if needed
+ */
+
+ struct RdrCapabilities
+ {
+ DWORD dwAsynch_Supported; /* Asynchronous Support */
+ DWORD dwDefault_Clock; /* Default Clock Rate */
+ DWORD dwMax_Clock; /* Max Clock Rate */
+ DWORD dwDefault_Data_Rate; /* Default Data Rate */
+ DWORD dwMax_Data_Rate; /* Max Data Rate */
+ DWORD dwMax_IFSD; /* Maximum IFSD Size */
+ DWORD dwSynch_Supported; /* Synchronous Support */
+ DWORD dwPower_Mgmt; /* Power Mgmt Features */
+ DWORD dwCard_Auth_Devices; /* Card Auth Devices */
+ DWORD dwUser_Auth_Device; /* User Auth Devices */
+ DWORD dwMechanics_Supported; /* Machanics Supported */
+ DWORD dwVendor_Features; /* User Defined. */
+ };
+
+ typedef struct RdrCapabilities RDR_CAPABILITIES, *PRDR_CAPABILITIES;
+
+ struct ProtOptions
+ {
+ DWORD dwProtocol_Type; /* Protocol Type */
+ DWORD dwCurrent_Clock; /* Current Clock */
+ DWORD dwCurrent_F; /* Current F */
+ DWORD dwCurrent_D; /* Current D */
+ DWORD dwCurrent_N; /* Current N */
+ DWORD dwCurrent_W; /* Current W */
+ DWORD dwCurrent_IFSC; /* Current IFSC */
+ DWORD dwCurrent_IFSD; /* Current IFSD */
+ DWORD dwCurrent_BWT; /* Current BWT */
+ DWORD dwCurrent_CWT; /* Current CWT */
+ DWORD dwCurrent_EBC; /* Current EBC */
+ };
+
+ typedef struct ProtOptions PROT_OPTIONS, *PPROT_OPTIONS;
+
+ struct RdrCliHandles
+ {
+ SCARDHANDLE hCard; /* hCard for this connection */
+ DWORD dwEventStatus; /* Recent event that must be sent */
+ };
+
+ typedef struct RdrCliHandles RDR_CLIHANDLES, *PRDR_CLIHANDLES;
+
+ struct ReaderContext
+ {
+ char lpcReader[MAX_READERNAME]; /* Reader Name */
+ char lpcLibrary[MAX_LIBNAME]; /* Library Path */
+ char lpcDevice[MAX_DEVICENAME]; /* Device Name */
+ PCSCLITE_THREAD_T pthThread; /* Event polling thread */
+ PCSCLITE_MUTEX_T mMutex; /* Mutex for this connection */
+ RDR_CLIHANDLES psHandles[PCSCLITE_MAX_READER_CONTEXT_CHANNELS];
+ /* Structure of connected handles */
+ union
+ {
+ FCT_MAP_V1 psFunctions_v1; /* API V1.0 */
+ FCT_MAP_V2 psFunctions_v2; /* API V2.0 */
+ FCT_MAP_V3 psFunctions_v3; /* API V3.0 */
+ } psFunctions;
+
+ LPVOID vHandle; /* Dlopen handle */
+ DWORD dwVersion; /* IFD Handler version number */
+ DWORD dwPort; /* Port ID */
+ DWORD dwSlot; /* Current Reader Slot */
+ DWORD dwBlockStatus; /* Current blocking status */
+ DWORD dwLockId; /* Lock Id */
+ DWORD dwIdentity; /* Shared ID High Nibble */
+ int32_t dwContexts; /* Number of open contexts */
+ PDWORD pdwFeeds; /* Number of shared client to lib */
+ PDWORD pdwMutex; /* Number of client to mutex */
+
+ struct pubReaderStatesList *readerState; /* link to the reader state */
+ /* we can't use PREADER_STATE here since eventhandler.h can't be
+ * included because of circular dependencies */
+
+ /* these structures are unused */
+#if 0
+ RDR_CAPABILITIES psCapabilites; /* Structure of reader
+ capabilities */
+ PROT_OPTIONS psProtOptions; /* Structure of protocol options */
+#endif
+ };
+
+ typedef struct ReaderContext READER_CONTEXT, *PREADER_CONTEXT;
+
+ LONG RFAllocateReaderSpace(void);
+ LONG RFAddReader(LPSTR, DWORD, LPSTR, LPSTR);
+ LONG RFRemoveReader(LPSTR, DWORD);
+ LONG RFSetReaderName(PREADER_CONTEXT, LPCSTR, LPCSTR, DWORD, DWORD);
+ LONG RFListReaders(LPSTR, LPDWORD);
+ LONG RFReaderInfo(LPSTR, struct ReaderContext **);
+ LONG RFReaderInfoNamePort(DWORD, LPSTR, struct ReaderContext **);
+ LONG RFReaderInfoById(DWORD, struct ReaderContext **);
+ LONG RFCheckSharing(DWORD);
+ LONG RFLockSharing(DWORD);
+ LONG RFUnlockSharing(DWORD);
+ LONG RFUnblockReader(PREADER_CONTEXT);
+ LONG RFUnblockContext(SCARDCONTEXT);
+#if 0
+ LONG RFLoadReader(PREADER_CONTEXT);
+ LONG RFBindFunctions(PREADER_CONTEXT);
+ LONG RFUnBindFunctions(PREADER_CONTEXT);
+ LONG RFUnloadReader(PREADER_CONTEXT);
+#endif
+ LONG RFInitializeReader(PREADER_CONTEXT);
+ LONG RFUnInitializeReader(PREADER_CONTEXT);
+ SCARDHANDLE RFCreateReaderHandle(PREADER_CONTEXT);
+ LONG RFDestroyReaderHandle(SCARDHANDLE hCard);
+ LONG RFAddReaderHandle(PREADER_CONTEXT, SCARDHANDLE);
+ LONG RFFindReaderHandle(SCARDHANDLE);
+ LONG RFRemoveReaderHandle(PREADER_CONTEXT, SCARDHANDLE);
+ LONG RFSetReaderEventState(PREADER_CONTEXT, DWORD);
+ LONG RFCheckReaderEventState(PREADER_CONTEXT, SCARDHANDLE);
+ LONG RFClearReaderEventState(PREADER_CONTEXT, SCARDHANDLE);
+ LONG RFCheckReaderStatus(PREADER_CONTEXT);
+ void RFCleanupReaders(int);
+ int RFStartSerialReaders(const char *readerconf);
+ void RFReCheckReaderConf(void);
+ void RFSuspendAllReaders(void);
+ void RFAwakeAllReaders(void);
+
+ void ReaderContextLock(PREADER_CONTEXT rContext);
+ void ReaderContextUnlock(PREADER_CONTEXT rContext);
+ int ReaderContextIsLocked(PREADER_CONTEXT rContext);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2007 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * readerstate.cpp
+ * SmartCardServices
+*/
+
+#include "readerstate.h"
+#include "pcsclite.h"
+#include "eventhandler.h"
+#include <security_utilities/debugging.h>
+
+DWORD SharedReaderState_State(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->xreaderState();
+}
+
+DWORD SharedReaderState_Protocol(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->xcardProtocol();
+}
+
+DWORD SharedReaderState_Sharing(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->sharing();
+}
+
+size_t SharedReaderState_CardAtrLength(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->xcardAtrLength();
+}
+
+LONG SharedReaderState_ReaderID(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->xreaderID();
+}
+
+const unsigned char *SharedReaderState_CardAtr(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->xcardAtr();
+}
+
+const char *SharedReaderState_ReaderName(READER_STATE *rs)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return srs->xreaderName();
+}
+
+int SharedReaderState_ReaderNameIsEqual(READER_STATE *rs, const char *otherName)
+{
+ if (otherName)
+ {
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ return (strcmp(otherName, srs->xreaderName()) == 0);
+ }
+ else
+ return 0;
+}
+
+void SharedReaderState_SetState(READER_STATE *rs, DWORD state)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ srs->xreaderState(state);
+}
+
+void SharedReaderState_SetProtocol(READER_STATE *rs, DWORD newprotocol)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ srs->xcardProtocol(newprotocol);
+}
+
+void SharedReaderState_SetCardAtrLength(READER_STATE *rs, size_t len)
+{
+ PCSCD::SharedReaderState *srs = PCSCD::SharedReaderState::overlay(rs);
+ srs->xcardAtrLength(len);
+}
+
+
+#pragma mark ---------- C Interface ----------
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/readerstate.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2007 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * readerstate.h
+ * SmartCardServices
+ */
+
+#ifndef _H_PCSCD_READER_STATE
+#define _H_PCSCD_READER_STATE
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "readerfactory.h"
+#include "eventhandler.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+DWORD SharedReaderState_State(READER_STATE *rs);
+DWORD SharedReaderState_Protocol(READER_STATE *rs);
+DWORD SharedReaderState_Sharing(READER_STATE *rs);
+size_t SharedReaderState_CardAtrLength(READER_STATE *rs);
+LONG SharedReaderState_ReaderID(READER_STATE *rs);
+const unsigned char *SharedReaderState_CardAtr(READER_STATE *rs);
+const char *SharedReaderState_ReaderName(READER_STATE *rs);
+int SharedReaderState_ReaderNameIsEqual(READER_STATE *rs, const char *otherName);
+void SharedReaderState_SetState(READER_STATE *rs, DWORD state);
+void SharedReaderState_SetProtocol(READER_STATE *rs, DWORD newprotocol);
+void SharedReaderState_SetCardAtrLength(READER_STATE *rs, size_t len);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined(__cplusplus)
+
+#include <security_utilities/threading.h>
+
+namespace PCSCD {
+
+//
+// NB: We are using the fact that on our systems, mutexes provide read/write
+// memory barrier as a side effect to avoid having to flush the shared memory
+// region to disk
+//
+
+
+//
+// A PODWrapper for the PCSC ReaderState structure
+//
+class SharedReaderState : public PodWrapper<SharedReaderState, READER_STATE>
+{
+public:
+
+ LONG xreaderID() const { Atomic<int>::barrier(); return ntohl(readerID); }
+ void xreaderID(LONG rid) { Atomic<int>::barrier(); readerID = htonl(rid); }
+
+ DWORD xreaderState() const { Atomic<int>::barrier(); return ntohl(readerState); }
+ void xreaderState(DWORD state) { Atomic<int>::barrier(); readerState = htonl(state); }
+
+ DWORD sharing() const { Atomic<int>::barrier(); return ntohl(readerSharing); }
+ void sharing(DWORD sharing) { Atomic<int>::barrier(); readerSharing = htonl(sharing); }
+
+ DWORD xlockState() const { Atomic<int>::barrier(); return ntohl(lockState); }
+ void xlockState(DWORD state) { Atomic<int>::barrier(); lockState = htonl(state); }
+
+ DWORD xcardProtocol() const { Atomic<int>::barrier(); return ntohl(cardProtocol); }
+ void xcardProtocol(DWORD prot) { Atomic<int>::barrier(); cardProtocol = htonl(prot); }
+
+ // strings
+ const char *xreaderName() const { Atomic<int>::barrier(); return readerName; }
+ void xreaderName(const char *rname, size_t len = MAX_READERNAME) { Atomic<int>::barrier(); strlcpy(readerName, rname, len); }
+ size_t readerNameLength() const { return strlen(readerName); }
+ void xreaderNameClear() { Atomic<int>::barrier(); memset(readerName, 0, sizeof(readerName)); }
+
+ const unsigned char *xcardAtr() const { Atomic<int>::barrier(); return cardAtr; }
+ unsigned char *xcardAtr() { Atomic<int>::barrier(); return cardAtr; }
+ void xcardAtr(const unsigned char *atr, size_t len) { Atomic<int>::barrier();
+ memcpy((char *)&cardAtr[0], (const char *)atr, len); cardAtrLength = htonl(len); }
+ size_t xcardAtrLength() const { Atomic<int>::barrier(); return ntohl(cardAtrLength); }
+ void xcardAtrLength(DWORD len) { Atomic<int>::barrier(); cardAtrLength = htonl(len); }
+ void xcardAtrClear() { Atomic<int>::barrier(); memset(cardAtr, 0, sizeof(cardAtr)); }
+};
+
+
+
+} // end namespace PCSCD
+
+#endif /* __cplusplus__ */
+
+#endif //_H_PCSCD_READER_STATE
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_generic.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_generic.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_generic.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sys_generic.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ *
+ * $Id: sys_generic.h 2264 2006-12-03 13:15:03Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles abstract system level calls.
+ */
+
+#ifndef __sys_generic_h__
+#define __sys_generic_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <sys/stat.h>
+
+ int SYS_Initialize(void);
+
+ int SYS_Mkdir(const char *, int);
+
+ int SYS_GetPID(void);
+
+ int SYS_Sleep(int);
+
+ int SYS_USleep(int);
+
+ int SYS_OpenFile(const char *, int, int);
+
+ int SYS_CloseFile(int);
+
+ int SYS_RemoveFile(const char *);
+
+ int SYS_Chmod(const char *, int);
+
+ int SYS_Chdir(const char *);
+
+ int SYS_GetUID(void);
+
+ int SYS_GetGID(void);
+
+ int SYS_ChangePermissions(const char *, int);
+
+ int SYS_SeekFile(int, int);
+
+ int SYS_ReadFile(int, char *, int);
+
+ int SYS_WriteFile(int, const char *, int);
+
+ int SYS_GetPageSize(void);
+
+ void *SYS_MemoryMap(int, int, int);
+
+ void *SYS_PublicMemoryMap(int, int, int);
+
+ void SYS_PublicMemoryUnmap(void *, int);
+
+ int SYS_MMapSynchronize(void *, int);
+
+ int SYS_Fork(void);
+
+ int SYS_Daemon(int, int);
+
+ int SYS_Stat(const char *pcFile, struct stat *psStatus);
+
+ int SYS_Fstat(int);
+
+ int SYS_Random(int, float, float);
+
+ int SYS_GetSeed();
+
+ void SYS_Exit(int);
+
+ int SYS_Unlink(const char *pcFile);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __sys_generic_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_macosx.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_macosx.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_macosx.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,374 @@
+/*
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : sys_unix.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 11/8/99
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This handles abstract system level calls.
+
+$Id: sys_macosx.cpp,v 1.5.40.1 2005/06/17 22:40:12 mb Exp $
+
+********************************************************************/
+
+#include <sys_generic.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <time.h>
+#include "pcscexport.h"
+#include "debug.h"
+
+#include "pcscdmonitor.h"
+#include <securityd_client/ssclient.h>
+//#include <security_utilities/debugging.h>
+
+#include "config.h"
+
+
+extern "C" {
+
+int SYS_Initialize()
+{
+ /*
+ * Nothing special for OS X and Linux
+ */
+ return 0;
+}
+
+/**
+ * @brief Attempts to create a directory with some permissions.
+ *
+ * @param[in] path Path of the directory to be created.
+ * @param[in] perms Permissions to the new directory.
+ *
+ * @return Eror code.
+ * @retval 0 Success.
+ * @retval -1 An error occurred.
+ */
+INTERNAL int SYS_Mkdir(const char *path, int perms)
+{
+ return mkdir(path, perms);
+}
+
+/**
+ * @brief Gets the running process's ID.
+ *
+ * @return PID.
+ */
+INTERNAL int SYS_GetPID(void)
+{
+ return getpid();
+}
+
+/**
+ * @brief Makes the current process sleep for some seconds.
+ *
+ * @param[in] iTimeVal Number of seconds to sleep.
+ */
+INTERNAL int SYS_Sleep(int iTimeVal)
+{
+#ifdef HAVE_NANOSLEEP
+ struct timespec mrqtp;
+ mrqtp.tv_sec = iTimeVal;
+ mrqtp.tv_nsec = 0;
+
+ return nanosleep(&mrqtp, NULL);
+#else
+ return sleep(iTimeVal);
+#endif
+}
+
+/**
+ * @brief Makes the current process sleep for some microseconds.
+ *
+ * @param[in] iTimeVal Number of microseconds to sleep.
+ */
+INTERNAL int SYS_USleep(int iTimeVal)
+{
+#ifdef HAVE_NANOSLEEP
+ struct timespec mrqtp;
+ mrqtp.tv_sec = iTimeVal/1000000;
+ mrqtp.tv_nsec = (iTimeVal - (mrqtp.tv_sec * 1000000)) * 1000;
+
+ return nanosleep(&mrqtp, NULL);
+#else
+ usleep(iTimeVal);
+ return iTimeVal;
+#endif
+}
+
+/**
+ * @brief Opens/creates a file.
+ *
+ * @param[in] pcFile path to the file.
+ * @param[in] flags Open and read/write choices.
+ * @param[in] mode Permissions to the file.
+ *
+ * @return File descriptor.
+ * @retval >0 The file descriptor.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_OpenFile(const char *pcFile, int flags, int mode)
+{
+ return open(pcFile, flags, mode);
+}
+
+/**
+ * @brief Opens/creates a file.
+ *
+ * @param[in] iHandle File descriptor.
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_CloseFile(int iHandle)
+{
+ return close(iHandle);
+}
+
+/**
+ * @brief Removes a file.
+ *
+ * @param[in] pcFile path to the file.
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_RemoveFile(const char *pcFile)
+{
+ return remove(pcFile);
+}
+
+INTERNAL int SYS_Chmod(const char *path, int mode)
+{
+ return chmod(path, mode);
+}
+
+INTERNAL int SYS_Chdir(const char *path)
+{
+ return chdir(path);
+}
+
+int SYS_Mkfifo(const char *path, int mode)
+{
+ return mkfifo(path, mode);
+}
+
+int SYS_Mknod(const char *path, int mode, int dev)
+{
+ return mknod(path, mode, dev);
+}
+
+int SYS_GetUID()
+{
+ return getuid();
+}
+
+INTERNAL int SYS_GetGID(void)
+{
+ return getgid();
+}
+
+INTERNAL int SYS_SeekFile(int iHandle, int iSeekLength)
+{
+ int iOffset;
+ iOffset = lseek(iHandle, iSeekLength, SEEK_SET);
+ return iOffset;
+}
+
+INTERNAL int SYS_ReadFile(int iHandle, char *pcBuffer, int iLength)
+{
+ return read(iHandle, pcBuffer, iLength);
+}
+
+INTERNAL int SYS_WriteFile(int iHandle, const char *pcBuffer, int iLength)
+{
+ return write(iHandle, pcBuffer, iLength);
+}
+
+/**
+ * @brief Gets the memory page size.
+ *
+ * The page size is used when calling the \c SYS_MemoryMap() and
+ * \c SYS_PublicMemoryMap() functions.
+ *
+ * @return Number of bytes per page.
+ */
+INTERNAL int SYS_GetPageSize(void)
+{
+ return getpagesize();
+}
+
+/**
+ * @brief Map the file \p iFid in memory for reading and writing.
+ *
+ * @param[in] iSize Size of the memmory mapped.
+ * @param[in] iFid File which will be mapped in memory.
+ * @param[in] iOffset Start point of the file to be mapped in memory.
+ *
+ * @return Address of the memory map.
+ * @retval MAP_FAILED in case of error
+ */
+INTERNAL void *SYS_MemoryMap(int iSize, int iFid, int iOffset)
+{
+
+ void *vAddress;
+
+ vAddress = 0;
+ vAddress = mmap(0, iSize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, iFid, iOffset);
+
+ /*
+ * Here are some common error types: switch( errno ) { case EINVAL:
+ * printf("EINVAL"); case EBADF: printf("EBADF"); break; case EACCES:
+ * printf("EACCES"); break; case EAGAIN: printf("EAGAIN"); break; case
+ * ENOMEM: printf("ENOMEM"); break; }
+ */
+
+ return vAddress;
+}
+
+/**
+ * @brief Map the file \p iFid in memory only for reading.
+ *
+ * @param[in] iSize Size of the memmory mapped.
+ * @param[in] iFid File which will be mapped in memory.
+ * @param[in] iOffset Start point of the file to be mapped in memory.
+ *
+ * @return Address of the memory map.
+ */
+INTERNAL void *SYS_PublicMemoryMap(int iSize, int iFid, int iOffset)
+{
+
+ void *vAddress;
+
+ vAddress = 0;
+ vAddress = mmap(0, iSize, PROT_READ, MAP_SHARED, iFid, iOffset);
+ if (vAddress == (void*)-1) /* mmap returns -1 on error */
+ {
+ Log2(PCSC_LOG_CRITICAL, "SYS_PublicMemoryMap() failed: %s",
+ strerror(errno));
+ vAddress = NULL;
+ }
+
+ return vAddress;
+}
+
+int SYS_MMapSynchronize(void *begin, int length)
+{
+ int rc = msync(begin, length, MS_SYNC | MS_INVALIDATE);
+
+ PCSCDMonitor::postNotification(SecurityServer::kNotificationPCSCStateChange);
+
+ return rc;
+}
+
+int SYS_MUnmap(void *begin, int length)
+{
+ return munmap(begin, length);
+}
+
+INTERNAL int SYS_Fork(void)
+{
+ return fork();
+}
+
+#ifdef HAVE_DAEMON
+int SYS_Daemon(int nochdir, int noclose)
+{
+ return daemon(nochdir, noclose);
+}
+#endif
+
+int SYS_Wait(int iPid, int iWait)
+{
+ return waitpid(-1, 0, WNOHANG);
+}
+
+INTERNAL int SYS_Stat(const char *pcFile, struct stat *psStatus)
+{
+ return stat(pcFile, psStatus);
+}
+
+int SYS_Fstat(int iFd)
+{
+ struct stat sStatus;
+ return fstat(iFd, &sStatus);
+}
+
+int SYS_Random(int iSeed, float fStart, float fEnd)
+{
+
+ int iRandNum = 0;
+
+ if (iSeed != 0)
+ {
+ srand(iSeed);
+ }
+
+ iRandNum = 1 + (int) (fEnd * rand() / (RAND_MAX + fStart));
+ srand(iRandNum);
+
+ return iRandNum;
+}
+
+INTERNAL int SYS_GetSeed(void)
+{
+ struct timeval tv;
+ struct timezone tz;
+ long myseed = 0;
+
+ tz.tz_minuteswest = 0;
+ tz.tz_dsttime = 0;
+ if (gettimeofday(&tv, &tz) == 0)
+ {
+ myseed = tv.tv_usec;
+ } else
+ {
+ myseed = (long) time(NULL);
+ }
+ return myseed;
+}
+
+INTERNAL void SYS_Exit(int iRetVal)
+{
+ _exit(iRetVal);
+}
+
+INTERNAL int SYS_Unlink(const char *pcFile)
+{
+ return unlink(pcFile);
+}
+
+} // extern "C"
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_unix.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_unix.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/sys_unix.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * sys_unix.c
+ * SmartCardServices
+ */
+
+/*
+ * This handles abstract system level calls.
+ *
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ *
+ * $Id: sys_unix.c 2353 2007-01-23 10:31:50Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles abstract system level calls.
+ */
+
+#include <sys_generic.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <time.h>
+#include <string.h>
+#include "debug.h"
+
+#include "config.h"
+#include "pcscexport.h"
+
+#include <security_utilities/debugging.h>
+
+/**
+ * @brief Make system wide initialization.
+ *
+ * @return Eror code.
+ * @retval 0 Success.
+ */
+INTERNAL int SYS_Initialize(void)
+{
+ /*
+ * Nothing special for OS X and Linux
+ */
+ return 0;
+}
+
+/**
+ * @brief Attempts to create a directory with some permissions.
+ *
+ * @param[in] path Path of the directory to be created.
+ * @param[in] perms Permissions to the new directory.
+ *
+ * @return Eror code.
+ * @retval 0 Success.
+ * @retval -1 An error occurred.
+ */
+INTERNAL int SYS_Mkdir(const char *path, int perms)
+{
+ return mkdir(path, perms);
+}
+
+/**
+ * @brief Gets the running process's ID.
+ *
+ * @return PID.
+ */
+INTERNAL int SYS_GetPID(void)
+{
+ return getpid();
+}
+
+/**
+ * @brief Makes the current process sleep for some seconds.
+ *
+ * @param[in] iTimeVal Number of seconds to sleep.
+ */
+INTERNAL int SYS_Sleep(int iTimeVal)
+{
+#ifdef HAVE_NANOSLEEP
+ struct timespec mrqtp;
+ mrqtp.tv_sec = iTimeVal;
+ mrqtp.tv_nsec = 0;
+
+ return nanosleep(&mrqtp, NULL);
+#else
+ return sleep(iTimeVal);
+#endif
+}
+
+/**
+ * @brief Makes the current process sleep for some microseconds.
+ *
+ * @param[in] iTimeVal Number of microseconds to sleep.
+ */
+INTERNAL int SYS_USleep(int iTimeVal)
+{
+#ifdef HAVE_NANOSLEEP
+ struct timespec mrqtp;
+ mrqtp.tv_sec = iTimeVal/1000000;
+ mrqtp.tv_nsec = (iTimeVal - (mrqtp.tv_sec * 1000000)) * 1000;
+
+ return nanosleep(&mrqtp, NULL);
+#else
+ usleep(iTimeVal);
+ return iTimeVal;
+#endif
+}
+
+/**
+ * @brief Opens/creates a file.
+ *
+ * @param[in] pcFile path to the file.
+ * @param[in] flags Open and read/write choices.
+ * @param[in] mode Permissions to the file.
+ *
+ * @return File descriptor.
+ * @retval >0 The file descriptor.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_OpenFile(const char *pcFile, int flags, int mode)
+{
+ return open(pcFile, flags, mode);
+}
+
+/**
+ * @brief Opens/creates a file.
+ *
+ * @param[in] iHandle File descriptor.
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_CloseFile(int iHandle)
+{
+ return close(iHandle);
+}
+
+/**
+ * @brief Removes a file.
+ *
+ * @param[in] pcFile path to the file.
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_RemoveFile(const char *pcFile)
+{
+ return remove(pcFile);
+}
+
+INTERNAL int SYS_Chmod(const char *path, int mode)
+{
+ return chmod(path, mode);
+}
+
+INTERNAL int SYS_Chdir(const char *path)
+{
+ return chdir(path);
+}
+
+INTERNAL int SYS_GetUID(void)
+{
+ return getuid();
+}
+
+INTERNAL int SYS_GetGID(void)
+{
+ return getgid();
+}
+
+INTERNAL int SYS_SeekFile(int iHandle, int iSeekLength)
+{
+ int iOffset;
+ iOffset = lseek(iHandle, iSeekLength, SEEK_SET);
+ return iOffset;
+}
+
+INTERNAL int SYS_ReadFile(int iHandle, char *pcBuffer, int iLength)
+{
+ return read(iHandle, pcBuffer, iLength);
+}
+
+INTERNAL int SYS_WriteFile(int iHandle, const char *pcBuffer, int iLength)
+{
+ return write(iHandle, pcBuffer, iLength);
+}
+
+/**
+ * @brief Gets the memory page size.
+ *
+ * The page size is used when calling the \c SYS_MemoryMap() and
+ * \c SYS_PublicMemoryMap() functions.
+ *
+ * @return Number of bytes per page.
+ */
+INTERNAL int SYS_GetPageSize(void)
+{
+ return getpagesize();
+}
+
+/**
+ * @brief Map the file \p iFid in memory for reading and writing.
+ *
+ * @param[in] iSize Size of the memmory mapped.
+ * @param[in] iFid File which will be mapped in memory.
+ * @param[in] iOffset Start point of the file to be mapped in memory.
+ *
+ * @return Address of the memory map.
+ * @retval MAP_FAILED in case of error
+ */
+INTERNAL void *SYS_MemoryMap(int iSize, int iFid, int iOffset)
+{
+
+ void *vAddress;
+
+ vAddress = 0;
+ vAddress = mmap(0, iSize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, iFid, iOffset);
+
+ /*
+ * Here are some common error types: switch( errno ) { case EINVAL:
+ * printf("EINVAL"); case EBADF: printf("EBADF"); break; case EACCES:
+ * printf("EACCES"); break; case EAGAIN: printf("EAGAIN"); break; case
+ * ENOMEM: printf("ENOMEM"); break; }
+ */
+
+ return vAddress;
+}
+
+/**
+ * @brief Map the file \p iFid in memory only for reading.
+ *
+ * @param[in] iSize Size of the memmory mapped.
+ * @param[in] iFid File which will be mapped in memory.
+ * @param[in] iOffset Start point of the file to be mapped in memory.
+ *
+ * @return Address of the memory map.
+ */
+INTERNAL void *SYS_PublicMemoryMap(int iSize, int iFid, int iOffset)
+{
+
+ void *vAddress;
+
+ vAddress = 0;
+ vAddress = mmap(0, iSize, PROT_READ, MAP_SHARED, iFid, iOffset);
+ if (vAddress == (void*)-1) /* mmap returns -1 on error */
+ {
+ Log2(PCSC_LOG_CRITICAL, "SYS_PublicMemoryMap() failed: %s",
+ strerror(errno));
+ vAddress = NULL;
+ }
+
+ return vAddress;
+}
+
+/**
+ * @brief Unmap a memory segment
+ *
+ * @param ptr pointer returned by SYS_PublicMemoryMap()
+ * @param iSize size of the memory segment
+ */
+INTERNAL void SYS_PublicMemoryUnmap(void * ptr, int iSize)
+{
+ munmap(ptr, iSize);
+}
+
+/**
+ * @brief Writes the changes made in a memory map to the disk mapped file.
+ *
+ * @param[in] begin Start of the block to be written
+ * @param[in] length Lenght of the block to be written
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 An error ocurred.
+ */
+INTERNAL int SYS_MMapSynchronize(void *begin, int length)
+{
+ int flags = 0;
+
+#ifdef MS_INVALIDATE
+ flags |= MS_INVALIDATE;
+#endif
+ return msync(begin, length, MS_SYNC | flags);
+}
+
+INTERNAL int SYS_Fork(void)
+{
+ return fork();
+}
+
+/**
+ * @brief put the process to run in the background.
+ *
+ * @param[in] nochdir if zero, change the current directory to "/".
+ * @param[in] noclose if zero, redirect standard imput/output/error to /dev/nulll.
+ *
+ * @return error code.
+ * @retval 0 success.
+ * @retval -1 an error ocurred.
+ */
+INTERNAL int SYS_Daemon(int nochdir, int noclose)
+{
+#ifdef HAVE_DAEMON
+ return daemon(nochdir, noclose);
+}
+#endif
+
+int SYS_Wait(int iPid, int iWait)
+{
+ return waitpid(-1, 0, WNOHANG);
+}
+
+INTERNAL int SYS_Stat(const char *pcFile, struct stat *psStatus)
+{
+ return stat(pcFile, psStatus);
+}
+
+int SYS_Fstat(int iFd)
+{
+ struct stat sStatus;
+ return fstat(iFd, &sStatus);
+}
+
+int SYS_Random(int iSeed, float fStart, float fEnd)
+{
+
+ int iRandNum = 0;
+
+ if (iSeed != 0)
+ {
+ srand(iSeed);
+ }
+
+ iRandNum = 1 + (int) (fEnd * rand() / (RAND_MAX + fStart));
+ srand(iRandNum);
+
+ return iRandNum;
+}
+
+INTERNAL int SYS_GetSeed(void)
+{
+ struct timeval tv;
+ struct timezone tz;
+ long myseed = 0;
+
+ tz.tz_minuteswest = 0;
+ tz.tz_dsttime = 0;
+ if (gettimeofday(&tv, &tz) == 0)
+ {
+ myseed = tv.tv_usec;
+ } else
+ {
+ myseed = (long) time(NULL);
+ }
+ return myseed;
+}
+
+INTERNAL void SYS_Exit(int iRetVal)
+{
+ _exit(iRetVal);
+}
+
+INTERNAL int SYS_Unlink(const char *pcFile)
+{
+ return unlink(pcFile);
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/testpcsc.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/testpcsc.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/testpcsc.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : test.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 7/27/99
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This is a test program for pcsc-lite.
+
+********************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "config.h"
+#include "pcsclite.h"
+#include "winscard.h"
+
+/*
+ * #define REPEAT_TEST 1
+ */
+
+int main(int argc, char **argv)
+{
+ SCARDHANDLE hCard;
+ SCARDCONTEXT hContext;
+ SCARD_READERSTATE_A rgReaderStates[1];
+ uint32_t dwReaderLen, dwState, dwProt, dwAtrLen;
+ // unsigned long dwSendLength, dwRecvLength;
+ uint32_t dwPref, dwReaders;
+ char *pcReaders, *mszReaders;
+ unsigned char pbAtr[MAX_ATR_SIZE];
+ const char *mszGroups;
+ long rv;
+ int i, p, iReader;
+ int iList[16];
+
+ int t = 0;
+
+ printf("\nMUSCLE PC/SC Lite Test Program\n\n");
+
+doInit:
+ printf("Testing SCardEstablishContext : ");
+ rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ return -1;
+ }
+
+ printf("Testing SCardGetStatusChange \n");
+ printf("Please insert a working reader : ");
+ rv = SCardGetStatusChange(hContext, INFINITE, 0, 0);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardReleaseContext(hContext);
+ return -1;
+ }
+
+ printf("Testing SCardListReaders : ");
+
+ mszGroups = 0;
+ rv = SCardListReaders(hContext, mszGroups, 0, &dwReaders);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardReleaseContext(hContext);
+ return -1;
+ }
+
+ mszReaders = (char *) malloc(sizeof(char) * dwReaders);
+ rv = SCardListReaders(hContext, mszGroups, mszReaders, &dwReaders);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardReleaseContext(hContext);
+ return -1;
+ }
+
+ /*
+ * Have to understand the multi-string here
+ */
+ p = 0;
+ for (i = 0; i < dwReaders - 1; i++)
+ {
+ ++p;
+ printf("Reader %02d: %s\n", p, &mszReaders[i]);
+ iList[p] = i;
+ while (mszReaders[++i] != 0) ;
+ }
+
+#ifdef REPEAT_TEST
+ if (t == 0)
+ {
+#endif
+
+ do
+ {
+ /* scanf doesn't provide a friendly way to 'throw away' the garbage input
+ * so we grab a line and then try to parse it */
+ size_t iScanLength;
+ char *sLine;
+ printf("Enter the reader number : ");
+ sLine = fgetln(stdin, &iScanLength);
+ if(sLine == NULL) /* EOF */
+ return 0;
+ /* Null terminate by replacing \n w/ \0*/
+ sLine[iScanLength - 1] = '\0';
+ iReader = atoi(sLine);
+ /* Since 0 is invalid input, no need to test errno */
+ if(iReader > p || iReader <= 0) {
+ printf("Invalid Value - try again\n");
+ }
+ }
+ while (iReader > p || iReader <= 0);
+
+#ifdef REPEAT_TEST
+ t = 1;
+ }
+#endif
+
+ rgReaderStates[0].szReader = &mszReaders[iList[iReader]];
+ rgReaderStates[0].dwCurrentState = SCARD_STATE_EMPTY;
+
+ printf("Waiting for card insertion \n");
+ rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
+
+ printf(" : %s\n",
+ pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardReleaseContext(hContext);
+ return -1;
+ }
+
+// printf(" context handle: %d [0x%08X]\n", hContext, hContext);
+ printf("Testing SCardConnect : ");
+ rv = SCardConnect(hContext, &mszReaders[iList[iReader]],
+ SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,
+ &hCard, &dwPref);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardReleaseContext(hContext);
+ return -1;
+ }
+
+ printf("Testing SCardStatus : ");
+
+ dwReaderLen = MAX_READERNAME;
+ pcReaders = (char *) malloc(sizeof(char) * MAX_READERNAME);
+ dwAtrLen = MAX_ATR_SIZE;
+
+ rv = SCardStatus(hCard, pcReaders, &dwReaderLen, &dwState, &dwProt,
+ pbAtr, &dwAtrLen);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ printf("Current Reader Name : %s\n", pcReaders);
+ printf("Current Reader State : 0x%X\n", dwState);
+ printf("Current Reader Protocol : 0x%X\n", dwProt - 1);
+ printf("Current Reader ATR Size : %d (0x%x)\n", dwAtrLen, dwAtrLen);
+ printf("Current Reader ATR Value : ");
+
+ for (i = 0; i < dwAtrLen; i++)
+ {
+ printf("%02X ", pbAtr[i]);
+ }
+ printf("\n");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardDisconnect(hCard, SCARD_RESET_CARD);
+ SCardReleaseContext(hContext);
+ }
+
+ printf("Testing SCardDisconnect : ");
+ rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ SCardReleaseContext(hContext);
+ return -1;
+ }
+
+ printf("Testing SCardReleaseContext : ");
+ rv = SCardReleaseContext(hContext);
+
+ printf("%s\n", pcsc_stringify_error(rv));
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ return -1;
+ }
+ if(t == 0) {
+ t = 1;
+ goto doInit;
+ }
+
+ printf("\n");
+ printf("PC/SC Test Completed Successfully !\n");
+
+ return 0;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_generic.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_generic.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_generic.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : thread_generic.h
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 3/24/00
+ License: Copyright (C) 2000 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This provides system specific thread calls.
+
+********************************************************************/
+
+#ifndef __thread_generic_h__
+#define __thread_generic_h__
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifdef WIN32
+#define PCSCLITE_THREAD_T HANDLE
+#define PCSCLITE_MUTEX CRITICAL_SECTION
+#define PCSCLITE_MUTEX_T CRITICAL_SECTION*
+#define PCSCLITE_THREAD_FUNCTION(f) void *(*f)(void *)
+#else
+#define PCSCLITE_THREAD_T pthread_t
+#define PCSCLITE_MUTEX pthread_mutex_t
+#define PCSCLITE_MUTEX_T pthread_mutex_t*
+#define PCSCLITE_THREAD_FUNCTION(f) void *(*f)(void *)
+#endif
+
+/* thread attributes */
+#define THREAD_ATTR_DEFAULT 0
+#define THREAD_ATTR_DETACHED 1
+
+ int SYS_MutexInit(PCSCLITE_MUTEX_T);
+ int SYS_MutexDestroy(PCSCLITE_MUTEX_T);
+ int SYS_MutexLock(PCSCLITE_MUTEX_T);
+ int SYS_MutexUnLock(PCSCLITE_MUTEX_T);
+ int SYS_ThreadCreate(PCSCLITE_THREAD_T *, int, PCSCLITE_THREAD_FUNCTION( ), LPVOID);
+ int SYS_ThreadCancel(PCSCLITE_THREAD_T *);
+ int SYS_ThreadDetach(PCSCLITE_THREAD_T);
+ int SYS_ThreadJoin(PCSCLITE_THREAD_T *, LPVOID*);
+ int SYS_ThreadExit(LPVOID);
+ PCSCLITE_THREAD_T SYS_ThreadSelf(void);
+ int SYS_ThreadEqual(PCSCLITE_THREAD_T *, PCSCLITE_THREAD_T *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __thread_generic_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_macosx.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_macosx.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/thread_macosx.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : thread_macosx.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 7/6/00
+ License: Copyright (C) 2000 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This handles thread function abstraction.
+
+********************************************************************/
+
+#include "config.h"
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "thread_generic.h"
+
+#define PCSC_MUTEX_LOCKED 1
+#define PCSC_MUTEX_UNLOCKED 0
+
+int SYS_MutexInit(PCSCLITE_MUTEX_T mMutex)
+{
+ int retval;
+ retval = pthread_mutex_init(mMutex, NULL);
+ return retval;
+}
+
+int SYS_MutexDestroy(PCSCLITE_MUTEX_T mMutex)
+{
+ int retval;
+ retval = pthread_mutex_destroy(mMutex);
+ return retval;
+}
+
+int SYS_MutexLock(PCSCLITE_MUTEX_T mMutex)
+{
+ int retval;
+ retval = pthread_mutex_lock(mMutex);
+ return retval;
+}
+
+int SYS_MutexUnLock(PCSCLITE_MUTEX_T mMutex)
+{
+ int retval;
+ retval = pthread_mutex_unlock(mMutex);
+ return retval;
+}
+
+int SYS_ThreadCreate(PCSCLITE_THREAD_T * pthThread, int attributes,
+ PCSCLITE_THREAD_FUNCTION(pvFunction), LPVOID pvArg)
+{
+ pthread_attr_t attr;
+
+ if (0 != pthread_attr_init(&attr))
+ return 0;
+
+ if (0 != pthread_attr_setdetachstate(&attr,
+ attributes & THREAD_ATTR_DETACHED ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE))
+ return 0;
+
+ if (0 == pthread_create(pthThread, &attr, pvFunction, pvArg))
+ return 1;
+ else
+ return 0;
+}
+
+int SYS_ThreadCancel(PCSCLITE_THREAD_T * pthThread)
+{
+
+ int retval;
+ retval = pthread_cancel(*pthThread);
+
+ if (retval == 0)
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+}
+
+int SYS_ThreadDetach(PCSCLITE_THREAD_T pthThread)
+{
+ // Returns 1 (true) if thread detached OK, 0 (false) otherwise
+ if (pthThread)
+ return (pthread_detach(pthThread) == 0); // 0 result is success
+
+ return 0;
+}
+
+int SYS_ThreadJoin(PCSCLITE_THREAD_T *pthThread, LPVOID* pvRetVal)
+{
+
+ int retval;
+ retval = pthread_join(*pthThread, pvRetVal);
+
+ if (retval == 0)
+ {
+ return 1;
+ } else
+ {
+ return 0;
+ }
+}
+
+int SYS_ThreadExit(LPVOID pvRetVal)
+{
+
+ pthread_exit(pvRetVal);
+ return 1;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,787 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : tokenfactory.c
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 01/01/00
+ Purpose: This handles card abstraction attachment.
+
+ $Id: tokenfactory.c,v 1.3 2004/09/21 02:43:57 mb Exp $
+
+*******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#ifndef WIN32
+#include <dirent.h>
+#include "config.h"
+#else
+#include "../win32/win32_config.h"
+#endif
+
+#include "debuglog.h"
+#include "dyn_generic.h"
+#include "tokenfactory.h"
+
+#define MSC_MANUMSC_KEY_NAME "spVendorName"
+#define MSC_PRODMSC_KEY_NAME "spProductName"
+#define MSC_ATRMSC_KEY_NAME "spAtrValue"
+#define MSC_LIBRMSC_KEY_NAME "CFBundleExecutable"
+#define MSC_DEFAULTAPP_NAME "spDefaultApplication"
+
+extern int LTPBundleFindValueWithKey(char *, char *, char *, int);
+
+int atrToString(MSCPUChar8 Atr, MSCULong32 Length, char *outAtr)
+{
+
+ int i;
+ int j;
+
+ j = 0;
+
+ for (i = 0; i < Length; i++)
+ {
+ if ((Atr[i] / 16) > 9)
+ {
+ outAtr[j] = ((Atr[i] / 16) - 10) + 'A';
+ } else
+ {
+ outAtr[j] = (Atr[i] / 16) + '0';
+ }
+
+ j += 1;
+
+ if ((Atr[i] % 16) > 9)
+ {
+ outAtr[j] = ((Atr[i] % 16) - 10) + 'A';
+ } else
+ {
+ outAtr[j] = (Atr[i] % 16) + '0';
+ }
+
+ j += 1;
+
+ }
+
+ outAtr[j] = 0; /* Add the NULL */
+
+ return 0;
+}
+
+int stringToBytes(char *inStr, MSCPUChar8 Buffer, MSCPULong32 Length)
+{
+
+ int i;
+ int j;
+ int inLen;
+
+ j = 0;
+ inLen = 0;
+
+ inLen = strlen(inStr);
+
+ if (inLen > MSC_MAXSIZE_AID)
+ {
+ return -1;
+ }
+
+ for (i = 0; i < inLen; i += 2)
+ {
+ if (inStr[i] <= '9' && inStr[i] >= '0')
+ {
+ Buffer[j] = (inStr[i] - '0') * 16;
+ } else if (inStr[i] <= 'F' && inStr[i] >= 'A')
+ {
+ Buffer[j] = (inStr[i] - 'A' + 10) * 16;
+ }
+
+ if (inStr[i + 1] <= '9' && inStr[i + 1] >= '0')
+ {
+ Buffer[j] += inStr[i + 1] - '0';
+ } else if (inStr[i + 1] <= 'F' && inStr[i + 1] >= 'A')
+ {
+ Buffer[j] += inStr[i + 1] - 'A' + 10;
+ }
+
+ j += 1;
+ }
+
+ *Length = j;
+
+ return 0;
+}
+
+MSCLong32 TPSearchBundlesForAtr(MSCPUChar8 Atr, MSCULong32 Length,
+ MSCLPTokenInfo tokenInfo)
+{
+
+ MSCLong32 rv;
+
+#ifndef WIN32
+ DIR *hpDir = 0;
+ struct dirent *currFP = 0;
+#else
+ HANDLE hFind;
+ WIN32_FIND_DATA findData;
+ char findPath[200];
+#endif
+
+ char atrString[100];
+ char fullPath[200];
+ char fullLibPath[250];
+ char keyValue[200];
+ int atrIndex;
+
+ rv = 0;
+ atrIndex = 0;
+
+ atrToString(Atr, Length, atrString);
+
+#ifndef WIN32
+
+ hpDir = opendir(MSC_SVC_DROPDIR);
+
+ if (hpDir == 0)
+#else
+ sprintf(findPath, "%s\\*.bundle", MSC_SVC_DROPDIR);
+ hFind = FindFirstFile(findPath, &findData);
+
+ if (hFind == INVALID_HANDLE_VALUE)
+#endif
+ {
+ DebugLogA("Cannot open PC/SC token drivers directory.\n");
+
+ return -1;
+ }
+
+#ifndef WIN32
+ while ((currFP = readdir(hpDir)) != 0)
+ {
+ if (strstr(currFP->d_name, ".bundle") != 0)
+#else
+ do
+ {
+ if (strstr(findData.cFileName, ".bundle") != 0)
+#endif
+ {
+
+ /*
+ * The bundle exists - let's form a full path name and get the
+ * vendor and product ID's for this particular bundle
+ */
+#ifndef WIN32
+ sprintf(fullPath, "%s%s%s", MSC_SVC_DROPDIR, currFP->d_name,
+ "/Contents/Info.plist");
+#else
+ sprintf(fullPath, "%s%s%s", MSC_SVC_DROPDIR, findData.cFileName,
+ "\\Contents\\Info.plist");
+#endif
+
+ atrIndex = 0;
+
+#ifdef MSC_DEBUG
+ DebugLogB("ATR comparison: FILE: %s\n", fullPath);
+ DebugLogB("ATR comparison: Target Match: %s\n", atrString);
+#endif
+
+ while (1)
+ {
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_ATRMSC_KEY_NAME, keyValue, atrIndex);
+ if (rv != 0)
+ {
+ break; /* No aliases found, break out of search
+ * aliases loop */
+ }
+#ifdef MSC_DEBUG
+ DebugLogB("ATR comparison: Source: %s\n", keyValue);
+#endif
+
+ if (strcmp(keyValue, atrString) != 0)
+ {
+ /*
+ * Go back and see if there are any aliases
+ */
+ atrIndex += 1;
+ continue;
+ }
+#ifdef MSC_DEBUG
+ DebugLogB("Match found at ATR alias %d\n", atrIndex);
+#endif
+
+ /*
+ * See if this bundle has a special name for this ATR
+ */
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_PRODMSC_KEY_NAME, keyValue, atrIndex);
+ if (rv != 0)
+ {
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_PRODMSC_KEY_NAME, keyValue, 0);
+ if (rv != 0)
+ {
+ DebugLogA
+ ("Match found, failed due to no product name.\n");
+#ifndef WIN32
+ closedir(hpDir);
+#endif
+ return -1;
+ }
+ }
+#ifdef MSC_DEBUG
+ DebugLogB("Product name: %s\n", keyValue);
+#endif
+ strcpy(tokenInfo->tokenName, keyValue);
+
+ /*
+ * See if this bundle has a special driver for this card
+ */
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_LIBRMSC_KEY_NAME, keyValue, atrIndex);
+ if (rv != 0)
+ {
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_LIBRMSC_KEY_NAME, keyValue, 0);
+ if (rv != 0)
+ {
+ DebugLogA
+ ("Match found, failed due to no library path.\n");
+#ifndef WIN32
+ closedir(hpDir);
+#endif
+ return -1;
+ }
+ }
+#ifdef WIN32
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ findData.cFileName, "\\Contents\\Win32\\", keyValue);
+#else
+#ifdef MSC_TARGET_LINUX
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name, "/Contents/Linux/", keyValue);
+#else
+#ifdef MSC_TARGET_OSX
+ sprintf(fullLibPath, "%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name);
+
+#else
+#ifdef MSC_TARGET_BSD
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name, "/Contents/BSD/", keyValue);
+
+#else
+#ifdef MSC_TARGET_SOLARIS
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name, "/Contents/Solaris/", keyValue);
+
+#else
+#ifdef MSC_TARGET_HPUX
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name, "/Contents/HPUX/", keyValue);
+
+#else
+#ifdef MSC_TARGET_TRU64
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name, "/Contents/Tru64/", keyValue);
+
+#else
+#ifdef MSC_TARGET_CYGWIN
+ sprintf(fullLibPath, "%s%s%s%s", MSC_SVC_DROPDIR,
+ currFP->d_name, "/Contents/CygWin/", keyValue);
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+ if (fullLibPath == NULL)
+ {
+ DebugLogA("No path to bundle library found !\n");
+ return -1;
+ }
+
+ /*
+ * Copy the library path and return successfully
+ */
+ strcpy(tokenInfo->svProvider, fullLibPath);
+
+ /*
+ * See if this bundle has a default AID
+ */
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_DEFAULTAPP_NAME, keyValue, atrIndex);
+ if (rv != 0)
+ {
+ rv = LTPBundleFindValueWithKey(fullPath,
+ MSC_DEFAULTAPP_NAME, keyValue, 0);
+ }
+
+ if (rv == 0)
+ {
+#ifdef MSC_DEBUG
+ DebugLogB("Default AID name: %s\n", keyValue);
+#endif
+ rv = stringToBytes(keyValue, tokenInfo->tokenApp,
+ &tokenInfo->tokenAppLen);
+ if (rv != 0)
+ {
+ DebugLogA
+ ("Match found, failed due to malformed aid string.\n");
+#ifndef WIN32
+ closedir(hpDir);
+#endif
+ return -1;
+ }
+
+ } else
+ {
+ DebugLogA("No AID specified in bundle\n");
+ tokenInfo->tokenAppLen = 0;
+ }
+
+#ifndef WIN32
+ closedir(hpDir);
+#endif
+ return 0;
+
+ } /* do ... while */
+ } /* if .bundle */
+ } /* while readdir */
+#ifdef WIN32
+ // This is part of a Do..While loop (see above)
+ while (FindNextFile(hFind, &findData) != 0);
+#endif
+
+#ifndef WIN32
+ closedir(hpDir);
+#endif
+ return -1;
+}
+
+const char *TPSvcDropdir(void)
+{
+ const char *dropDir = getenv(MSC_SVC_DROPDIR_ENV);
+ if (dropDir)
+ return dropDir;
+
+ return MSC_SVC_DROPDIR_DEFAULT;
+}
+
+MSCLong32 TPLoadToken(MSCLPTokenConnection pConnection)
+{
+
+ MSCLong32 rv;
+
+ pConnection->libPointers.pvfWriteFramework = 0;
+ pConnection->libPointers.pvfInitializePlugin = 0;
+ pConnection->libPointers.pvfFinalizePlugin = 0;
+ pConnection->libPointers.pvfGetStatus = 0;
+ pConnection->libPointers.pvfGetCapabilities = 0;
+ pConnection->libPointers.pvfExtendedFeature = 0;
+ pConnection->libPointers.pvfGenerateKeys = 0;
+ pConnection->libPointers.pvfImportKey = 0;
+ pConnection->libPointers.pvfExportKey = 0;
+ pConnection->libPointers.pvfComputeCrypt = 0;
+ pConnection->libPointers.pvfExtAuthenticate = 0;
+ pConnection->libPointers.pvfListKeys = 0;
+ pConnection->libPointers.pvfCreatePIN = 0;
+ pConnection->libPointers.pvfVerifyPIN = 0;
+ pConnection->libPointers.pvfChangePIN = 0;
+ pConnection->libPointers.pvfUnblockPIN = 0;
+ pConnection->libPointers.pvfListPINs = 0;
+ pConnection->libPointers.pvfCreateObject = 0;
+ pConnection->libPointers.pvfDeleteObject = 0;
+ pConnection->libPointers.pvfWriteObject = 0;
+ pConnection->libPointers.pvfReadObject = 0;
+ pConnection->libPointers.pvfListObjects = 0;
+ pConnection->libPointers.pvfLogoutAll = 0;
+ pConnection->libPointers.pvfGetChallenge = 0;
+
+ /*
+ * Find the Card's Library
+ */
+
+ rv = TPSearchBundlesForAtr(pConnection->tokenInfo.tokenId,
+ pConnection->tokenInfo.tokenIdLength, &pConnection->tokenInfo);
+
+ if (rv != 0)
+ {
+ DebugLogA("Error: Matching Token ATR Not Found.\n");
+ log_xxd(PCSC_LOG_INFO, "ATR : ", pConnection->tokenInfo.tokenId,
+ pConnection->tokenInfo.tokenIdLength);
+
+ return SCARD_E_CARD_UNSUPPORTED;
+ }
+
+ /*
+ * Load that library and store the handle in the SCARDCHANNEL
+ * structure
+ */
+
+ rv = DYN_LoadLibrary(&pConnection->tokenLibHandle,
+ pConnection->tokenInfo.svProvider);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ DebugLogA("Error: Could not load service library\n");
+ DebugLogB("->> %s\n", pConnection->tokenInfo.svProvider);
+ return SCARD_E_INVALID_TARGET;
+ } else
+ {
+ DebugLogB("Loading service library %s\n",
+ pConnection->tokenInfo.svProvider);
+ }
+
+ rv = TPBindFunctions(pConnection);
+
+ return rv;
+}
+
+MSCLong32 TPUnloadToken(MSCLPTokenConnection pConnection)
+{
+
+ MSCLong32 rv;
+
+ if (pConnection->tokenLibHandle == 0)
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ rv = DYN_CloseLibrary(&pConnection->tokenLibHandle);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ return rv;
+ }
+
+ pConnection->tokenLibHandle = 0;
+ return TPUnbindFunctions(pConnection);
+}
+
+MSCLong32 TPBindFunctions(MSCLPTokenConnection pConnection)
+{
+
+ MSCLong32 rv;
+
+ if (pConnection->tokenLibHandle == 0)
+ {
+ return SCARD_E_INVALID_TARGET;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfWriteFramework,
+ "PL_MSCWriteFramework");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfWriteFramework = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ /*
+ * No big deal - this feature is just not supported
+ */
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfIdentifyToken, "PL_MSCIdentifyToken");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfIdentifyToken = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfInitializePlugin,
+ "PL_MSCInitializePlugin");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfInitializePlugin = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfFinalizePlugin,
+ "PL_MSCFinalizePlugin");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfFinalizePlugin = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfGetStatus, "PL_MSCGetStatus");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfGetStatus = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfGetCapabilities,
+ "PL_MSCGetCapabilities");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfGetCapabilities = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfExtendedFeature,
+ "PL_MSCExtendedFeature");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfExtendedFeature = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ /*
+ * No big deal - there are no extended features
+ */
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfGenerateKeys, "PL_MSCGenerateKeys");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfGenerateKeys = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfImportKey, "PL_MSCImportKey");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfImportKey = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfExportKey, "PL_MSCExportKey");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfExportKey = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfComputeCrypt, "PL_MSCComputeCrypt");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfComputeCrypt = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfExtAuthenticate,
+ "PL_MSCExtAuthenticate");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfExtAuthenticate = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfListKeys, "PL_MSCListKeys");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfListKeys = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfCreatePIN, "PL_MSCCreatePIN");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfCreatePIN = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfVerifyPIN, "PL_MSCVerifyPIN");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfVerifyPIN = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfChangePIN, "PL_MSCChangePIN");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfChangePIN = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfUnblockPIN, "PL_MSCUnblockPIN");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfUnblockPIN = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfListPINs, "PL_MSCListPINs");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfListPINs = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfCreateObject, "PL_MSCCreateObject");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfCreateObject = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfDeleteObject, "PL_MSCDeleteObject");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfDeleteObject = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfWriteObject, "PL_MSCWriteObject");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfWriteObject = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfReadObject, "PL_MSCReadObject");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfReadObject = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfListObjects, "PL_MSCListObjects");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfListObjects = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfLogoutAll, "PL_MSCLogoutAll");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfLogoutAll = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ rv = DYN_GetAddress(pConnection->tokenLibHandle,
+ &pConnection->libPointers.pvfGetChallenge, "PL_MSCGetChallenge");
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ pConnection->libPointers.pvfGetChallenge = 0;
+ DebugLogA("TPBindFunctions: Missing functions");
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+MSCLong32 TPUnbindFunctions(MSCLPTokenConnection pConnection)
+{
+
+ pConnection->libPointers.pvfWriteFramework = 0;
+ pConnection->libPointers.pvfInitializePlugin = 0;
+ pConnection->libPointers.pvfFinalizePlugin = 0;
+ pConnection->libPointers.pvfGetStatus = 0;
+ pConnection->libPointers.pvfGetCapabilities = 0;
+ pConnection->libPointers.pvfExtendedFeature = 0;
+ pConnection->libPointers.pvfGenerateKeys = 0;
+ pConnection->libPointers.pvfImportKey = 0;
+ pConnection->libPointers.pvfExportKey = 0;
+ pConnection->libPointers.pvfComputeCrypt = 0;
+ pConnection->libPointers.pvfExtAuthenticate = 0;
+ pConnection->libPointers.pvfListKeys = 0;
+ pConnection->libPointers.pvfCreatePIN = 0;
+ pConnection->libPointers.pvfVerifyPIN = 0;
+ pConnection->libPointers.pvfChangePIN = 0;
+ pConnection->libPointers.pvfUnblockPIN = 0;
+ pConnection->libPointers.pvfListPINs = 0;
+ pConnection->libPointers.pvfCreateObject = 0;
+ pConnection->libPointers.pvfDeleteObject = 0;
+ pConnection->libPointers.pvfWriteObject = 0;
+ pConnection->libPointers.pvfReadObject = 0;
+ pConnection->libPointers.pvfListObjects = 0;
+ pConnection->libPointers.pvfLogoutAll = 0;
+ pConnection->libPointers.pvfGetChallenge = 0;
+
+ return SCARD_S_SUCCESS;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenfactory.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : tokenfactory.h
+ Package: pcsc-lite
+ Author : David Corcoran
+ Date : 01/01/00
+ Purpose: This handles card abstraction attachment.
+
+********************************************************************/
+
+#ifndef __cardfactory_h__
+#define __cardfactory_h__
+
+#include "mscdefines.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef WIN32
+#ifndef MSC_SVC_DROPDIR
+#define MSC_SVC_DROPDIR TPSvcDropdir()
+#define MSC_SVC_DROPDIR_DEFAULT "/usr/libexec/SmartCardServices/services/"
+#define MSC_SVC_DROPDIR_ENV "MSC_SVC_DROPDIR"
+#endif
+#else
+#define MSC_SVC_DROPDIR "C:\\Program Files\\Muscle\\Services\\"
+#endif
+
+ const char *TPSvcDropdir(void);
+ MSCLong32 TPLoadToken(MSCLPTokenConnection);
+ MSCLong32 TPUnloadToken(MSCLPTokenConnection);
+ MSCLong32 TPBindFunctions(MSCLPTokenConnection);
+ MSCLong32 TPUnbindFunctions(MSCLPTokenConnection);
+ MSCLong32 TPSearchBundlesForAtr(MSCPUChar8 Atr, MSCULong32 Length,
+ MSCLPTokenInfo tokenInfo);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __cardfactory_h__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1775 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+#ifdef WIN32
+#include <malloc.h>
+#include <stdlib.h>
+#endif
+
+#define yy_create_buffer tp_create_buffer
+#define yy_delete_buffer tp_delete_buffer
+#define yy_scan_buffer tp_scan_buffer
+#define yy_scan_string tp_scan_string
+#define yy_scan_bytes tp_scan_bytes
+#define yy_flex_debug tp_flex_debug
+#define yy_init_buffer tp_init_buffer
+#define yy_flush_buffer tp_flush_buffer
+#define yy_load_buffer_state tp_load_buffer_state
+#define yy_switch_to_buffer tp_switch_to_buffer
+#define yyin tpin
+#define yyleng tpleng
+#define yylex tplex
+#define yyout tpout
+#define yyrestart tprestart
+#define yytext tptext
+#define yywrap tpwrap
+
+/*
+ * A lexical scanner generated by flex
+ */
+
+/*
+ * Scanner skeleton version: $Header:
+ * /home/cvsroot/muscle/PCSC/src/tokenparser.c,v 1.2 2002/03/30 20:59:07
+ * corcoran Exp $
+ */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+
+#include <stdio.h>
+
+/*
+ * cfront 1.2 defines "c_plusplus" instead of "__cplusplus"
+ */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif
+#endif
+
+#ifdef __cplusplus
+
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ * Use prototypes in function declarations.
+ */
+#define YY_USE_PROTOS
+
+/*
+ * The "const" storage-class-modifier is valid.
+ */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_PROTOS
+#define YY_USE_CONST
+
+#endif /* __STDC__ */
+#endif /* ! __cplusplus */
+
+#ifdef __TURBOC__
+#pragma warn -rch
+#pragma warn -use
+#include <io.h>
+#include <stdlib.h>
+#define YY_USE_CONST
+#define YY_USE_PROTOS
+#endif
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+#ifdef YY_USE_PROTOS
+#define YY_PROTO(proto) proto
+#else
+#define YY_PROTO(proto) ()
+#endif
+
+/*
+ * Returned upon end-of-file.
+ */
+#define YY_NULL 0
+
+/*
+ * Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative, we
+ * want to instead treat it as an 8-bit unsigned char, hence the double
+ * cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/*
+ * Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yy_start = 1 + 2 *
+
+/*
+ * Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/*
+ * Action number for EOF rule of a given start state.
+ */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/*
+ * Special action meaning "start processing a new file".
+ */
+#define YY_NEW_FILE yyrestart( yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/*
+ * Size of default input buffer.
+ */
+#define YY_BUF_SIZE 16384
+
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+
+extern int yyleng;
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+/*
+ * The funky do-while in the following #define is used to turn the
+ * definition int a single C statement (which needs a semi-colon
+ * terminator). This avoids problems with code like: if (
+ * condition_holds ) yyless( 5 ); else do_something_else(); Prior to
+ * using the do-while the compiler would get upset at the "else" because
+ * it interpreted the "if" statement as being all done when it reached the
+ * ';' after the yyless() call.
+ */
+
+/*
+ * Return all but the first 'n' matched characters back to the input
+ * stream.
+ */
+
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ *yy_cp = yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yytext_ptr )
+
+/*
+ * The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+typedef unsigned int yy_size_t;
+
+struct yy_buffer_state
+{
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /*
+ * Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /*
+ * Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /*
+ * Whether we "own" the buffer - i.e., we know we created it, and can
+ * realloc() it to grow it, and should free() it to delete it.
+ */
+ int yy_is_our_buffer;
+
+ /*
+ * Whether this is an "interactive" input source; if so, and if we're
+ * using stdio for input, then we want to use getc() instead of
+ * fread(), to make sure we stop fetching input after each newline.
+ */
+ int yy_is_interactive;
+
+ /*
+ * Whether we're considered to be at the beginning of a line. If so,
+ * '^' rules will be active on the next match, otherwise not.
+ */
+ int yy_at_bol;
+
+ /*
+ * Whether to try to fill the input buffer when we reach the end of
+ * it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /*
+ * When an EOF's been seen but there's still some text to process then
+ * we mark the buffer as YY_EOF_PENDING, to indicate that we shouldn't
+ * try reading from the input source any more. We might still have a
+ * bunch of tokens to match, though, because of possible backing-up.
+ * When we actually see the EOF, we change the status to "new" (via
+ * yyrestart()), so that the user can continue scanning by just
+ * pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+};
+
+static YY_BUFFER_STATE yy_current_buffer = 0;
+
+/*
+ * We provide macros for accessing buffer states in case in the future we
+ * want to put the buffer states in a more general "scanner state".
+ */
+#define YY_CURRENT_BUFFER yy_current_buffer
+
+/*
+ * yy_hold_char holds the character lost when yytext is formed.
+ */
+static char yy_hold_char;
+
+static int yy_n_chars; /* number of characters read into
+ * yy_ch_buf */
+
+int yyleng;
+
+/*
+ * Points to current character in buffer.
+ */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 1; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/*
+ * Flag which is used to allow yywrap()'s to do buffer switches instead of
+ * setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart YY_PROTO((FILE * input_file));
+
+void yy_switch_to_buffer YY_PROTO((YY_BUFFER_STATE new_buffer));
+void yy_load_buffer_state YY_PROTO((void));
+YY_BUFFER_STATE yy_create_buffer YY_PROTO((FILE * file, int size));
+void yy_delete_buffer YY_PROTO((YY_BUFFER_STATE b));
+void yy_init_buffer YY_PROTO((YY_BUFFER_STATE b, FILE * file));
+void yy_flush_buffer YY_PROTO((YY_BUFFER_STATE b));
+#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
+
+YY_BUFFER_STATE yy_scan_buffer YY_PROTO((char *base, yy_size_t size));
+YY_BUFFER_STATE yy_scan_string YY_PROTO((yyconst char *yy_str));
+YY_BUFFER_STATE yy_scan_bytes YY_PROTO((yyconst char *bytes, int len));
+
+static void *yy_flex_alloc YY_PROTO((yy_size_t));
+static void *yy_flex_realloc YY_PROTO((void *, yy_size_t));
+static void yy_flex_free YY_PROTO((void *));
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! yy_current_buffer ) \
+ yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
+ yy_current_buffer->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+
+typedef unsigned char YY_CHAR;
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+typedef int yy_state_type;
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state YY_PROTO((void));
+static yy_state_type yy_try_NUL_trans YY_PROTO((yy_state_type
+ current_state));
+static int yy_get_next_buffer YY_PROTO((void));
+static void yy_fatal_error YY_PROTO((yyconst char msg[]));
+
+/*
+ * Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yytext_ptr = yy_bp; \
+ yyleng = (int) (yy_cp - yy_bp); \
+ yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 7
+#define YY_END_OF_BUFFER 8
+static yyconst short int yy_accept[39] = { 0,
+ 0, 0, 8, 6, 4, 2, 1, 6, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 0, 0, 0, 0, 0, 0, 5, 0
+};
+
+static yyconst int yy_ec[256] = { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 4, 4, 5, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 6, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 4, 1, 8,
+ 4, 9, 4, 4, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 1, 1, 1, 4, 4, 1, 11, 11, 11, 11,
+
+ 12, 11, 13, 11, 14, 11, 15, 11, 11, 16,
+ 11, 11, 11, 17, 18, 19, 11, 11, 11, 11,
+ 20, 11, 1, 1, 1, 4, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+};
+
+static yyconst int yy_meta[21] = { 0,
+ 1, 2, 3, 4, 4, 4, 2, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+static yyconst short int yy_base[43] = { 0,
+ 0, 7, 49, 50, 50, 50, 0, 1, 0, 36,
+ 28, 26, 28, 35, 29, 0, 26, 33, 27, 33,
+ 29, 22, 0, 24, 27, 14, 27, 23, 13, 50,
+ 10, 9, 4, 1, 0, 2, 50, 50, 19, 23,
+ 2, 26
+};
+
+static yyconst short int yy_def[43] = { 0,
+ 39, 39, 38, 38, 38, 38, 40, 38, 40, 38,
+ 38, 38, 38, 38, 38, 41, 38, 41, 38, 38,
+ 38, 38, 42, 38, 42, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 0, 38, 38,
+ 38, 38
+};
+
+static yyconst short int yy_nxt[71] = { 0,
+ 38, 5, 6, 18, 7, 38, 38, 8, 5, 6,
+ 37, 7, 36, 38, 8, 10, 35, 34, 11, 4,
+ 4, 4, 4, 9, 9, 33, 9, 25, 32, 25,
+ 31, 30, 29, 28, 27, 26, 24, 23, 22, 21,
+ 20, 19, 17, 16, 15, 14, 13, 12, 38, 3,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38
+};
+
+static yyconst short int yy_chk[71] = { 0,
+ 0, 1, 1, 41, 1, 0, 0, 1, 2, 2,
+ 36, 2, 35, 0, 2, 8, 34, 33, 8, 39,
+ 39, 39, 39, 40, 40, 32, 40, 42, 31, 42,
+ 29, 28, 27, 26, 25, 24, 22, 21, 20, 19,
+ 18, 17, 15, 14, 13, 12, 11, 10, 3, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38,
+ 38, 38, 38, 38, 38, 38, 38, 38, 38, 38
+};
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+/*
+ * The intent behind this definition is that it'll catch any uses of
+ * REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "tokenparser.l"
+#define INITIAL 0
+/*****************************************************************
+
+ File : configfile.ll
+ Author : David Corcoran
+ Date : February 12, 1999 modified 7/28/99
+ Purpose: Reads lexical config files and updates database.
+ See http://www.linuxnet.com for more information.
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+
+******************************************************************/
+#line 14 "tokenparser.l"
+
+void tpevalToken(char *pcToken, int tokType);
+
+static char *pcDesiredKey = 0;
+static char pcKey[200];
+static char pcValue[200];
+static char pcFinValue[200];
+static int valueIndex = 0;
+static int desiredIndex = 0;
+
+void tperrorCheck(char *pcToken_error);
+
+#line 429 "lex.tp.c"
+
+/*
+ * Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap YY_PROTO((void));
+#else
+extern int yywrap YY_PROTO((void));
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+static void yyunput YY_PROTO((int c, char *buf_ptr));
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy YY_PROTO((char *, yyconst char *, int));
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen YY_PROTO((yyconst char *));
+#endif
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+static int yyinput YY_PROTO((void));
+#else
+static int input YY_PROTO((void));
+#endif
+#endif
+
+#if YY_STACK_USED
+static int yy_start_stack_ptr = 0;
+static int yy_start_stack_depth = 0;
+static int *yy_start_stack = 0;
+#ifndef YY_NO_PUSH_STATE
+static void yy_push_state YY_PROTO((int new_state));
+#endif
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state YY_PROTO((void));
+#endif
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state YY_PROTO((void));
+#endif
+
+#else
+#define YY_NO_PUSH_STATE 1
+#define YY_NO_POP_STATE 1
+#define YY_NO_TOP_STATE 1
+#endif
+
+#ifdef YY_MALLOC_DECL
+YY_MALLOC_DECL
+#else
+#if __STDC__
+#ifndef __cplusplus
+#include <stdlib.h>
+#endif
+#else
+/*
+ * Just try to get by without declaring the routines. This will fail
+ * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
+ * or sizeof(void*) != sizeof(int).
+ */
+#endif
+#endif
+
+/*
+ * Amount of stuff to slurp up with each read.
+ */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/*
+ * Copy whatever the last rule matched to the standard output.
+ */
+
+#ifndef ECHO
+/*
+ * This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/*
+ * Gets input and stuffs it into "buf". number of characters read, or
+ * YY_NULL, is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( yy_current_buffer->yy_is_interactive ) \
+ { \
+ int c = '*', n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
+ && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" );
+#endif
+
+/*
+ * No semi-colon after return; correct usage is to write "yyterminate();"
+ * - we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/*
+ * Number of entries by which start-condition stack grows.
+ */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/*
+ * Report a fatal error.
+ */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/*
+ * Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL int yylex YY_PROTO(( void ))
+#endif
+
+/*
+ * Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/*
+ * Code executed at the end of each rule.
+ */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 28 "tokenparser.l"
+
+#line 583 "lex.tp.c"
+
+ if (yy_init)
+ {
+ yy_init = 0;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if (!yy_start)
+ yy_start = 1; /* first start state */
+
+ if (!yyin)
+ yyin = stdin;
+
+ if (!yyout)
+ yyout = stdout;
+
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_load_buffer_state();
+ }
+
+ while (1) /* loops until end-of-file is reached */
+ {
+ yy_cp = yy_c_buf_p;
+
+ /*
+ * Support of yytext.
+ */
+ *yy_cp = yy_hold_char;
+
+ /*
+ * yy_bp points to the position in yy_ch_buf of the start of the
+ * current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yy_start;
+ yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] !=
+ yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 39)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while (yy_base[yy_current_state] != 50);
+
+ yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if (yy_act == 0)
+ { /* have to back up */
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+ do_action: /* This label is used only to access EOF actions. */
+
+ switch (yy_act)
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /*
+ * undo the effects of YY_DO_BEFORE_ACTION
+ */
+ *yy_cp = yy_hold_char;
+ yy_cp = yy_last_accepting_cpos;
+ yy_current_state = yy_last_accepting_state;
+ goto yy_find_action;
+
+ case 1:
+ YY_RULE_SETUP
+#line 30 "tokenparser.l"
+ {
+ }
+ YY_BREAK case 2:
+ YY_RULE_SETUP
+#line 31 "tokenparser.l"
+ {
+ }
+ YY_BREAK case 3:
+ YY_RULE_SETUP
+#line 32 "tokenparser.l"
+ {
+ valueIndex = 0;
+ tpevalToken(yytext, 1);
+ }
+ YY_BREAK case 4:
+ YY_RULE_SETUP
+#line 33 "tokenparser.l"
+ {
+ }
+ YY_BREAK case 5:
+ YY_RULE_SETUP
+#line 34 "tokenparser.l"
+ {
+ tpevalToken(yytext, 2);
+ valueIndex += 1;
+ }
+ YY_BREAK case 6:
+ YY_RULE_SETUP
+#line 35 "tokenparser.l"
+ {
+ tperrorCheck(yytext);
+ }
+ YY_BREAK case 7:
+ YY_RULE_SETUP
+#line 36 "tokenparser.l"
+ ECHO;
+ YY_BREAK
+#line 701 "lex.tp.c"
+ case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /*
+ * Amount of text matched not including the EOB char.
+ */
+ int yy_amount_of_matched_text =
+ (int) (yy_cp - yytext_ptr) - 1;
+
+ /*
+ * Undo the effects of YY_DO_BEFORE_ACTION.
+ */
+ *yy_cp = yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+ if (yy_current_buffer->yy_buffer_status ==
+ YY_BUFFER_NEW)
+ {
+ /*
+ * We're scanning a new file or input source. It's
+ * possible that this happened because the user just
+ * pointed yyin at a new source and called yylex().
+ * If so, then we have to assure consistency between
+ * yy_current_buffer and our globals. Here is the
+ * right place to do so, because this is the first
+ * action (other than possibly a back-up) that will
+ * match for the new input source.
+ */
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yy_current_buffer->yy_input_file = yyin;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /*
+ * Note that here we test for yy_c_buf_p "<=" to the
+ * position of the first EOB in the buffer, since
+ * yy_c_buf_p will already have been incremented past the
+ * NUL character (since all states make transitions on EOB
+ * to the end-of-buffer state). Contrast this with the
+ * test in input().
+ */
+ if (yy_c_buf_p <=
+ &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ /*
+ * Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it for us
+ * because it doesn't know how to deal with the
+ * possibility of jamming (and we don't want to build
+ * jamming into it because then it will run more
+ * slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans(yy_current_state);
+
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+
+ if (yy_next_state)
+ {
+ /*
+ * Consume the NUL.
+ */
+ yy_cp = ++yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else
+ switch (yy_get_next_buffer())
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yy_did_buffer_switch_on_eof = 0;
+
+ if (yywrap())
+ {
+ /*
+ * Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up yy_c_buf_p so
+ * that if some total hoser (like flex
+ * itself) wants to call the scanner after
+ * we return the YY_NULL, it'll still work
+ * - another YY_NULL will get returned.
+ */
+ yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p =
+ yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yy_c_buf_p =
+ &yy_current_buffer->yy_ch_buf[yy_n_chars];
+
+ yy_current_state = yy_get_previous_state();
+
+ yy_cp = yy_c_buf_p;
+ yy_bp = yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR
+ ("fatal flex scanner internal error--no action found");
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/*
+ * yy_get_next_buffer - try to read in a new buffer Returns a code
+ * representing an action: EOB_ACT_LAST_MATCH - EOB_ACT_CONTINUE_SCAN -
+ * continue scanning from current position EOB_ACT_END_OF_FILE - end of
+ * file
+ */
+
+static int yy_get_next_buffer()
+{
+ register char *dest = yy_current_buffer->yy_ch_buf;
+ register char *source = yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if (yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1])
+ YY_FATAL_ERROR
+ ("fatal flex scanner internal error--end of buffer missed");
+
+ if (yy_current_buffer->yy_fill_buffer == 0)
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if (yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1)
+ {
+ /*
+ * We matched a single character, the EOB, so treat this as a
+ * final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /*
+ * We matched some text prior to the EOB, first process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /*
+ * Try to read more data.
+ */
+
+ /*
+ * First move last chars to start of buffer.
+ */
+ number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+
+ for (i = 0; i < number_to_move; ++i)
+ *(dest++) = *(source++);
+
+ if (yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING)
+ /*
+ * don't do the read, it's not guaranteed to return an EOF, just
+ * force an EOF
+ */
+ yy_current_buffer->yy_n_chars = yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ yy_current_buffer->yy_buf_size - number_to_move - 1;
+
+ while (num_to_read <= 0)
+ { /* Not enough room in the buffer - grow it. */
+#ifdef YY_USES_REJECT
+ YY_FATAL_ERROR
+ ("input buffer overflow, can't enlarge buffer because scanner uses REJECT");
+#else
+
+ /*
+ * just a shorter name for the current buffer
+ */
+ YY_BUFFER_STATE b = yy_current_buffer;
+
+ int yy_c_buf_p_offset = (int) (yy_c_buf_p - b->yy_ch_buf);
+
+ if (b->yy_is_our_buffer)
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if (new_size <= 0)
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /*
+ * Include room in for 2 EOB chars.
+ */
+ yy_flex_realloc((void *) b->yy_ch_buf,
+ b->yy_buf_size + 2);
+ } else
+ /*
+ * Can't grow it, we don't own it.
+ */
+ b->yy_ch_buf = 0;
+
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR
+ ("fatal error - scanner input buffer overflow");
+
+ yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = yy_current_buffer->yy_buf_size -
+ number_to_move - 1;
+#endif
+ }
+
+ if (num_to_read > YY_READ_BUF_SIZE)
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /*
+ * Read in more data.
+ */
+ YY_INPUT((&yy_current_buffer->yy_ch_buf[number_to_move]),
+ yy_n_chars, num_to_read);
+
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ if (yy_n_chars == 0)
+ {
+ if (number_to_move == YY_MORE_ADJ)
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ yy_current_buffer->yy_buffer_status = YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ yy_n_chars += number_to_move;
+ yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/*
+ * yy_get_previous_state - get the state just before the EOB char was
+ * reached
+ */
+
+static yy_state_type yy_get_previous_state()
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = yy_start;
+
+ for (yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp)
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] !=
+ yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 39)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/*
+ * yy_try_NUL_trans - try to make a transition on the NUL character
+ * synopsis next_state = yy_try_NUL_trans( current_state );
+ */
+
+#ifdef YY_USE_PROTOS
+static yy_state_type yy_try_NUL_trans(yy_state_type yy_current_state)
+#else
+static yy_state_type yy_try_NUL_trans(yy_current_state)
+ yy_state_type yy_current_state;
+#endif
+{
+ register int yy_is_jam;
+ register char *yy_cp = yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if (yy_accept[yy_current_state])
+ {
+ yy_last_accepting_state = yy_current_state;
+ yy_last_accepting_cpos = yy_cp;
+ }
+ while (yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state)
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if (yy_current_state >= 39)
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state =
+ yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 38);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+#ifdef YY_USE_PROTOS
+static void yyunput(int c, register char *yy_bp)
+#else
+static void yyunput(c, yy_bp)
+ int c;
+ register char *yy_bp;
+#endif
+{
+ register char *yy_cp = yy_c_buf_p;
+
+ /*
+ * undo effects of setting up yytext
+ */
+ *yy_cp = yy_hold_char;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ { /* need to shift things up to make room */
+ /*
+ * +2 for EOB chars.
+ */
+ register int number_to_move = yy_n_chars + 2;
+ register char *dest =
+ &yy_current_buffer->yy_ch_buf[yy_current_buffer->yy_buf_size +
+ 2];
+ register char *source =
+ &yy_current_buffer->yy_ch_buf[number_to_move];
+
+ while (source > yy_current_buffer->yy_ch_buf)
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ yy_current_buffer->yy_n_chars =
+ yy_n_chars = yy_current_buffer->yy_buf_size;
+
+ if (yy_cp < yy_current_buffer->yy_ch_buf + 2)
+ YY_FATAL_ERROR("flex scanner push-back overflow");
+ }
+
+ *--yy_cp = (char) c;
+
+ yytext_ptr = yy_bp;
+ yy_hold_char = *yy_cp;
+ yy_c_buf_p = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifdef __cplusplus
+static int yyinput()
+#else
+static int input()
+#endif
+{
+ int c;
+
+ *yy_c_buf_p = yy_hold_char;
+
+ if (*yy_c_buf_p == YY_END_OF_BUFFER_CHAR)
+ {
+ /*
+ * yy_c_buf_p now points to the character we want to return. If
+ * this occurs *before* the EOB characters, then it's a valid NUL;
+ * if not, then we've hit the end of the buffer.
+ */
+ if (yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars])
+ /*
+ * This was really a NUL.
+ */
+ *yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yy_c_buf_p - yytext_ptr;
+ ++yy_c_buf_p;
+
+ switch (yy_get_next_buffer())
+ {
+ case EOB_ACT_LAST_MATCH:
+ /*
+ * This happens because yy_g_n_b() sees that we've
+ * accumulated a token and flags that we need to try
+ * matching the token before proceeding. But for input(),
+ * there's no matching to consider. So convert the
+ * EOB_ACT_LAST_MATCH to EOB_ACT_END_OF_FILE.
+ */
+
+ /*
+ * Reset buffer status.
+ */
+ yyrestart(yyin);
+
+ /*
+ * fall through
+ */
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if (yywrap())
+ return EOF;
+
+ if (!yy_did_buffer_switch_on_eof)
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yy_c_buf_p = yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
+ *yy_c_buf_p = '\0'; /* preserve yytext */
+ yy_hold_char = *++yy_c_buf_p;
+
+ return c;
+}
+
+#ifdef YY_USE_PROTOS
+void yyrestart(FILE * input_file)
+#else
+void yyrestart(input_file)
+ FILE *input_file;
+#endif
+{
+ if (!yy_current_buffer)
+ yy_current_buffer = yy_create_buffer(yyin, YY_BUF_SIZE);
+
+ yy_init_buffer(yy_current_buffer, input_file);
+ yy_load_buffer_state();
+}
+
+#ifdef YY_USE_PROTOS
+void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer)
+#else
+void yy_switch_to_buffer(new_buffer)
+ YY_BUFFER_STATE new_buffer;
+#endif
+{
+ if (yy_current_buffer == new_buffer)
+ return;
+
+ if (yy_current_buffer)
+ {
+ /*
+ * Flush out information for old buffer.
+ */
+ *yy_c_buf_p = yy_hold_char;
+ yy_current_buffer->yy_buf_pos = yy_c_buf_p;
+ yy_current_buffer->yy_n_chars = yy_n_chars;
+ }
+
+ yy_current_buffer = new_buffer;
+ yy_load_buffer_state();
+
+ /*
+ * We don't actually know whether we did this switch during EOF
+ * (yywrap()) processing, but the only time this flag is looked at is
+ * after yywrap() is called, so it's safe to go ahead and always set
+ * it.
+ */
+ yy_did_buffer_switch_on_eof = 1;
+}
+
+#ifdef YY_USE_PROTOS
+void yy_load_buffer_state(void)
+#else
+void yy_load_buffer_state()
+#endif
+{
+ yy_n_chars = yy_current_buffer->yy_n_chars;
+ yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
+ yyin = yy_current_buffer->yy_input_file;
+ yy_hold_char = *yy_c_buf_p;
+}
+
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_create_buffer(FILE * file, int size)
+#else
+YY_BUFFER_STATE yy_create_buffer(file, size)
+ FILE *file;
+ int size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_buf_size = size;
+
+ /*
+ * yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yy_flex_alloc(b->yy_buf_size + 2);
+ if (!b->yy_ch_buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_create_buffer()");
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b, file);
+
+ return b;
+}
+
+#ifdef YY_USE_PROTOS
+void yy_delete_buffer(YY_BUFFER_STATE b)
+#else
+void yy_delete_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+{
+ if (!b)
+ return;
+
+ if (b == yy_current_buffer)
+ yy_current_buffer = (YY_BUFFER_STATE) 0;
+
+ if (b->yy_is_our_buffer)
+ yy_flex_free((void *) b->yy_ch_buf);
+
+ yy_flex_free((void *) b);
+}
+
+#ifndef YY_ALWAYS_INTERACTIVE
+#ifndef YY_NEVER_INTERACTIVE
+extern int isatty YY_PROTO((int));
+#endif
+#endif
+
+#ifdef YY_USE_PROTOS
+void yy_init_buffer(YY_BUFFER_STATE b, FILE * file)
+#else
+void yy_init_buffer(b, file)
+ YY_BUFFER_STATE b;
+ FILE *file;
+#endif
+
+{
+ yy_flush_buffer(b);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+#if YY_ALWAYS_INTERACTIVE
+ b->yy_is_interactive = 1;
+#else
+#if YY_NEVER_INTERACTIVE
+ b->yy_is_interactive = 0;
+#else
+ b->yy_is_interactive = file ? (isatty(fileno(file)) > 0) : 0;
+#endif
+#endif
+}
+
+#ifdef YY_USE_PROTOS
+void yy_flush_buffer(YY_BUFFER_STATE b)
+#else
+void yy_flush_buffer(b)
+ YY_BUFFER_STATE b;
+#endif
+
+{
+ if (!b)
+ return;
+
+ b->yy_n_chars = 0;
+
+ /*
+ * We always need two end-of-buffer characters. The first causes a
+ * transition to the end-of-buffer state. The second causes a jam in
+ * that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if (b == yy_current_buffer)
+ yy_load_buffer_state();
+}
+
+#ifndef YY_NO_SCAN_BUFFER
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_buffer(char *base, yy_size_t size)
+#else
+YY_BUFFER_STATE yy_scan_buffer(base, size)
+ char *base;
+ yy_size_t size;
+#endif
+{
+ YY_BUFFER_STATE b;
+
+ if (size < 2 ||
+ base[size - 2] != YY_END_OF_BUFFER_CHAR ||
+ base[size - 1] != YY_END_OF_BUFFER_CHAR)
+ /*
+ * They forgot to leave room for the EOB's.
+ */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yy_flex_alloc(sizeof(struct yy_buffer_state));
+ if (!b)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_buffer()");
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b);
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_SCAN_STRING
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_string(yyconst char *yy_str)
+#else
+YY_BUFFER_STATE yy_scan_string(yy_str)
+ yyconst char *yy_str;
+#endif
+{
+ int len;
+ for (len = 0; yy_str[len]; ++len)
+ ;
+
+ return yy_scan_bytes(yy_str, len);
+}
+#endif
+
+#ifndef YY_NO_SCAN_BYTES
+#ifdef YY_USE_PROTOS
+YY_BUFFER_STATE yy_scan_bytes(yyconst char *bytes, int len)
+#else
+YY_BUFFER_STATE yy_scan_bytes(bytes, len)
+ yyconst char *bytes;
+ int len;
+#endif
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /*
+ * Get memory for full buffer, including space for trailing EOB's.
+ */
+ n = len + 2;
+ buf = (char *) yy_flex_alloc(n);
+ if (!buf)
+ YY_FATAL_ERROR("out of dynamic memory in yy_scan_bytes()");
+
+ for (i = 0; i < len; ++i)
+ buf[i] = bytes[i];
+
+ buf[len] = buf[len + 1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf, n);
+ if (!b)
+ YY_FATAL_ERROR("bad buffer in yy_scan_bytes()");
+
+ /*
+ * It's okay to grow etc. this buffer, and we should throw it away
+ * when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+#endif
+
+#ifndef YY_NO_PUSH_STATE
+#ifdef YY_USE_PROTOS
+static void yy_push_state(int new_state)
+#else
+static void yy_push_state(new_state)
+ int new_state;
+#endif
+{
+ if (yy_start_stack_ptr >= yy_start_stack_depth)
+ {
+ yy_size_t new_size;
+
+ yy_start_stack_depth += YY_START_STACK_INCR;
+ new_size = yy_start_stack_depth * sizeof(int);
+
+ if (!yy_start_stack)
+ yy_start_stack = (int *) yy_flex_alloc(new_size);
+
+ else
+ yy_start_stack = (int *) yy_flex_realloc(
+ (void *) yy_start_stack, new_size);
+
+ if (!yy_start_stack)
+ YY_FATAL_ERROR
+ ("out of memory expanding start-condition stack");
+ }
+
+ yy_start_stack[yy_start_stack_ptr++] = YY_START;
+
+ BEGIN(new_state);
+}
+#endif
+
+#ifndef YY_NO_POP_STATE
+static void yy_pop_state()
+{
+ if (--yy_start_stack_ptr < 0)
+ YY_FATAL_ERROR("start-condition stack underflow");
+
+ BEGIN(yy_start_stack[yy_start_stack_ptr]);
+}
+#endif
+
+#ifndef YY_NO_TOP_STATE
+static int yy_top_state()
+{
+ return yy_start_stack[yy_start_stack_ptr - 1];
+}
+#endif
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+#ifdef YY_USE_PROTOS
+static void yy_fatal_error(yyconst char msg[])
+#else
+static void yy_fatal_error(msg)
+ char msg[];
+#endif
+{
+ (void) fprintf(stderr, "%s\n", msg);
+ exit(YY_EXIT_FAILURE);
+}
+
+/*
+ * Redefine yyless() so it works in section 3 code.
+ */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ yytext[yyleng] = yy_hold_char; \
+ yy_c_buf_p = yytext + n; \
+ yy_hold_char = *yy_c_buf_p; \
+ *yy_c_buf_p = '\0'; \
+ yyleng = n; \
+ } \
+ while ( 0 )
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+#ifdef YY_USE_PROTOS
+static void yy_flex_strncpy(char *s1, yyconst char *s2, int n)
+#else
+static void yy_flex_strncpy(s1, s2, n)
+ char *s1;
+ yyconst char *s2;
+ int n;
+#endif
+{
+ register int i;
+ for (i = 0; i < n; ++i)
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+#ifdef YY_USE_PROTOS
+static int yy_flex_strlen(yyconst char *s)
+#else
+static int yy_flex_strlen(s)
+ yyconst char *s;
+#endif
+{
+ register int n;
+ for (n = 0; s[n]; ++n)
+ ;
+
+ return n;
+}
+#endif
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_alloc(yy_size_t size)
+#else
+static void *yy_flex_alloc(size)
+ yy_size_t size;
+#endif
+{
+ return (void *) malloc(size);
+}
+
+#ifdef YY_USE_PROTOS
+static void *yy_flex_realloc(void *ptr, yy_size_t size)
+#else
+static void *yy_flex_realloc(ptr, size)
+ void *ptr;
+ yy_size_t size;
+#endif
+{
+ /*
+ * The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those that use
+ * void* generic pointers. It works with the latter because both ANSI
+ * C and C++ allow castless assignment from any pointer type to void*,
+ * and deal with argument conversions as though doing an assignment.
+ */
+ return (void *) realloc((char *) ptr, size);
+}
+
+#ifdef YY_USE_PROTOS
+static void yy_flex_free(void *ptr)
+#else
+static void yy_flex_free(ptr)
+ void *ptr;
+#endif
+{
+ free(ptr);
+}
+
+#if YY_MAIN
+int main()
+{
+ yylex();
+ return 0;
+}
+#endif
+#line 36 "tokenparser.l"
+
+#include <stdio.h>
+#include <string.h>
+#include "debuglog.h"
+
+#ifndef WIN32
+#include "config.h"
+#else
+#include "../win32/win32_config.h"
+#endif
+
+int yywrap()
+{
+ return 1;
+}
+
+void tpevalToken(char *pcToken, int tokType)
+{
+
+ int len;
+ len = 0;
+
+ if (tokType == 1)
+ {
+ for (len = 5; pcToken[len] != '<'; len++) ;
+ strncpy(pcKey, &pcToken[5], len - 5);
+ pcKey[len - 5] = 0;
+ }
+
+ if (tokType == 2)
+ {
+ for (len = 8; pcToken[len] != '<'; len++) ;
+ strncpy(pcValue, &pcToken[8], len - 8);
+ pcValue[len - 8] = 0;
+ if (strcmp(pcKey, pcDesiredKey) == 0)
+ {
+ if (desiredIndex == valueIndex)
+ {
+ strcpy(pcFinValue, pcValue);
+ }
+ }
+ }
+
+}
+
+void tperrorCheck(char *token_error)
+{
+}
+
+int LTPBundleFindValueWithKey(char *fileName, char *tokenKey,
+ char *tokenValue, int tokenIndice)
+{
+
+ FILE *file;
+ file = 0;
+
+ desiredIndex = tokenIndice;
+ pcDesiredKey = tokenKey;
+ pcFinValue[0] = 0;
+
+ file = fopen(fileName, "r");
+
+ if (!file)
+ {
+ DebugLogB("Could not open bundle file : %s\n", fileName);
+ return 1;
+ }
+
+ yyin = file;
+
+ do
+ {
+ yylex();
+ }
+ while (!feof(file));
+
+ if (pcFinValue[0] == 0)
+ {
+ if (tokenIndice == 0)
+ {
+ /*
+ * Not defined at all
+ */
+ DebugLogB("Value/Key not defined for: %s\n", tokenKey);
+ }
+ fclose(file);
+ return -1;
+ } else
+ {
+ strcpy(tokenValue, pcFinValue);
+ fclose(file);
+ return 0;
+ }
+
+ fclose(file);
+ return 0;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.l
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.l (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/tokenparser.l 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,114 @@
+/*****************************************************************
+
+ File : configfile.ll
+ Author : David Corcoran
+ Date : February 12, 1999 modified 7/28/99
+ Purpose: Reads lexical config files and updates database.
+ See http://www.linuxnet.com for more information.
+ License: Copyright (C) 1999 David Corcoran
+ <corcoran at linuxnet.com>
+
+******************************************************************/
+
+%{
+
+void tpevalToken( char *pcToken, int tokType );
+
+static char *pcDesiredKey = 0;
+static char pcKey[200];
+static char pcValue[200];
+static char pcFinValue[200];
+static int valueIndex = 0;
+static int desiredIndex = 0;
+
+void tperrorCheck ( char *pcToken_error );
+
+%}
+
+%%
+
+#.* {}
+"\n" {}
+\<key\>([A-Z]|[a-z]|[0-9]|[ \t])+\<\/key\> { valueIndex = 0; tpevalToken(yytext, 1); }
+[ \t] {}
+\<string\>([A-Z]|[a-z]|[0-9]|[ \t]|[!@#$%^&*()\-+/_\:?.,=~'"])+\<\/string\> {tpevalToken(yytext, 2); valueIndex += 1;}
+. { tperrorCheck( yytext ); }
+%%
+
+#include <stdio.h>
+#include <string.h>
+#include "debuglog.h"
+#include "config.h"
+
+int yywrap() {
+ return 1;
+}
+
+
+void tpevalToken( char *pcToken, int tokType ) {
+
+ int len;
+ len = 0;
+
+ if ( tokType == 1 ) {
+ for (len=5; pcToken[len] != '<'; len++);
+ strncpy(pcKey, &pcToken[5], len - 5);
+ pcKey[len-5] = 0;
+ }
+
+ if ( tokType == 2 ) {
+ for (len=8; pcToken[len] != '<'; len++);
+ strncpy(pcValue, &pcToken[8], len - 8);
+ pcValue[len-8] = 0;
+ if ( strcmp(pcKey, pcDesiredKey) == 0 ) {
+ if ( desiredIndex == valueIndex ) {
+ strcpy(pcFinValue, pcValue);
+ }
+ }
+ }
+
+
+}
+
+void tperrorCheck ( char *token_error ) { }
+
+int LTPBundleFindValueWithKey(char *fileName, char *tokenKey,
+ char *tokenValue, int tokenIndice) {
+
+ FILE *file;
+ file = 0;
+
+ desiredIndex = tokenIndice;
+ pcDesiredKey = tokenKey;
+ pcFinValue[0] = 0;
+
+ file = fopen(fileName, "r");
+
+ if (!file) {
+ DebugLogC( "Could not open bundle file : %s\n", fileName );
+ return 1;
+ }
+
+ yyin = file;
+
+ do {
+ yylex();
+ } while (!feof(file));
+
+ if ( pcFinValue[0] == 0 ) {
+ if ( tokenIndice == 0 ) {
+ /* Not defined at all */
+ DebugLogC( "Value/Key not defined for: %s\n", tokenKey );
+ }
+ fclose(file);
+ return -1;
+ } else {
+ strcpy(tokenValue, pcFinValue);
+ fclose(file);
+ return 0;
+ }
+
+ fclose(file);
+ return 0;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/utils/bundleTool.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/utils/bundleTool.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/utils/bundleTool.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : bundleTool.c
+ Package: MuscleCard Framework
+ Author : David Corcoran
+ Date : 03/11/01
+ License: Copyright (C) 2002 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This automatically updates the Info.plist
+
+ You may not remove this header from this file
+ without prior permission from the author.
+
+$Id: bundleTool.c,v 1.2 2003/02/13 20:06:36 ghoo Exp $
+
+********************************************************************/
+
+#include "wintypes.h"
+#include "winscard.h"
+#include "tokenfactory.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+/*
+ * End of personalization
+ */
+
+#define CHECK_ERR(cond, msg) { if (cond) { \
+ printf("Error: %s\n", msg); return -1; } }
+
+int main(int argc, char **argv)
+{
+
+ LONG rv;
+ SCARDCONTEXT hContext;
+ SCARD_READERSTATE_A rgReaderStates;
+ DWORD readerListSize;
+ struct stat statBuffer;
+ char spAtrValue[100];
+ char chosenInfoPlist[1024];
+ char *readerList;
+ char *restFile;
+ char atrInsertion[256];
+ FILE *fp;
+ DIR *bundleDir;
+ struct dirent *currBundle;
+ int i, p;
+ int userChoice;
+ int totalBundles;
+ int filePosition;
+ int restFileSize;
+ int restOffset;
+ int getsSize;
+
+ if (argc > 1)
+ {
+ printf("Invalid arguments\n");
+ printf("./bundleTool\n");
+ return -1;
+ }
+
+ currBundle = 0;
+
+ bundleDir = opendir(MSC_SVC_DROPDIR);
+ CHECK_ERR(bundleDir == 0, "Could not open services directory.");
+
+ printf("Select the approprate token driver:\n");
+ printf("-----------------------------------\n");
+
+ i = 1;
+ totalBundles = 0;
+
+ while ((currBundle = readdir(bundleDir)) != 0)
+ {
+ if (strstr(currBundle->d_name, ".bundle") != 0)
+ {
+ printf(" %d. %s\n", i++, currBundle->d_name);
+ totalBundles += 1;
+ }
+ }
+ printf("-----------------------------------\n");
+
+ if (totalBundles == 0)
+ {
+ printf("No services are present - exiting.\n");
+ return 1;
+ }
+
+ do
+ {
+ printf("Enter the number: ");
+ scanf("%d", &userChoice);
+ }
+ while (userChoice < 1 && userChoice > totalBundles);
+
+ closedir(bundleDir);
+
+ bundleDir = opendir(MSC_SVC_DROPDIR);
+ CHECK_ERR(bundleDir == 0, "Could not open services directory.");
+ CHECK_ERR(bundleDir == 0, MSC_SVC_DROPDIR);
+
+ do
+ {
+ if ((currBundle = readdir(bundleDir)) != 0)
+ {
+ if (strstr(currBundle->d_name, ".bundle") != 0)
+ {
+ userChoice -= 1;
+ }
+ }
+ }
+ while (userChoice != 0);
+
+ snprintf(chosenInfoPlist, sizeof(chosenInfoPlist),
+ "%s%s/Contents/Info.plist", MSC_SVC_DROPDIR, currBundle->d_name);
+ closedir(bundleDir);
+ printf("\n");
+
+ rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, 0, 0, &hContext);
+ CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardEstablishContext Failed");
+
+ readerListSize = 0;
+ rv = SCardListReaders(hContext, 0, 0, &readerListSize);
+ CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardListReaders Failed");
+
+ readerList = (char *) malloc(sizeof(char) * readerListSize);
+ CHECK_ERR(readerList == 0, "Malloc Failed");
+
+ rv = SCardListReaders(hContext, 0, readerList, &readerListSize);
+ CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardListReaders Alloc Failed");
+
+ printf("Insert your token in: %s\n", readerList);
+
+ rgReaderStates.szReader = readerList;
+ rgReaderStates.dwCurrentState = SCARD_STATE_EMPTY;
+
+ rv = SCardGetStatusChange(hContext, INFINITE, &rgReaderStates, 1);
+ CHECK_ERR(rv != SCARD_S_SUCCESS, "PC/SC SCardGetStatusChange Failed");
+
+ p = 0;
+ for (i = 0; i < rgReaderStates.cbAtr; i++)
+ {
+ sprintf(&spAtrValue[p], "%02X", rgReaderStates.rgbAtr[i]);
+ p += 2;
+ }
+ printf("\n");
+
+ snprintf(atrInsertion, sizeof(atrInsertion),
+ " <string>%s</string>\n", spAtrValue);
+
+ fp = fopen(chosenInfoPlist, "r+");
+ if (fp == 0)
+ {
+ printf("Could not open %s\n", chosenInfoPlist);
+ }
+ CHECK_ERR(fp == 0, "Opening of Info.plist failed.");
+
+ rv = stat(chosenInfoPlist, &statBuffer);
+ CHECK_ERR(rv != 0, "File Stat failed\n");
+
+ restFileSize = statBuffer.st_size + strlen(atrInsertion);
+ restFile = (char *) malloc(sizeof(char) * restFileSize);
+ CHECK_ERR(restFile == 0, "Malloc failed");
+
+ filePosition = 0;
+ restOffset = 0;
+ getsSize = 0;
+
+ do
+ {
+ if (fgets(&restFile[restOffset], restFileSize, fp) == 0)
+ {
+ break;
+ }
+
+ if (strstr(&restFile[restOffset], "<key>spAtrValue</key>"))
+ {
+ filePosition = ftell(fp);
+ }
+
+ getsSize = strlen(&restFile[restOffset]);
+ restOffset += getsSize;
+ }
+ while (1);
+
+ rewind(fp);
+ fwrite(restFile, 1, filePosition, fp);
+ fwrite(atrInsertion, 1, strlen(atrInsertion), fp);
+ fwrite(&restFile[filePosition], 1,
+ statBuffer.st_size - filePosition, fp);
+
+ fclose(fp);
+
+ printf("Token support updated successfully !\n");
+
+ return 0;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1497 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * winscard.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard.c 2385 2007-02-05 13:55:01Z rousseau $
+ */
+
+/**
+ * @mainpage MUSCLE PC/SC-Lite API Documentation
+ *
+ * @section Introduction
+ *
+ * This document contains the reference API calls for communicating to the
+ * MUSCLE PC/SC Smart Card Resource Manager. PC/SC is a standard proposed by
+ * the PC/SC workgroup http://www.pcscworkgroup.com/ which is a conglomerate of
+ * representative from major smart card manufacturers and other companies. This
+ * specification tries to abstract the smart card layer into a high level API
+ * so that smart cards and their readers can be accessed in a homogeneous
+ * fashion.
+ *
+ * This toolkit was written in ANSI C that can be used with most compilers and
+ * does NOT use complex and large data structures such as vectors, etc. The C
+ * API emulates the winscard API that is used on the Windows platform. It is
+ * contained in the library <tt>libpcsclite.so</tt> that is linked to your
+ * application.
+ *
+ * I would really like to hear from you. If you have any feedback either on
+ * this documentation or on the MUSCLE project please feel free to email me at:
+ * corcoran at musclecard.com.
+ *
+ *
+ * @section API Routines
+ *
+ * These routines specified here are winscard routines like those in the
+ * winscard API provided under Windows(R). These are compatible with the
+ * Microsoft(R) API calls. This list of calls is mainly an abstraction of
+ * readers. It gives a common API for communication to most readers in a
+ * homogeneous fashion.
+ *
+ * Since all functions can produce a wide array of errors, please refer to
+ * Error codes for a list of error returns.
+ *
+ * For a human readable representation of an error the function
+ * pcsc_stringify_error() is declared in pcsclite.h. This function is not
+ * available on Microsoft(R) winscard API and is pcsc-lite specific.
+ *
+ * @section Internals
+ *
+ * PC/SC Lite is formed by a server deamon (<tt>pcscd</tt>) and a client
+ * library (<tt>libpcsclite.so</tt>) that communicate via IPC.
+ *
+ * The file \em winscard_clnt.c in the client-side exposes the API for
+ * applications.\n The file \em winscard.c has the server-side counterpart
+ * functions present in \em winscard_clnt.c.\n The file \em winscard_msg.c is
+ * the communication interface between \em winscard_clnt.c and \em
+ * winscard.c.\n The file pcscdaemon.c has the main server-side function,
+ * including a loop for accepting client requests.\n The file \em
+ * winscard_svc.c has the functions called by \em pcscdaemon.c to serve clients
+ * requests.
+ *
+ * When a function from \em winscard_clnt.c is called by a client application,
+ * it calls a function in \em winscard_msg.c to send the message to \em
+ * pcscdaemon.c. When \em pcscdaemon.c a client detects a request arrived, it
+ * calls \em winscard_svc.c which identifies what command the message contains
+ * and requests \em winscard.c to execute the command.\n Meanwhile
+ * winscard_clnt.c waits for the response until a timeout occurs.
+ */
+
+/**
+ * @file
+ * @brief This handles smartcard reader communications.
+ * This is the heart of the MS smartcard API.
+ *
+ * Here are the main server-side functions which execute the requests from the
+ * clients.
+ */
+
+#include "config.h"
+#include <stdlib.h>
+#include <sys/time.h>
+#include <string.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "winscard.h"
+#include "ifdhandler.h"
+#include "debuglog.h"
+#include "readerfactory.h"
+#include "prothandler.h"
+#include "ifdwrapper.h"
+#include "atrhandler.h"
+#include "configfile.h"
+#include "sys_generic.h"
+#include "eventhandler.h"
+#include "readerstate.h"
+
+#include <security_utilities/debugging.h>
+
+/** used for backward compatibility */
+#define SCARD_PROTOCOL_ANY_OLD 0x1000
+
+/** Some defines for context stack. */
+#define SCARD_LAST_CONTEXT 1
+/** Some defines for context stack. */
+#define SCARD_NO_CONTEXT 0
+/** Some defines for context stack. */
+#define SCARD_EXCLUSIVE_CONTEXT -1
+/** Some defines for context stack. */
+#define SCARD_NO_LOCK 0
+
+SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
+SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
+SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
+
+#define PCSCLITE_LOCK_POLL_RATE 100000 /**< Lock polling rate */
+
+static LONG NotifyOfCardReset(DWORD state, PREADER_CONTEXT rContext, SCARDHANDLE hCard);
+static LONG EjectCard(PREADER_CONTEXT rContext);
+
+
+/**
+ * @brief Creates an Application Context for a client.
+ *
+ * This must be the first function called in a PC/SC application.
+ *
+ * @param[in] dwScope Scope of the establishment.
+ * This can either be a local or remote connection.
+ * <ul>
+ * <li>SCARD_SCOPE_USER - Not used.
+ * <li>SCARD_SCOPE_TERMINAL - Not used.
+ * <li>SCARD_SCOPE_GLOBAL - Not used.
+ * <li>SCARD_SCOPE_SYSTEM - Services on the local machine.
+ * </ul>
+ * @param[in] pvReserved1 Reserved for future use. Can be used for remote connection.
+ * @param[in] pvReserved2 Reserved for future use.
+ * @param[out] phContext Returned Application Context.
+ *
+ * @return Connection status.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_VALUE Invalid scope type passed (\ref SCARD_E_INVALID_VALUE)
+ * @retval SCARD_E_INVALID_PARAMETER phContext is null (\ref SCARD_E_INVALID_PARAMETER)
+ */
+LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
+ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
+{
+ /*
+ * Check for NULL pointer
+ */
+ if (phContext == 0)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
+ dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
+ {
+
+ *phContext = 0;
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ /*
+ * Unique identifier for this server so that it can uniquely be
+ * identified by clients and distinguished from others
+ */
+
+ *phContext = (PCSCLITE_SVC_IDENTITY + SYS_Random(SYS_GetSeed(),
+ 1.0, 65535.0));
+
+ Log3(PCSC_LOG_DEBUG, "Establishing Context: %d [0x%08X]", *phContext, *phContext);
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardReleaseContext(SCARDCONTEXT hContext)
+{
+ /*
+ * Nothing to do here RPC layer will handle this
+ */
+
+ Log2(PCSC_LOG_DEBUG, "Releasing Context: %d", hContext);
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
+{
+ /*
+ * This is only used at the client side of an RPC call but just in
+ * case someone calls it here
+ */
+
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
+ DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
+ LPDWORD pdwActiveProtocol)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+ DWORD dwStatus;
+
+ /*
+ * Check for NULL parameters
+ */
+ if (szReader == NULL || phCard == NULL || pdwActiveProtocol == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+ else
+ *phCard = 0;
+
+ if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
+ return SCARD_E_PROTO_MISMATCH;
+
+ if (dwShareMode != SCARD_SHARE_EXCLUSIVE &&
+ dwShareMode != SCARD_SHARE_SHARED &&
+ dwShareMode != SCARD_SHARE_DIRECT)
+ return SCARD_E_INVALID_VALUE;
+
+ Log3(PCSC_LOG_DEBUG, "Attempting Connect to %s using protocol: %d",
+ szReader, dwPreferredProtocols);
+
+ rv = RFReaderInfo((LPSTR) szReader, &rContext);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log2(PCSC_LOG_ERROR, "Reader %s Not Found", szReader);
+ return rv;
+ }
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*******************************************
+ *
+ * This section checks for simple errors
+ *
+ *******************************************/
+
+ /*
+ * Connect if not exclusive mode
+ */
+ if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
+ {
+ Log1(PCSC_LOG_ERROR, "Error Reader Exclusive");
+ return SCARD_E_SHARING_VIOLATION;
+ }
+
+ /*
+ * wait until a possible transaction is finished
+ */
+ if (rContext->dwLockId != 0)
+ {
+ Log1(PCSC_LOG_INFO, "Waiting for release of lock");
+ while (rContext->dwLockId != 0)
+ SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
+ Log1(PCSC_LOG_INFO, "Lock released");
+
+ /* Allow the status thread to convey information */
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
+ }
+
+ /*******************************************
+ *
+ * This section tries to determine the
+ * presence of a card or not
+ *
+ *******************************************/
+ dwStatus = SharedReaderState_State(rContext->readerState);
+
+ if (dwShareMode != SCARD_SHARE_DIRECT)
+ {
+ if (!(dwStatus & SCARD_PRESENT))
+ {
+ Log1(PCSC_LOG_ERROR, "Card Not Inserted");
+ return SCARD_E_NO_SMARTCARD;
+ }
+
+ if (dwStatus & SCARD_SWALLOWED)
+ {
+ Log1(PCSC_LOG_ERROR, "Card Not Powered");
+ return SCARD_W_UNPOWERED_CARD;
+ }
+ }
+
+
+ /*******************************************
+ *
+ * This section tries to decode the ATR
+ * and set up which protocol to use
+ *
+ *******************************************/
+ if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
+ SharedReaderState_SetProtocol(rContext->readerState, SCARD_PROTOCOL_RAW);
+ else
+ {
+ if (dwShareMode != SCARD_SHARE_DIRECT)
+ {
+ /* the protocol is not yet set (no PPS yet) */
+ if (SCARD_PROTOCOL_UNSET == SharedReaderState_Protocol(rContext->readerState))
+ {
+ UCHAR ucAvailable, ucDefault;
+ int ret;
+
+ ucDefault = PHGetDefaultProtocol(SharedReaderState_CardAtr(rContext->readerState),
+ SharedReaderState_CardAtrLength(rContext->readerState));
+ ucAvailable =
+ PHGetAvailableProtocols(SharedReaderState_CardAtr(rContext->readerState),
+ SharedReaderState_CardAtrLength(rContext->readerState));
+
+ /*
+ * If it is set to ANY let it do any of the protocols
+ */
+ if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
+ dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
+
+ ret = PHSetProtocol(rContext, dwPreferredProtocols,
+ ucAvailable, ucDefault);
+
+ /* keep cardProtocol = SCARD_PROTOCOL_UNSET in case of error */
+ if (SET_PROTOCOL_PPS_FAILED == ret)
+ return SCARD_W_UNRESPONSIVE_CARD;
+
+ if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
+ return SCARD_E_PROTO_MISMATCH;
+
+ /* use negociated protocol */
+ SharedReaderState_SetProtocol(rContext->readerState, ret);
+ }
+ else
+ {
+ if (! (dwPreferredProtocols & SharedReaderState_Protocol(rContext->readerState)))
+ return SCARD_E_PROTO_MISMATCH;
+ }
+ }
+ }
+
+ *pdwActiveProtocol = SharedReaderState_Protocol(rContext->readerState);
+
+ if (dwShareMode != SCARD_SHARE_DIRECT)
+ {
+ if ((*pdwActiveProtocol != SCARD_PROTOCOL_T0)
+ && (*pdwActiveProtocol != SCARD_PROTOCOL_T1))
+ Log2(PCSC_LOG_ERROR, "Active Protocol: unknown %d",
+ *pdwActiveProtocol);
+ else
+ Log2(PCSC_LOG_DEBUG, "Active Protocol: T=%d",
+ (*pdwActiveProtocol == SCARD_PROTOCOL_T0) ? 0 : 1);
+ }
+ else
+ Log1(PCSC_LOG_DEBUG, "Direct access: no protocol selected");
+
+ /*
+ * Prepare the SCARDHANDLE identity
+ */
+ *phCard = RFCreateReaderHandle(rContext);
+
+ Log2(PCSC_LOG_DEBUG, "hCard Identity: %x", *phCard);
+
+ /*******************************************
+ *
+ * This section tries to set up the
+ * exclusivity modes. -1 is exclusive
+ *
+ *******************************************/
+
+ if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
+ {
+ if (rContext->dwContexts == SCARD_NO_CONTEXT)
+ {
+ rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
+ RFLockSharing(*phCard);
+ }
+ else
+ {
+ RFDestroyReaderHandle(*phCard);
+ *phCard = 0;
+ Log1(PCSC_LOG_ERROR, "SCardConnect: share mode is exclusive, but already in use");
+ return SCARD_E_SHARING_VIOLATION;
+ }
+ }
+ else
+ {
+ /*
+ * Add a connection to the context stack
+ */
+ rContext->dwContexts += 1;
+ }
+
+ /*
+ * Add this handle to the handle list
+ */
+ rv = RFAddReaderHandle(rContext, *phCard);
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ /*
+ * Clean up - there is no more room
+ */
+ RFDestroyReaderHandle(*phCard);
+ if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
+ rContext->dwContexts = SCARD_NO_CONTEXT;
+ else
+ if (rContext->dwContexts > SCARD_NO_CONTEXT)
+ rContext->dwContexts -= 1;
+
+ *phCard = 0;
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ /*
+ * Allow the status thread to convey information
+ */
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
+ DWORD dwPreferredProtocols, DWORD dwInitialization,
+ LPDWORD pdwActiveProtocol)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+ int do_sleep = 1;
+
+ Log1(PCSC_LOG_DEBUG, "Attempting reconnect to token.");
+
+ if (hCard == 0)
+ return SCARD_E_INVALID_HANDLE;
+
+ /*
+ * Handle the dwInitialization
+ */
+ if (dwInitialization != SCARD_LEAVE_CARD &&
+ dwInitialization != SCARD_RESET_CARD &&
+ dwInitialization != SCARD_UNPOWER_CARD)
+ return SCARD_E_INVALID_VALUE;
+
+ if (dwShareMode != SCARD_SHARE_SHARED &&
+ dwShareMode != SCARD_SHARE_EXCLUSIVE &&
+ dwShareMode != SCARD_SHARE_DIRECT)
+ return SCARD_E_INVALID_VALUE;
+
+ if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
+ return SCARD_E_PROTO_MISMATCH;
+
+ if (pdwActiveProtocol == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure no one has a lock on this reader
+ */
+ rv = RFCheckSharing(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * RFUnblockReader( rContext ); FIX - this doesn't work
+ */
+
+ if (dwInitialization == SCARD_RESET_CARD ||
+ dwInitialization == SCARD_UNPOWER_CARD)
+ {
+ LONG ret = NotifyOfCardReset(dwInitialization, rContext, hCard);
+ if (ret != SCARD_S_SUCCESS)
+ return ret;
+
+ do_sleep = 1;
+ }
+ else if (dwInitialization == SCARD_LEAVE_CARD)
+ {
+ /*
+ * Do nothing
+ */
+ do_sleep = 0;
+ }
+
+ /*******************************************
+ *
+ * This section tries to decode the ATR
+ * and set up which protocol to use
+ *
+ *******************************************/
+
+
+ if (dwPreferredProtocols & SCARD_PROTOCOL_RAW)
+ SharedReaderState_SetProtocol(rContext->readerState, SCARD_PROTOCOL_RAW);
+ else
+ {
+ if (dwShareMode != SCARD_SHARE_DIRECT)
+ {
+ /* the protocol is not yet set (no PPS yet) */
+ if (SCARD_PROTOCOL_UNSET == SharedReaderState_Protocol(rContext->readerState))
+ {
+ UCHAR ucAvailable, ucDefault;
+ int ret;
+
+ ucDefault = PHGetDefaultProtocol(SharedReaderState_CardAtr(rContext->readerState),
+ SharedReaderState_CardAtrLength(rContext->readerState));
+ ucAvailable =
+ PHGetAvailableProtocols(SharedReaderState_CardAtr(rContext->readerState),
+ SharedReaderState_CardAtrLength(rContext->readerState));
+
+ /* If it is set to ANY let it do any of the protocols */
+ if (dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD)
+ dwPreferredProtocols = SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1;
+
+ ret = PHSetProtocol(rContext, dwPreferredProtocols,
+ ucAvailable, ucDefault);
+
+ /* keep cardProtocol = SCARD_PROTOCOL_UNSET in case of error */
+ if (SET_PROTOCOL_PPS_FAILED == ret)
+ return SCARD_W_UNRESPONSIVE_CARD;
+
+ if (SET_PROTOCOL_WRONG_ARGUMENT == ret)
+ return SCARD_E_PROTO_MISMATCH;
+
+ /* use negociated protocol */
+ SharedReaderState_SetProtocol(rContext->readerState, ret);
+ }
+ else
+ {
+ if (! (dwPreferredProtocols & SharedReaderState_Protocol(rContext->readerState)))
+ return SCARD_E_PROTO_MISMATCH;
+ }
+ }
+ }
+
+ *pdwActiveProtocol = SharedReaderState_Protocol(rContext->readerState);
+
+ if (dwShareMode == SCARD_SHARE_EXCLUSIVE)
+ {
+ if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
+ {
+ /*
+ * Do nothing - we are already exclusive
+ */
+ } else
+ {
+ if (rContext->dwContexts == SCARD_LAST_CONTEXT)
+ {
+ rContext->dwContexts = SCARD_EXCLUSIVE_CONTEXT;
+ RFLockSharing(hCard);
+ } else
+ {
+ Log1(PCSC_LOG_ERROR, "SCardReConnect: share mode is exclusive, but already in use");
+ return SCARD_E_SHARING_VIOLATION;
+ }
+ }
+ } else if (dwShareMode == SCARD_SHARE_SHARED)
+ {
+ if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT)
+ {
+ /*
+ * Do nothing - in sharing mode already
+ */
+ } else
+ {
+ /*
+ * We are in exclusive mode but want to share now
+ */
+ RFUnlockSharing(hCard);
+ rContext->dwContexts = SCARD_LAST_CONTEXT;
+ }
+ } else if (dwShareMode == SCARD_SHARE_DIRECT)
+ {
+ if (rContext->dwContexts != SCARD_EXCLUSIVE_CONTEXT)
+ {
+ /*
+ * Do nothing - in sharing mode already
+ */
+ } else
+ {
+ /*
+ * We are in exclusive mode but want to share now
+ */
+ RFUnlockSharing(hCard);
+ rContext->dwContexts = SCARD_LAST_CONTEXT;
+ }
+ } else
+ return SCARD_E_INVALID_VALUE;
+
+ /*
+ * Clear a previous event to the application
+ */
+ RFClearReaderEventState(rContext, hCard);
+
+ /*
+ * Allow the status thread to convey information
+ */
+ if (do_sleep)
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ if (hCard == 0)
+ return SCARD_E_INVALID_HANDLE;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ if ((dwDisposition != SCARD_LEAVE_CARD)
+ && (dwDisposition != SCARD_UNPOWER_CARD)
+ && (dwDisposition != SCARD_RESET_CARD)
+ && (dwDisposition != SCARD_EJECT_CARD))
+ return SCARD_E_INVALID_VALUE;
+
+ /*
+ * wait until a possible transaction is finished
+ */
+ if ((rContext->dwLockId != 0) && (rContext->dwLockId != (uint32_t)hCard))
+ {
+ Log1(PCSC_LOG_INFO, "Waiting for release of lock");
+ while (rContext->dwLockId != 0)
+ SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
+ Log1(PCSC_LOG_INFO, "Lock released");
+ }
+
+ /*
+ * Unlock any blocks on this context
+ */
+ rv = RFUnlockSharing(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ Log2(PCSC_LOG_DEBUG, "Active Contexts: %d", rContext->dwContexts);
+
+ if (dwDisposition == SCARD_RESET_CARD ||
+ dwDisposition == SCARD_UNPOWER_CARD)
+ {
+ /* LONG ret = */ NotifyOfCardReset(dwDisposition, rContext, hCard);
+ /* we ignore the return values in this case */
+
+ /*
+ * Allow the status thread to convey information
+ */
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
+
+ }
+ else
+ if (dwDisposition == SCARD_EJECT_CARD)
+ EjectCard(rContext);
+ else if (dwDisposition == SCARD_LEAVE_CARD)
+ {
+ /*
+ * Do nothing
+ */
+ }
+
+ /*
+ * Remove and destroy this handle
+ */
+ RFRemoveReaderHandle(rContext, hCard);
+ RFDestroyReaderHandle(hCard);
+
+ /*
+ * For exclusive connection reset it to no connections
+ */
+ if (rContext->dwContexts == SCARD_EXCLUSIVE_CONTEXT)
+ {
+ rContext->dwContexts = SCARD_NO_CONTEXT;
+ return SCARD_S_SUCCESS;
+ }
+
+ /*
+ * Remove a connection from the context stack
+ */
+ rContext->dwContexts -= 1;
+
+ if (rContext->dwContexts < 0)
+ rContext->dwContexts = 0;
+
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardBeginTransaction(SCARDHANDLE hCard)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext;
+
+ if (hCard == 0)
+ return SCARD_E_INVALID_HANDLE;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+
+ /*
+ * Cannot find the hCard in this context
+ */
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log3(PCSC_LOG_DEBUG, "SCardBeginTransaction: cannot find hCard: 0x%08X [0x%08X]", hCard, rv);
+ return rv;
+ }
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log3(PCSC_LOG_DEBUG, "SCardBeginTransaction: reader status fail: 0x%08X [0x%08X]", hCard, rv);
+ return rv;
+ }
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ {
+ Log3(PCSC_LOG_DEBUG, "SCardBeginTransaction: reader handle fail: 0x%08X [0x%08X]", hCard, rv);
+ return rv;
+ }
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ {
+ Log3(PCSC_LOG_DEBUG, "SCardBeginTransaction: reader event fail: 0x%08X [0x%08X]", hCard, rv);
+ return rv;
+ }
+
+ rv = RFLockSharing(hCard);
+
+ /* if the transaction is not yet ready we sleep a bit so the client
+ * do not retry immediately */
+ if (SCARD_E_SHARING_VIOLATION == (uint32_t)rv)
+ SYS_USleep(PCSCLITE_LOCK_POLL_RATE);
+
+ Log2(PCSC_LOG_DEBUG, "SCardBeginTransaction ending status: 0x%08X", rv);
+
+ return rv;
+}
+
+LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ /*
+ * Ignoring dwDisposition for now
+ */
+ if (hCard == 0)
+ return SCARD_E_INVALID_HANDLE;
+
+ if ((dwDisposition != SCARD_LEAVE_CARD)
+ && (dwDisposition != SCARD_UNPOWER_CARD)
+ && (dwDisposition != SCARD_RESET_CARD)
+ && (dwDisposition != SCARD_EJECT_CARD))
+ return SCARD_E_INVALID_VALUE;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+
+ /*
+ * Cannot find the hCard in this context
+ */
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ if (dwDisposition == SCARD_RESET_CARD ||
+ dwDisposition == SCARD_UNPOWER_CARD)
+ {
+ /* LONG ret = */ NotifyOfCardReset(dwDisposition, rContext, hCard);
+ }
+ else if (dwDisposition == SCARD_EJECT_CARD)
+ EjectCard(rContext);
+ else if (dwDisposition == SCARD_LEAVE_CARD)
+ {
+ /*
+ * Do nothing
+ */
+ }
+
+ /*
+ * Unlock any blocks on this context
+ */
+ RFUnlockSharing(hCard);
+
+ Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv);
+
+ return rv;
+}
+
+LONG SCardCancelTransaction(SCARDHANDLE hCard)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ /*
+ * Ignoring dwDisposition for now
+ */
+ if (hCard == 0)
+ return SCARD_E_INVALID_HANDLE;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+
+ /*
+ * Cannot find the hCard in this context
+ */
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFUnlockSharing(hCard);
+
+ Log2(PCSC_LOG_DEBUG, "Status: 0x%08X", rv);
+
+ return rv;
+}
+
+LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
+ LPDWORD pcchReaderLen, LPDWORD pdwState,
+ LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+
+ /*
+ * Cannot find the hCard in this context
+ */
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ if (strlen(rContext->lpcReader) > MAX_BUFFER_SIZE
+ || SharedReaderState_CardAtrLength(rContext->readerState) > MAX_ATR_SIZE)
+ return SCARD_F_INTERNAL_ERROR;
+
+ /*
+ * This is a client side function however the server maintains the
+ * list of events between applications so it must be passed through to
+ * obtain this event if it has occurred
+ */
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ if (mszReaderNames) /* want reader name */
+ {
+ int cchReaderLen;
+ if (!pcchReaderLen) /* present buf & no buflen */
+ return SCARD_E_INVALID_PARAMETER;
+
+ cchReaderLen = strlen(rContext->lpcReader);
+ if(*pcchReaderLen < cchReaderLen)
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+ else /* There's enough room in the buffer */
+ strncpy(mszReaderNames, rContext->lpcReader, cchReaderLen);
+ *pcchReaderLen = cchReaderLen;
+ }
+ else if (pcchReaderLen) /* want the reader length but not the name */
+ *pcchReaderLen = strlen(rContext->lpcReader);
+
+ if (pdwState)
+ *pdwState = SharedReaderState_State(rContext->readerState);
+
+ if (pdwProtocol)
+ *pdwProtocol = SharedReaderState_Protocol(rContext->readerState);
+
+ if (pbAtr) /* want ATR */
+ {
+ int cbAtrLen;
+ if (!pcbAtrLen)
+ return SCARD_E_INVALID_PARAMETER;
+ cbAtrLen = SharedReaderState_CardAtrLength(rContext->readerState);
+
+ if(cbAtrLen >= *pcbAtrLen)
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+ else
+ {
+ *pcbAtrLen = cbAtrLen;
+ memcpy(pbAtr, SharedReaderState_CardAtr(rContext->readerState), cbAtrLen);
+ }
+ }
+ else if (pcbAtrLen)
+ *pcbAtrLen = SharedReaderState_CardAtrLength(rContext->readerState);
+
+ return rv;
+}
+
+LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
+ LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
+{
+ /*
+ * Client side function
+ */
+ return SCARD_S_SUCCESS;
+}
+
+#undef SCardControl
+
+LONG SCardControl(SCARDHANDLE hCard, const void *pbSendBuffer,
+ DWORD cbSendLength, void *pbRecvBuffer, LPDWORD pcbRecvLength)
+{
+ // Pre pcsclite 1.3.2 version
+
+ uint32_t dwControlCode = 0;
+
+ uint32_t cbRecvLength = *pcbRecvLength;
+ uint32_t bytesReturned = 0;
+ int32_t rv = SCardControl132(hCard, dwControlCode, pbSendBuffer, cbSendLength,
+ pbRecvBuffer, cbRecvLength, &bytesReturned);
+ *pcbRecvLength = bytesReturned;
+ return rv;
+}
+
+int32_t SCardControl132(SCARDHANDLE hCard, uint32_t dwControlCode,
+ const void *pbSendBuffer, uint32_t cbSendLength,
+ void *pbRecvBuffer, uint32_t cbRecvLength, uint32_t *lpBytesReturned)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ /* 0 bytes returned by default */
+ *lpBytesReturned = 0;
+
+ if (0 == hCard)
+ return SCARD_E_INVALID_HANDLE;
+
+ /*
+ * Make sure no one has a lock on this reader
+ */
+ if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ if (IFD_HVERSION_2_0 == rContext->dwVersion)
+ if (NULL == pbSendBuffer || 0 == cbSendLength)
+ return SCARD_E_INVALID_PARAMETER;
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ if (IFD_HVERSION_2_0 == rContext->dwVersion)
+ {
+ /* we must wrap a API 3.0 client in an API 2.0 driver */
+ *lpBytesReturned = cbRecvLength;
+ return IFDControl_v2(rContext, (PUCHAR)pbSendBuffer,
+ cbSendLength, (uint8_t *)pbRecvBuffer, lpBytesReturned);
+ }
+ else
+ if (IFD_HVERSION_3_0 == rContext->dwVersion)
+ return IFDControl(rContext, dwControlCode, pbSendBuffer,
+ cbSendLength, pbRecvBuffer, cbRecvLength, lpBytesReturned);
+ else
+ return SCARD_E_UNSUPPORTED_FEATURE;
+}
+
+LONG SCardGetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
+ LPBYTE pbAttr, LPDWORD pcbAttrLen)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ if (0 == hCard)
+ return SCARD_E_INVALID_HANDLE;
+
+ /*
+ * Make sure no one has a lock on this reader
+ */
+ if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = IFDGetCapabilities(rContext, dwAttrId, pcbAttrLen, pbAttr);
+ if (rv == IFD_SUCCESS)
+ return SCARD_S_SUCCESS;
+ else
+ if (rv == IFD_ERROR_TAG)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+ else
+ return SCARD_E_NOT_TRANSACTED;
+}
+
+LONG SCardSetAttrib(SCARDHANDLE hCard, DWORD dwAttrId,
+ LPCBYTE pbAttr, DWORD cbAttrLen)
+{
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+
+ if (0 == hCard)
+ return SCARD_E_INVALID_HANDLE;
+
+ /*
+ * Make sure no one has a lock on this reader
+ */
+ if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = IFDSetCapabilities(rContext, dwAttrId, cbAttrLen, (PUCHAR)pbAttr);
+ if (rv == IFD_SUCCESS)
+ return SCARD_S_SUCCESS;
+ else
+ if (rv == IFD_ERROR_TAG)
+ return SCARD_E_UNSUPPORTED_FEATURE;
+ else
+ return SCARD_E_NOT_TRANSACTED;
+}
+
+#define kSCARD_LE_IN_SW2 0x6C
+#define kReadBinaryAPDU 0xB0
+#define kReadBinaryLe 4
+
+LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
+ LPCBYTE pbSendBuffer, DWORD cbSendLength,
+ LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
+ LPDWORD pcbRecvLength)
+{
+ /*
+ See for example:
+ NIST IR 6887 "Government Smart Card Interoperability Specification (GSC-IS), v2.1",
+ July 2003
+ http://csrc.nist.gov/publications/nistir/nistir-6887.pdf
+ for info on error conditions. One define is SCARD_LE_IN_SW2
+ */
+ LONG rv;
+ PREADER_CONTEXT rContext = NULL;
+ SCARD_IO_HEADER sSendPci, sRecvPci;
+ DWORD dwRxLength, tempRxLength;
+
+ if (pcbRecvLength == 0)
+ return SCARD_E_INVALID_PARAMETER;
+
+ dwRxLength = *pcbRecvLength;
+ *pcbRecvLength = 0;
+
+ if (hCard == 0)
+ return SCARD_E_INVALID_HANDLE;
+
+ if (pbSendBuffer == NULL || pbRecvBuffer == NULL || pioSendPci == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+
+ /*
+ * Must at least send a 4 bytes APDU
+ */
+ if (cbSendLength < 4)
+ return SCARD_E_INVALID_PARAMETER;
+
+ /*
+ * Must at least have 2 status words even for SCardControl
+ */
+ if (dwRxLength < 2)
+ return SCARD_E_INSUFFICIENT_BUFFER;
+
+ /*
+ * Make sure no one has a lock on this reader
+ */
+ if ((rv = RFCheckSharing(hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFReaderInfoById(hCard, &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure the reader is working properly
+ */
+ rv = RFCheckReaderStatus(rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ rv = RFFindReaderHandle(hCard);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Make sure some event has not occurred
+ */
+ if ((rv = RFCheckReaderEventState(rContext, hCard)) != SCARD_S_SUCCESS)
+ return rv;
+
+ /*
+ * Check for some common errors
+ */
+ if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
+ {
+ if (SharedReaderState_State(rContext->readerState) & SCARD_ABSENT)
+ {
+ return SCARD_E_NO_SMARTCARD;
+ }
+ }
+
+ if (pioSendPci->dwProtocol != SCARD_PROTOCOL_RAW)
+ {
+ if (pioSendPci->dwProtocol != SCARD_PROTOCOL_ANY_OLD)
+ {
+ if (pioSendPci->dwProtocol != SharedReaderState_Protocol(rContext->readerState))
+ {
+ return SCARD_E_PROTO_MISMATCH;
+ }
+ }
+ }
+
+ /*
+ * Quick fix: PC/SC starts at 1 for bit masking but the IFD_Handler
+ * just wants 0 or 1
+ */
+
+ sSendPci.Protocol = 0; /* protocol T=0 by default */
+
+ if (pioSendPci->dwProtocol == SCARD_PROTOCOL_T1)
+ {
+ sSendPci.Protocol = 1;
+ } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
+ {
+ /*
+ * This is temporary ......
+ */
+ sSendPci.Protocol = SCARD_PROTOCOL_RAW;
+ } else if (pioSendPci->dwProtocol == SCARD_PROTOCOL_ANY_OLD)
+ {
+ /* Fix by Amira (Athena) */
+ unsigned long i;
+ unsigned long prot = SharedReaderState_Protocol(rContext->readerState);
+
+ for (i = 0 ; prot != 1 ; i++)
+ prot >>= 1;
+
+ sSendPci.Protocol = i;
+ }
+
+ sSendPci.Length = pioSendPci->cbPciLength;
+
+ /* the protocol number is decoded a few lines above */
+ Log2(PCSC_LOG_DEBUG, "Send Protocol: T=%d", sSendPci.Protocol);
+
+ tempRxLength = dwRxLength;
+
+ if (pioSendPci->dwProtocol == SCARD_PROTOCOL_RAW)
+ {
+ rv = IFDControl_v2(rContext, (PUCHAR)pbSendBuffer , cbSendLength,
+ pbRecvBuffer, &dwRxLength);
+ } else
+ {
+ rv = IFDTransmit(rContext, sSendPci, (PUCHAR)pbSendBuffer,
+ cbSendLength, pbRecvBuffer, &dwRxLength, &sRecvPci);
+ }
+
+ if (pioRecvPci)
+ {
+ pioRecvPci->dwProtocol = sRecvPci.Protocol;
+ pioRecvPci->cbPciLength = sRecvPci.Length;
+ }
+
+ Log3(PCSC_LOG_DEBUG, "IFDControl_v2/IFDTransmit result: 0x%08X, received: %d", rv, dwRxLength);
+ Log3(PCSC_LOG_DEBUG, " pbRecvBuffer: [0]: 0x%02X, [1]: 0x%02X", pbRecvBuffer[0], pbRecvBuffer[1]);
+
+ /*
+ * Check for any errors that might have occurred
+ */
+
+ if (rv != SCARD_S_SUCCESS)
+ {
+ *pcbRecvLength = 0;
+ Log2(PCSC_LOG_ERROR, "Card not transacted: 0x%08lX", rv);
+ return SCARD_E_NOT_TRANSACTED;
+ }
+
+ /*
+ * Available is less than received
+ */
+ if (tempRxLength < dwRxLength)
+ {
+ Log3(PCSC_LOG_DEBUG, "Available is less than received: avail: %d, received: %d", tempRxLength, dwRxLength);
+ *pcbRecvLength = 0;
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+
+ /*
+ * Successful return
+ */
+ *pcbRecvLength = dwRxLength;
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
+ LPSTR mszReaders, LPDWORD pcchReaders)
+{
+ /*
+ * Client side function
+ */
+ return SCARD_S_SUCCESS;
+}
+
+LONG SCardCancel(SCARDCONTEXT hContext)
+{
+ /*
+ * Client side function
+ */
+ return SCARD_S_SUCCESS;
+}
+
+static LONG NotifyOfCardReset(DWORD state, PREADER_CONTEXT rContext, SCARDHANDLE hCard)
+{
+ /*
+ * Currently pcsc-lite keeps the card powered constantly
+ * Note that although EndTransaction initially sets dwAction in one
+ * case to IFD_POWER_DOWN, it then sets it to IFD_RESET
+ */
+
+ LONG rv = SCARD_S_SUCCESS, ret = SCARD_S_SUCCESS;
+
+ DWORD tmpCardAtrLength = SharedReaderState_CardAtrLength(rContext->readerState);
+ if (SCARD_RESET_CARD == state)
+ rv = IFDPowerICC(rContext, IFD_RESET, SharedReaderState_CardAtr(rContext->readerState), &tmpCardAtrLength);
+ else
+ {
+ rv = IFDPowerICC(rContext, IFD_POWER_DOWN, SharedReaderState_CardAtr(rContext->readerState), &tmpCardAtrLength);
+ rv = IFDPowerICC(rContext, IFD_POWER_UP, SharedReaderState_CardAtr(rContext->readerState), &tmpCardAtrLength);
+ }
+ SharedReaderState_SetCardAtrLength(rContext->readerState, tmpCardAtrLength);
+
+ /* the protocol is unset after a power on */
+ SharedReaderState_SetProtocol(rContext->readerState, SCARD_PROTOCOL_UNSET);
+
+ /*
+ * Notify the card has been reset
+ * Not doing this could result in deadlock
+ */
+ ret = RFCheckReaderEventState(rContext, hCard);
+
+ /*
+ Note: there is disagreement on which value of rv to use for the switch below:
+
+ SCardReconnect: result of RFCheckReaderEventState
+ SCardDisconnect: result of IFDPowerICC
+ SCardEndTransaction: result of IFDPowerICC
+
+ We use the result of IFDPowerICC here; this seems more sensible
+ */
+ switch (rv)
+ {
+ /* avoid deadlock */
+ case SCARD_W_RESET_CARD:
+ break;
+
+ case SCARD_W_REMOVED_CARD:
+ Log1(PCSC_LOG_ERROR, "card removed");
+ return SCARD_W_REMOVED_CARD;
+
+ /* invalid EventStatus */
+ case SCARD_E_INVALID_VALUE:
+ Log1(PCSC_LOG_ERROR, "invalid EventStatus");
+ return SCARD_F_INTERNAL_ERROR;
+
+ /* invalid hCard, but hCard was widely used some lines above :( */
+ case SCARD_E_INVALID_HANDLE:
+ Log1(PCSC_LOG_ERROR, "invalid handle");
+ return SCARD_F_INTERNAL_ERROR;
+
+ case SCARD_S_SUCCESS:
+ /*
+ * Notify the card has been reset
+ */
+ RFSetReaderEventState(rContext, SCARD_RESET);
+
+ /*
+ * Set up the status bit masks on dwStatus
+ */
+ DWORD readerStateTmp = SharedReaderState_State(rContext->readerState);
+ if (rv == SCARD_S_SUCCESS)
+ {
+ readerStateTmp |= SCARD_PRESENT;
+ readerStateTmp &= ~SCARD_ABSENT;
+ readerStateTmp |= SCARD_POWERED;
+ readerStateTmp |= SCARD_NEGOTIABLE;
+ readerStateTmp &= ~SCARD_SPECIFIC;
+ readerStateTmp &= ~SCARD_SWALLOWED;
+ readerStateTmp &= ~SCARD_UNKNOWN;
+ }
+ else
+ {
+ readerStateTmp |= SCARD_PRESENT;
+ readerStateTmp &= ~SCARD_ABSENT;
+ readerStateTmp |= SCARD_SWALLOWED;
+ readerStateTmp &= ~SCARD_POWERED;
+ readerStateTmp &= ~SCARD_NEGOTIABLE;
+ readerStateTmp &= ~SCARD_SPECIFIC;
+ readerStateTmp &= ~SCARD_UNKNOWN;
+ SharedReaderState_SetCardAtrLength(rContext->readerState, 0);
+ }
+ SharedReaderState_SetState(rContext->readerState, readerStateTmp);
+
+ if (SharedReaderState_CardAtrLength(rContext->readerState) > 0)
+ {
+ Log1(PCSC_LOG_ERROR, "Reset complete.");
+ LogXxd(PCSC_LOG_DEBUG, "Card ATR: ", SharedReaderState_CardAtr(rContext->readerState),
+ SharedReaderState_CardAtrLength(rContext->readerState));
+ }
+ else
+ {
+ DWORD dwStatus, dwAtrLen;
+ UCHAR ucAtr[MAX_ATR_SIZE];
+
+ Log1(PCSC_LOG_ERROR, "Error resetting card.");
+ IFDStatusICC(rContext, &dwStatus, ucAtr, &dwAtrLen);
+ if (dwStatus & SCARD_PRESENT)
+ return SCARD_W_UNRESPONSIVE_CARD;
+ else
+ return SCARD_E_NO_SMARTCARD;
+ }
+ break;
+ default:
+ Log2(PCSC_LOG_ERROR, "invalid retcode from RFCheckReaderEventState (%X)", rv);
+ return SCARD_F_INTERNAL_ERROR;
+ }
+ return SCARD_S_SUCCESS;
+}
+
+static LONG EjectCard(PREADER_CONTEXT rContext)
+{
+ LONG rv = SCARD_S_SUCCESS;
+
+ UCHAR controlBuffer[5];
+ UCHAR receiveBuffer[MAX_BUFFER_SIZE];
+ DWORD receiveLength;
+
+ /*
+ * Set up the CTBCS command for Eject ICC
+ */
+ controlBuffer[0] = 0x20;
+ controlBuffer[1] = 0x15;
+ controlBuffer[2] = (rContext->dwSlot & 0x0000FFFF) + 1;
+ controlBuffer[3] = 0x00;
+ controlBuffer[4] = 0x00;
+ receiveLength = 2;
+ rv = IFDControl_v2(rContext, controlBuffer, 5, receiveBuffer, &receiveLength);
+
+ if (rv == SCARD_S_SUCCESS)
+ {
+ if (receiveLength == 2 && receiveBuffer[0] == 0x90) // Successful
+ Log1(PCSC_LOG_ERROR, "Card ejected successfully.");
+ else
+ {
+ Log3(PCSC_LOG_ERROR, "Error ejecting card: %02X%02X", receiveBuffer[0], receiveBuffer[1]);
+ rv = SCARD_F_UNKNOWN_ERROR;
+ }
+ }
+ else
+ Log1(PCSC_LOG_ERROR, "Error ejecting card.");
+
+ return rv;
+}
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2003
+ * David Corcoran <corcoran at linuxnet.com>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard.h 2072 2006-06-06 09:31:07Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles smartcard reader communications.
+ */
+
+#ifndef __winscard_h__
+#define __winscard_h__
+
+#include <PCSC/pcsclite.h>
+#include <stdint.h>
+//#include "pcscexport.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#ifndef PCSC_API
+#define PCSC_API
+#endif
+
+ PCSC_API int32_t SCardEstablishContext(uint32_t dwScope,
+ const void *pvReserved1, const void *pvReserved2, LPSCARDCONTEXT phContext);
+
+ PCSC_API int32_t SCardReleaseContext(SCARDCONTEXT hContext);
+
+ PCSC_API int32_t SCardSetTimeout(SCARDCONTEXT hContext, uint32_t dwTimeout);
+
+ PCSC_API int32_t SCardConnect(SCARDCONTEXT hContext,
+ const char *szReader,
+ uint32_t dwShareMode,
+ uint32_t dwPreferredProtocols,
+ LPSCARDHANDLE phCard, uint32_t *pdwActiveProtocol);
+
+ PCSC_API int32_t SCardReconnect(SCARDHANDLE hCard,
+ uint32_t dwShareMode,
+ uint32_t dwPreferredProtocols,
+ uint32_t dwInitialization, uint32_t *pdwActiveProtocol);
+
+ PCSC_API int32_t SCardDisconnect(SCARDHANDLE hCard, uint32_t dwDisposition);
+
+ PCSC_API int32_t SCardBeginTransaction(SCARDHANDLE hCard);
+
+ PCSC_API int32_t SCardEndTransaction(SCARDHANDLE hCard, uint32_t dwDisposition);
+
+ PCSC_API int32_t SCardCancelTransaction(SCARDHANDLE hCard);
+
+ PCSC_API int32_t SCardStatus(SCARDHANDLE hCard,
+ char *mszReaderNames, uint32_t *pcchReaderLen,
+ uint32_t *pdwState,
+ uint32_t *pdwProtocol,
+ unsigned char *pbAtr, uint32_t *pcbAtrLen);
+
+ PCSC_API int32_t SCardGetStatusChange(SCARDCONTEXT hContext,
+ uint32_t dwTimeout,
+ LPSCARD_READERSTATE_A rgReaderStates, uint32_t cReaders);
+
+ PCSC_API int32_t SCardControl(SCARDHANDLE hCard,
+ const void *pbSendBuffer, uint32_t cbSendLength,
+ void *pbRecvBuffer, uint32_t *pcbRecvLength);
+
+ PCSC_API int32_t SCardControl132(SCARDHANDLE hCard, uint32_t dwControlCode,
+ const void *pbSendBuffer, uint32_t cbSendLength,
+ void *pbRecvBuffer, uint32_t cbRecvLength, uint32_t *lpBytesReturned);
+
+ PCSC_API int32_t SCardTransmit(SCARDHANDLE hCard,
+ LPCSCARD_IO_REQUEST pioSendPci,
+ const unsigned char *pbSendBuffer, uint32_t cbSendLength,
+ LPSCARD_IO_REQUEST pioRecvPci,
+ unsigned char *pbRecvBuffer, uint32_t *pcbRecvLength);
+
+ PCSC_API int32_t SCardListReaderGroups(SCARDCONTEXT hContext,
+ char *mszGroups, uint32_t *pcchGroups);
+
+ PCSC_API int32_t SCardListReaders(SCARDCONTEXT hContext,
+ const char *mszGroups,
+ char *mszReaders, uint32_t *pcchReaders);
+
+ PCSC_API int32_t SCardCancel(SCARDCONTEXT hContext);
+
+ PCSC_API int32_t SCardGetAttrib(SCARDHANDLE hCard, uint32_t dwAttrId,
+ uint8_t *pbAttr, uint32_t *pcbAttrLen);
+
+ PCSC_API int32_t SCardSetAttrib(SCARDHANDLE hCard, uint32_t dwAttrId,
+ const uint8_t *pbAttr, uint32_t cbAttrLen);
+
+ void SCardUnload(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+ To support the newer version of SCardControl, we define it
+ as follows. The old version number was 1.1.2, the new call
+ appears in 1.3.2 of pcsc-lite (or perhaps earlier).
+*/
+
+#if !defined(USE_SCARD_CONTROL_112)
+#define SCardControl SCardControl132
+#endif /* USE_SCARD_CONTROL_112 */
+
+#endif
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_clnt.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_clnt.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_clnt.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,3385 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * winscard_clnt.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard_clnt.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This handles smartcard reader communications and
+ * forwarding requests over message queues.
+ *
+ * Here is exposed the API for client applications.
+ */
+
+#include <assert.h>
+#include "config.h"
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/_endian.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "pcscexport.h"
+#include "winscard.h"
+#include "debug.h"
+#include "thread_generic.h"
+
+#include "readerfactory.h"
+#include "eventhandler.h"
+#include "sys_generic.h"
+#include "winscard_msg.h"
+#include "readerstate.h"
+
+#include <security_utilities/debugging.h>
+
+/** used for backward compatibility */
+#define SCARD_PROTOCOL_ANY_OLD 0x1000
+
+#ifndef min
+#define min(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define PROFILE_START
+#define PROFILE_END
+
+/**
+ * Represents an Application Context Channel.
+ * A channel belongs to an Application Context (\c _psContextMap).
+ */
+struct _psChannelMap
+{
+ SCARDHANDLE hCard;
+ LPSTR readerName;
+};
+
+typedef struct _psChannelMap CHANNEL_MAP, *PCHANNEL_MAP;
+
+/**
+ * @brief Represents the an Application Context on the Client side.
+ *
+ * An Application Context contains Channels (\c _psChannelMap).
+ */
+static struct _psContextMap
+{
+ DWORD dwClientID; /** Client Connection ID */
+ SCARDCONTEXT hContext; /** Application Context ID */
+ DWORD contextBlockStatus;
+ PCSCLITE_MUTEX_T mMutex; /** Mutex for this context */
+ CHANNEL_MAP psChannelMap[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
+} psContextMap[PCSCLITE_MAX_APPLICATION_CONTEXTS];
+
+/**
+ * Make sure the initialization code is executed only once.
+ */
+static short isExecuted = 0;
+
+/**
+ * Memory mapped address used to read status information about the readers.
+ * Each element in the vector \ref readerStates makes references to a part of
+ * the memory mapped.
+ */
+static int mapAddr = 0;
+
+/**
+ * Ensure that some functions be accessed in thread-safe mode.
+ * These function's names finishes with "TH".
+ */
+static PCSCLITE_MUTEX clientMutex = PTHREAD_MUTEX_INITIALIZER;
+
+/**
+ * Pointers to a memory mapped area used to read status information about the
+ * readers.
+ * Each element in the vector \ref readerStates makes references to a part of
+ * the memory mapped \ref mapAddr.
+ */
+static PREADER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS];
+
+PCSC_API SCARD_IO_REQUEST g_rgSCardT0Pci = { SCARD_PROTOCOL_T0, 8 };
+PCSC_API SCARD_IO_REQUEST g_rgSCardT1Pci = { SCARD_PROTOCOL_T1, 8 };
+PCSC_API SCARD_IO_REQUEST g_rgSCardRawPci = { SCARD_PROTOCOL_RAW, 8 };
+
+
+static LONG SCardAddContext(SCARDCONTEXT, DWORD);
+static LONG SCardGetContextIndice(SCARDCONTEXT);
+static LONG SCardGetContextIndiceTH(SCARDCONTEXT);
+static LONG SCardRemoveContext(SCARDCONTEXT);
+
+static LONG SCardAddHandle(SCARDHANDLE, DWORD, LPSTR);
+static LONG SCardGetIndicesFromHandle(SCARDHANDLE, PDWORD, PDWORD);
+static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE, PDWORD, PDWORD);
+static LONG SCardRemoveHandle(SCARDHANDLE);
+
+static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
+ LPBYTE pbAttr, LPDWORD pcbAttrLen);
+
+static LONG SCardCheckDaemonAvailability(void);
+static int SCardInitializeOnce();
+
+/*
+ * Thread safety functions
+ */
+inline static LONG SCardLockThread(void);
+inline static LONG SCardUnlockThread(void);
+
+static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT);
+
+/**
+ * @brief Creates an Application Context to the PC/SC Resource Manager.
+
+ * This must be the first function called in a PC/SC application.
+ * This is a thread-safe wrapper to the function SCardEstablishContextTH().
+ *
+ * @param[in] dwScope Scope of the establishment.
+ * This can either be a local or remote connection.
+ * <ul>
+ * <li>\ref SCARD_SCOPE_USER - Not used.
+ * <li>\ref SCARD_SCOPE_TERMINAL - Not used.
+ * <li>\ref SCARD_SCOPE_GLOBAL - Not used.
+ * <li>\ref SCARD_SCOPE_SYSTEM - Services on the local machine.
+ * </ul>
+ * @param[in] pvReserved1 Reserved for future use. Can be used for remote connection.
+ * @param[in] pvReserved2 Reserved for future use.
+ * @param[out] phContext Returned Application Context.
+ *
+ * @return Connection status.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NO_SERVICE The server is not runing (\ref SCARD_E_NO_SERVICE)
+ * @retval SCARD_E_INVALID_VALUE Invalid scope type passed (\ref SCARD_E_INVALID_VALUE )
+ * @retval SCARD_E_INVALID_PARAMETER phContext is null (\ref SCARD_E_INVALID_PARAMETER)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * @endcode
+ */
+LONG SCardEstablishContext(DWORD dwScope, LPCVOID pvReserved1,
+ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
+{
+ LONG rv;
+
+ PROFILE_START
+
+ SCardLockThread();
+ rv = SCardEstablishContextTH(dwScope, pvReserved1,
+ pvReserved2, phContext);
+ SCardUnlockThread();
+
+ PROFILE_END
+
+ return rv;
+}
+
+/**
+ * @brief Creates a communication context to the PC/SC Resource
+ * Manager.
+ *
+ * This function shuld not be called directly. Instead, the thread-safe
+ * function SCardEstablishContext() should be called.
+ *
+ * @param[in] dwScope Scope of the establishment.
+ * This can either be a local or remote connection.
+ * <ul>
+ * <li>\ref SCARD_SCOPE_USER - Not used.
+ * <li>\ref SCARD_SCOPE_TERMINAL - Not used.
+ * <li>\ref SCARD_SCOPE_GLOBAL - Not used.
+ * <li>\ref SCARD_SCOPE_SYSTEM - Services on the local machine.
+ * </ul>
+ * @param[in] pvReserved1 Reserved for future use. Can be used for remote connection.
+ * @param[in] pvReserved2 Reserved for future use.
+ * @param[out] phContext Returned reference to this connection.
+ *
+ * @return Connection status.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NO_SERVICE The server is not runing (\ref SCARD_E_NO_SERVICE)
+ * @retval SCARD_E_INVALID_PARAMETER phContext is null. (\ref SCARD_E_INVALID_PARAMETER)
+ * @retval SCARD_E_INVALID_VALUE Invalid scope type passed (\ref SCARD_E_INVALID_VALUE)
+ */
+static LONG SCardEstablishContextTH(DWORD dwScope, LPCVOID pvReserved1,
+ LPCVOID pvReserved2, LPSCARDCONTEXT phContext)
+{
+ LONG rv;
+ establish_struct scEstablishStruct;
+ sharedSegmentMsg msgStruct;
+ DWORD dwClientID = 0;
+
+ if (phContext == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+ else
+ *phContext = 0;
+
+ /* Check if the server is running */
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Do this only once:
+ * - Initialize debug of need.
+ * - Set up the memory mapped structures for reader states.
+ * - Allocate each reader structure.
+ * - Initialize context struct.
+ */
+ if (isExecuted == 0)
+ {
+ SCardInitializeOnce();
+ isExecuted = 1;
+ }
+
+ /* Establishes a connection to the server */
+ if (SHMClientSetupSession(&dwClientID) != 0)
+ {
+ SYS_CloseFile(mapAddr);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ { /* exchange client/server protocol versions */
+ sharedSegmentMsg msgStruct;
+ version_struct *veStr = (version_struct *)&msgStruct.data;
+ veStr->major = PROTOCOL_VERSION_MAJOR;
+ veStr->minor = PROTOCOL_VERSION_MINOR;
+ htonlVersionStruct(veStr);
+
+ if (-1 == WrapSHMWrite(CMD_VERSION, dwClientID, sizeof(version_struct), PCSCLITE_CLIENT_ATTEMPTS, veStr))
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Read a message from the server
+ */
+ if (-1 == SHMClientReadMessage(&msgStruct, dwClientID, sizeof(version_struct), PCSCLITE_CLIENT_ATTEMPTS))
+ {
+ Log1(PCSC_LOG_ERROR, "Your pcscd is too old and does not support CMD_VERSION");
+ return SCARD_F_COMM_ERROR;
+ }
+
+ ntohlVersionStruct(veStr);
+ Log3(PCSC_LOG_ERROR, "Server is protocol version %d:%d",
+ veStr->major, veStr->minor);
+
+ if (veStr->rv != SCARD_S_SUCCESS)
+ return veStr->rv;
+ }
+
+ if (dwScope != SCARD_SCOPE_USER && dwScope != SCARD_SCOPE_TERMINAL &&
+ dwScope != SCARD_SCOPE_SYSTEM && dwScope != SCARD_SCOPE_GLOBAL)
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ /*
+ * Try to establish an Application Context with the server
+ */
+ scEstablishStruct.dwScope = dwScope;
+ scEstablishStruct.phContext = 0;
+ scEstablishStruct.rv = 0;
+
+ htonlEstablishStruct(&scEstablishStruct);
+ rv = WrapSHMWrite(SCARD_ESTABLISH_CONTEXT, dwClientID,
+ sizeof(scEstablishStruct), PCSCLITE_MCLIENT_ATTEMPTS,
+ (void *) &scEstablishStruct);
+
+ if (rv == -1)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Read the response from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, dwClientID, sizeof(establish_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ if (rv == -1)
+ return SCARD_F_COMM_ERROR;
+
+ memcpy(&scEstablishStruct, &msgStruct.data, sizeof(scEstablishStruct));
+ ntohlEstablishStruct(&scEstablishStruct);
+
+ if (scEstablishStruct.rv != SCARD_S_SUCCESS)
+ return scEstablishStruct.rv;
+
+ *phContext = scEstablishStruct.phContext;
+
+ /*
+ * Allocate the new hContext - if allocator full return an error
+ */
+ rv = SCardAddContext(*phContext, dwClientID);
+
+ return rv;
+}
+
+/**
+ * @brief This function destroys a communication context to the PC/SC Resource
+ * Manager. This must be the last function called in a PC/SC application.
+ *
+ * @param[in] hContext Connection context to be closed.
+ *
+ * @return Connection status.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardReleaseContext(hContext);
+ * @endcode
+ */
+LONG SCardReleaseContext(SCARDCONTEXT hContext)
+{
+ LONG rv;
+ release_struct scReleaseStruct;
+ sharedSegmentMsg msgStruct;
+ LONG dwContextIndex;
+
+ PROFILE_START
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this context has been opened
+ */
+ dwContextIndex = SCardGetContextIndice(hContext);
+ if (dwContextIndex == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ scReleaseStruct.hContext = hContext;
+ scReleaseStruct.rv = 0;
+ htonlReleaseStruct(&scReleaseStruct);
+
+ rv = WrapSHMWrite(SCARD_RELEASE_CONTEXT, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scReleaseStruct),
+ PCSCLITE_MCLIENT_ATTEMPTS, (void *) &scReleaseStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(release_struct), PCSCLITE_CLIENT_ATTEMPTS);
+ memcpy(&scReleaseStruct, &msgStruct.data, sizeof(scReleaseStruct));
+ ntohlReleaseStruct(&scReleaseStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ /*
+ * Remove the local context from the stack
+ */
+ SCardLockThread();
+ SCardRemoveContext(hContext);
+ SCardUnlockThread();
+
+ PROFILE_END
+
+ return scReleaseStruct.rv;
+}
+
+/**
+ * @deprecated
+ * This function is not in Microsoft(R) WinSCard API and is deprecated
+ * in pcsc-lite API.
+ * The function does not do anything except returning \ref SCARD_S_SUCCESS.
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ * @param[in] dwTimeout New timeout value.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ */
+LONG SCardSetTimeout(SCARDCONTEXT hContext, DWORD dwTimeout)
+{
+ /*
+ * Deprecated
+ */
+
+ return SCARD_S_SUCCESS;
+}
+
+/**
+ * This function establishes a connection to the friendly name of the reader
+ * specified in szReader. The first connection will power up and perform a
+ * reset on the card.
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ * @param[in] szReader Reader name to connect to.
+ * @param[in] dwShareMode Mode of connection type: exclusive or shared.
+ * <ul>
+ * <li>\ref SCARD_SHARE_SHARED - This application will allow others to share
+ * the reader.
+ * <li>\ref SCARD_SHARE_EXCLUSIVE - This application will NOT allow others to
+ * share the reader.
+ * <li>\ref SCARD_SHARE_DIRECT - Direct control of the reader, even without a
+ * card. \ref SCARD_SHARE_DIRECT can be used before using SCardControl() to
+ * send control commands to the reader even if a card is not present in the
+ * reader.
+ * </ul>
+ * @param[in] dwPreferredProtocols Desired protocol use.
+ * <ul>
+ * <li>\ref SCARD_PROTOCOL_T0 - Use the T=0 protocol.
+ * <li>\ref SCARD_PROTOCOL_T1 - Use the T=1 protocol.
+ * <li>\ref SCARD_PROTOCOL_RAW - Use with memory type cards.
+ * </ul>
+ * dwPreferredProtocols is a bit mask of acceptable protocols for the
+ * connection. You can use (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1) if you
+ * do not have a preferred protocol.
+ * @param[out] phCard Handle to this connection.
+ * @param[out] pdwActiveProtocol Established protocol to this connection.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hContext handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_INVALID_VALUE Invalid sharing mode, requested protocol, or reader name (\ref SCARD_E_INVALID_VALUE)
+ * @retval SCARD_E_NOT_READY Could not allocate the desired port (\ref SCARD_E_NOT_READY)
+ * @retval SCARD_E_READER_UNAVAILABLE Could not power up the reader or card (\ref SCARD_E_READER_UNAVAILABLE)
+ * @retval SCARD_E_SHARING_VIOLATION Someone else has exclusive rights (\ref SCARD_E_SHARING_VIOLATION)
+ * @retval SCARD_E_UNSUPPORTED_FEATURE Protocol not supported (\ref SCARD_E_UNSUPPORTED_FEATURE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * @endcode
+ */
+LONG SCardConnect(SCARDCONTEXT hContext, LPCSTR szReader,
+ DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE phCard,
+ LPDWORD pdwActiveProtocol)
+{
+ LONG rv;
+ connect_struct scConnectStruct = {0,};
+ sharedSegmentMsg msgStruct = {0,};
+ LONG dwContextIndex;
+
+ PROFILE_START
+
+ /*
+ * Check for NULL parameters
+ */
+ if (phCard == NULL || pdwActiveProtocol == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+ else
+ *phCard = 0;
+
+ if (szReader == NULL)
+ return SCARD_E_UNKNOWN_READER;
+
+ /*
+ * Check for uninitialized strings
+ */
+ if (strlen(szReader) > MAX_READERNAME)
+ return SCARD_E_INVALID_VALUE;
+
+ if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this context has been opened
+ */
+ dwContextIndex = SCardGetContextIndice(hContext);
+ if (dwContextIndex == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ strncpy(scConnectStruct.szReader, szReader, MAX_READERNAME);
+
+ scConnectStruct.hContext = hContext;
+ scConnectStruct.dwShareMode = dwShareMode;
+ scConnectStruct.dwPreferredProtocols = dwPreferredProtocols;
+ scConnectStruct.phCard = *phCard;
+ scConnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
+ htonlConnectStruct(&scConnectStruct);
+
+ rv = WrapSHMWrite(SCARD_CONNECT, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scConnectStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scConnectStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(connect_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ memcpy(&scConnectStruct, &msgStruct.data, sizeof(scConnectStruct));
+ ntohlConnectStruct(&scConnectStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ *phCard = scConnectStruct.phCard;
+ *pdwActiveProtocol = scConnectStruct.pdwActiveProtocol;
+
+ if (scConnectStruct.rv == SCARD_S_SUCCESS)
+ {
+ /*
+ * Keep track of the handle locally
+ */
+ rv = SCardAddHandle(*phCard, dwContextIndex, (LPSTR) szReader);
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return rv;
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return scConnectStruct.rv;
+}
+
+/**
+ * @brief This function reestablishes a connection to a reader that was previously
+ * connected to using SCardConnect().
+ *
+ * In a multi application environment it is possible for an application to reset
+ * the card in shared mode. When this occurs any other application trying to
+ * access certain commands will be returned the value SCARD_W_RESET_CARD. When
+ * this occurs SCardReconnect() must be called in order to acknowledge that
+ * the card was reset and allow it to change it's state accordingly.
+ *
+ * @param[in] hCard Handle to a previous call to connect.
+ * @param[in] dwShareMode Mode of connection type: exclusive/shared.
+ * <ul>
+ * <li>\ref SCARD_SHARE_SHARED - This application will allow others to share
+ * the reader.
+ * <li>\ref SCARD_SHARE_EXCLUSIVE - This application will NOT allow others to
+ * share the reader.
+ * </ul>
+ * @param[in] dwPreferredProtocols Desired protocol use.
+ * <ul>
+ * <li>\ref SCARD_PROTOCOL_T0 - Use the T=0 protocol.
+ * <li>\ref SCARD_PROTOCOL_T1 - Use the T=1 protocol.
+ * <li>\ref SCARD_PROTOCOL_RAW - Use with memory type cards.
+ * </ul>
+ * \p dwPreferredProtocols is a bit mask of acceptable protocols for
+ * the connection. You can use (SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1)
+ * if you do not have a preferred protocol.
+ * @param[in] dwInitialization Desired action taken on the card/reader.
+ * <ul>
+ * <li>\ref SCARD_LEAVE_CARD - Do nothing.
+ * <li>\ref SCARD_RESET_CARD - Reset the card (warm reset).
+ * <li>\ref SCARD_UNPOWER_CARD - Unpower the card (cold reset).
+ * <li>\ref SCARD_EJECT_CARD - Eject the card.
+ * </ul>
+ * @param[out] pdwActiveProtocol Established protocol to this connection.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid \p hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_NOT_READY Could not allocate the desired port (\ref SCARD_E_NOT_READY)
+ * @retval SCARD_E_INVALID_VALUE Invalid sharing mode, requested protocol, or reader name (\ref SCARD_E_INVALID_VALUE)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader has been removed (\ref SCARD_E_READER_UNAVAILABLE)
+ * @retval SCARD_E_UNSUPPORTED_FEATURE Protocol not supported (\ref SCARD_E_UNSUPPORTED_FEATURE)
+ * @retval SCARD_E_SHARING_VIOLATION Someone else has exclusive rights (\ref SCARD_E_SHARING_VIOLATION)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol, dwSendLength, dwRecvLength;
+ * LONG rv;
+ * BYTE pbRecvBuffer[10];
+ * BYTE pbSendBuffer[] = {0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00};
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * ...
+ * dwSendLength = sizeof(pbSendBuffer);
+ * dwRecvLength = sizeof(pbRecvBuffer);
+ * rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength, &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ * / * Card has been reset by another application * /
+ * if (rv == SCARD_W_RESET_CARD)
+ * {
+ * rv = SCardReconnect(hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &dwActiveProtocol);
+ * }
+ * @endcode
+ */
+LONG SCardReconnect(SCARDHANDLE hCard, DWORD dwShareMode,
+ DWORD dwPreferredProtocols, DWORD dwInitialization,
+ LPDWORD pdwActiveProtocol)
+{
+ LONG rv;
+ reconnect_struct scReconnectStruct;
+ sharedSegmentMsg msgStruct;
+ int i;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ if (dwInitialization != SCARD_LEAVE_CARD &&
+ dwInitialization != SCARD_RESET_CARD &&
+ dwInitialization != SCARD_UNPOWER_CARD &&
+ dwInitialization != SCARD_EJECT_CARD)
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ if (!(dwPreferredProtocols & SCARD_PROTOCOL_T0) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_T1) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_RAW) &&
+ !(dwPreferredProtocols & SCARD_PROTOCOL_ANY_OLD))
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ if (pdwActiveProtocol == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ scReconnectStruct.hCard = hCard;
+ scReconnectStruct.dwShareMode = dwShareMode;
+ scReconnectStruct.dwPreferredProtocols = dwPreferredProtocols;
+ scReconnectStruct.dwInitialization = dwInitialization;
+ scReconnectStruct.pdwActiveProtocol = *pdwActiveProtocol;
+ htonlReconnectStruct(&scReconnectStruct);
+
+ rv = WrapSHMWrite(SCARD_RECONNECT, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scReconnectStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scReconnectStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(reconnect_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ memcpy(&scReconnectStruct, &msgStruct.data, sizeof(scReconnectStruct));
+ ntohlReconnectStruct(&scReconnectStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ *pdwActiveProtocol = scReconnectStruct.pdwActiveProtocol;
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return scReconnectStruct.rv;
+}
+
+/**
+ * This function terminates a connection to the connection made through
+ * SCardConnect(). dwDisposition can have the following values:
+ *
+ * @param[in] hCard Connection made from SCardConnect.
+ * @param[in] dwDisposition Reader function to execute.
+ * <ul>
+ * <li>\ref SCARD_LEAVE_CARD - Do nothing.
+ * <li>\ref SCARD_RESET_CARD - Reset the card (warm reset).
+ * <li>\ref SCARD_UNPOWER_CARD - Unpower the card (cold reset).
+ * <li>\ref SCARD_EJECT_CARD - Eject the card.
+ * </ul>
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful(\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid \p hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_INVALID_VALUE - Invalid \p dwDisposition (\ref SCARD_E_INVALID_VALUE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * rv = SCardDisconnect(hCard, SCARD_UNPOWER_CARD);
+ * @endcode
+ */
+LONG SCardDisconnect(SCARDHANDLE hCard, DWORD dwDisposition)
+{
+ LONG rv;
+ disconnect_struct scDisconnectStruct;
+ sharedSegmentMsg msgStruct;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ if (dwDisposition != SCARD_LEAVE_CARD &&
+ dwDisposition != SCARD_RESET_CARD &&
+ dwDisposition != SCARD_UNPOWER_CARD &&
+ dwDisposition != SCARD_EJECT_CARD)
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ scDisconnectStruct.hCard = hCard;
+ scDisconnectStruct.dwDisposition = dwDisposition;
+ htonlDisconnectStruct(&scDisconnectStruct);
+
+ rv = WrapSHMWrite(SCARD_DISCONNECT, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scDisconnectStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scDisconnectStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(disconnect_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ memcpy(&scDisconnectStruct, &msgStruct.data, sizeof(scDisconnectStruct));
+ ntohlDisconnectStruct(&scDisconnectStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ SCardRemoveHandle(hCard);
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return scDisconnectStruct.rv;
+}
+
+/**
+ * @brief This function establishes a temporary exclusive access mode for
+ * doing a series of commands or transaction.
+ *
+ * You might want to use this when you are selecting a few files and then
+ * writing a large file so you can make sure that another application will
+ * not change the current file. If another application has a lock on this
+ * reader or this application is in \ref SCARD_SHARE_EXCLUSIVE there will be no
+ * action taken.
+ *
+ * @param[in] hCard Connection made from SCardConnect.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_SHARING_VIOLATION Someone else has exclusive rights (\ref SCARD_E_SHARING_VIOLATION)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader has been removed (\ref SCARD_E_READER_UNAVAILABLE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * rv = SCardBeginTransaction(hCard);
+ * ...
+ * / * Do some transmit commands * /
+ * @endcode
+ */
+LONG SCardBeginTransaction(SCARDHANDLE hCard)
+{
+
+ LONG rv;
+ begin_struct txBeginStruct = {0,}, rxBeginStruct = {0,};
+ int i;
+ sharedSegmentMsg msgStruct = {0,};
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ secdebug("pcscd", "SCardBeginTransaction: initial request: hCard: 0x%08X", hCard);
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ txBeginStruct.hCard = hCard;
+ htonlBeginStruct(&txBeginStruct);
+
+ /*
+ * Query the server every so often until the sharing violation ends
+ * and then hold the lock for yourself.
+ */
+
+ do
+ {
+ rv = WrapSHMWrite(SCARD_BEGIN_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
+ sizeof(txBeginStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &txBeginStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(begin_struct), PCSCLITE_CLIENT_ATTEMPTS);
+ memcpy(&rxBeginStruct, &msgStruct.data, sizeof(rxBeginStruct));
+ ntohlBeginStruct(&rxBeginStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ }
+ while (rxBeginStruct.rv == SCARD_E_SHARING_VIOLATION);
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+ secdebug("pcscd", "SCardBeginTransaction: hCard: 0x%08X, returning: 0x%08X", rxBeginStruct.hCard, rxBeginStruct.rv);
+
+ return rxBeginStruct.rv;
+}
+
+/**
+ * @brief This function ends a previously begun transaction.
+ *
+ * The calling application must be the owner of the previously begun
+ * transaction or an error will occur.
+ *
+ * @param[in] hCard Connection made from SCardConnect.
+ * @param[in] dwDisposition Action to be taken on the reader.
+ * The disposition action is not currently used in this release.
+ * <ul>
+ * <li>\ref SCARD_LEAVE_CARD - Do nothing.
+ * <li>\ref SCARD_RESET_CARD - Reset the card.
+ * <li>\ref SCARD_UNPOWER_CARD - Unpower the card.
+ * <li>\ref SCARD_EJECT_CARD - Eject the card.
+ * </ul>
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_SHARING_VIOLATION Someone else has exclusive rights (\ref SCARD_E_SHARING_VIOLATION)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader has been removed (\ref SCARD_E_READER_UNAVAILABLE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * rv = SCardBeginTransaction(hCard);
+ * ...
+ * / * Do some transmit commands * /
+ * ...
+ * rv = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
+ * @endcode
+ */
+LONG SCardEndTransaction(SCARDHANDLE hCard, DWORD dwDisposition)
+{
+ LONG rv;
+ end_struct scEndStruct;
+ sharedSegmentMsg msgStruct;
+ int randnum, i;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ secdebug("pcscd", "SCardEndTransaction: initial request: hCard: 0x%08X, dwDisposition: 0x%04X",
+ hCard, dwDisposition);
+ /*
+ * Zero out everything
+ */
+ randnum = 0;
+
+ if (dwDisposition != SCARD_LEAVE_CARD &&
+ dwDisposition != SCARD_RESET_CARD &&
+ dwDisposition != SCARD_UNPOWER_CARD &&
+ dwDisposition != SCARD_EJECT_CARD)
+ {
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ scEndStruct.hCard = hCard;
+ scEndStruct.dwDisposition = dwDisposition;
+ htonlEndStruct(&scEndStruct);
+
+ rv = WrapSHMWrite(SCARD_END_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scEndStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scEndStruct);
+ secdebug("pcscd", "SCardEndTransaction: WrapSHMWrite result: 0x%08X", rv);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(end_struct), PCSCLITE_CLIENT_ATTEMPTS);
+ secdebug("pcscd", "SCardEndTransaction: SHMClientRead result: 0x%08X", rv);
+
+ memcpy(&scEndStruct, &msgStruct.data, sizeof(scEndStruct));
+ ntohlEndStruct(&scEndStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ /*
+ * This helps prevent starvation
+ */
+ randnum = SYS_Random(randnum, 1000.0, 10000.0);
+ SYS_USleep(randnum);
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ secdebug("pcscd", "SCardEndTransaction: returning: 0x%08X", scEndStruct.rv);
+ return scEndStruct.rv;
+}
+
+/**
+ * @deprecated
+ * This function is not in Microsoft(R) WinSCard API and is deprecated
+ * in pcsc-lite API.
+ */
+LONG SCardCancelTransaction(SCARDHANDLE hCard)
+{
+ LONG rv;
+ cancel_struct scCancelStruct;
+ sharedSegmentMsg msgStruct;
+ int i;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ scCancelStruct.hCard = hCard;
+ htonlCancelStruct(&scCancelStruct);
+
+ rv = WrapSHMWrite(SCARD_CANCEL_TRANSACTION, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scCancelStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scCancelStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(cancel_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ memcpy(&scCancelStruct, &msgStruct.data, sizeof(scCancelStruct));
+ ntohlCancelStruct(&scCancelStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return scCancelStruct.rv;
+}
+
+/**
+ * @brief This function returns the current status of the reader connected to by hCard.
+ *
+ * It's friendly name will be stored in szReaderName. pcchReaderLen will be
+ * the size of the allocated buffer for szReaderName, while pcbAtrLen will
+ * be the size of the allocated buffer for pbAtr. If either of these is too
+ * small, the function will return with \ref SCARD_E_INSUFFICIENT_BUFFER and the
+ * necessary size in pcchReaderLen and pcbAtrLen. The current state, and
+ * protocol will be stored in pdwState and pdwProtocol respectively.
+ *
+ * @param[in] hCard Connection made from SCardConnect.
+ * @param mszReaderNames [inout] Friendly name of this reader.
+ * @param pcchReaderLen [inout] Size of the szReaderName multistring.
+ * @param[out] pdwState Current state of this reader. pdwState
+ * is a DWORD possibly OR'd with the following values:
+ * <ul>
+ * <li>\ref SCARD_ABSENT - There is no card in the reader.
+ * <li>\ref SCARD_PRESENT - There is a card in the reader, but it has not
+ * been moved into position for use.
+ * <li>\ref SCARD_SWALLOWED - There is a card in the reader in position for
+ * use. The card is not powered.
+ * <li>\ref SCARD_POWERED - Power is being provided to the card, but the
+ * reader driver is unaware of the mode of the card.
+ * <li>\ref SCARD_NEGOTIABLE - The card has been reset and is awaiting PTS
+ * negotiation.
+ * <li>\ref SCARD_SPECIFIC - The card has been reset and specific
+ * communication protocols have been established.
+ * </ul>
+ * @param[out] pdwProtocol Current protocol of this reader.
+ * <ul>
+ * <li>\ref SCARD_PROTOCOL_T0 Use the T=0 protocol.
+ * <li>\ref SCARD_PROTOCOL_T1 Use the T=1 protocol.
+ * </ul>
+ * @param[out] pbAtr Current ATR of a card in this reader.
+ * @param[out] pcbAtrLen Length of ATR.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_INSUFFICIENT_BUFFER Not enough allocated memory for szReaderName or for pbAtr (\ref SCARD_E_INSUFFICIENT_BUFFER)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader has been removed (\ref SCARD_E_READER_UNAVAILABLE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * DWORD dwState, dwProtocol, dwAtrLen, dwReaderLen;
+ * BYTE pbAtr[MAX_ATR_SIZE];
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * ...
+ * dwAtrLen = sizeof(pbAtr);
+ * rv=SCardStatus(hCard, NULL, &dwReaderLen, &dwState, &dwProtocol, pbAtr, &dwAtrLen);
+ * @endcode
+ */
+LONG SCardStatus(SCARDHANDLE hCard, LPSTR mszReaderNames,
+ LPDWORD pcchReaderLen, LPDWORD pdwState,
+ LPDWORD pdwProtocol, LPBYTE pbAtr, LPDWORD pcbAtrLen)
+{
+ DWORD dwReaderLen, atrOutputBufferSize;
+ LONG rv;
+ int i;
+ status_struct scStatusStruct;
+ sharedSegmentMsg msgStruct;
+ DWORD dwContextIndex, dwChannelIndex;
+ char *r;
+
+ PROFILE_START
+
+ /*
+ * Check for NULL parameters
+ */
+
+ if (pcchReaderLen == NULL || pcbAtrLen == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+
+ /* length passed from caller */
+ dwReaderLen = *pcchReaderLen;
+ atrOutputBufferSize = *pcbAtrLen;
+
+ /* default output values */
+ if (pdwState)
+ *pdwState = 0;
+
+ if (pdwProtocol)
+ *pdwProtocol = 0;
+
+ *pcchReaderLen = 0;
+ *pcbAtrLen = 0;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ /* initialise the structure */
+ memset(&scStatusStruct, 0, sizeof(scStatusStruct));
+ scStatusStruct.hCard = hCard;
+
+ /* those sizes need to be initialised */
+ scStatusStruct.pcchReaderLen = sizeof(scStatusStruct.mszReaderNames);
+ scStatusStruct.pcbAtrLen = sizeof(scStatusStruct.pbAtr);
+ htonlStatusStruct(&scStatusStruct);
+
+ rv = WrapSHMWrite(SCARD_STATUS, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scStatusStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scStatusStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(status_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ memcpy(&scStatusStruct, &msgStruct.data, sizeof(scStatusStruct));
+ ntohlStatusStruct(&scStatusStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ rv = scStatusStruct.rv;
+ if (rv != SCARD_S_SUCCESS && rv != SCARD_E_INSUFFICIENT_BUFFER)
+ {
+ /*
+ * An event must have occurred
+ */
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return rv;
+ }
+
+ /*
+ * Now continue with the client side SCardStatus
+ */
+
+ *pcchReaderLen = strlen(psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName) + 1;
+ *pcbAtrLen = SharedReaderState_CardAtrLength(readerStates[i]);
+
+ if (pdwState)
+ *pdwState = SharedReaderState_State(readerStates[i]);
+
+ if (pdwProtocol)
+ *pdwProtocol = SharedReaderState_Protocol(readerStates[i]);
+
+ /* return SCARD_E_INSUFFICIENT_BUFFER only if buffer pointer is non NULL */
+ if (mszReaderNames)
+ {
+ if (*pcchReaderLen > dwReaderLen)
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+
+ strncpy(mszReaderNames,
+ psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName,
+ dwReaderLen);
+ }
+
+ if (pbAtr)
+ {
+ if (*pcbAtrLen > atrOutputBufferSize)
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+
+ memcpy(pbAtr, SharedReaderState_CardAtr(readerStates[i]),
+ min(*pcbAtrLen, atrOutputBufferSize));
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return rv;
+}
+
+/**
+ * @brief This function receives a structure or list of structures containing
+ * reader names. It then blocks for a change in state to occur on any of the
+ * OR'd values contained in dwCurrentState for a maximum blocking time of
+ * dwTimeout or forever if INFINITE is used.
+ *
+ * The new event state will be contained in dwEventState. A status change might
+ * be a card insertion or removal event, a change in ATR, etc.
+ *
+ * This function will block for reader availability if cReaders is equal to
+ * zero and rgReaderStates is NULL.
+ *
+ * @code
+ * typedef struct {
+ * LPCSTR szReader; // Reader name
+ * LPVOID pvUserData; // User defined data
+ * DWORD dwCurrentState; // Current state of reader
+ * DWORD dwEventState; // Reader state after a state change
+ * DWORD cbAtr; // ATR Length, usually MAX_ATR_SIZE
+ * BYTE rgbAtr[MAX_ATR_SIZE]; // ATR Value
+ * } SCARD_READERSTATE;
+ * ...
+ * typedef SCARD_READERSTATE *PSCARD_READERSTATE, **LPSCARD_READERSTATE;
+ * ...
+ * @endcode
+ *
+ * Value of dwCurrentState and dwEventState:
+ * <ul>
+ * <li>\ref SCARD_STATE_UNAWARE The application is unaware of the current
+ * state, and would like to know. The use of this value results in an
+ * immediate return from state transition monitoring services. This is
+ * represented by all bits set to zero.
+ * <li>\ref SCARD_STATE_IGNORE This reader should be ignored
+ * <li>\ref SCARD_STATE_CHANGED There is a difference between the state believed
+ * by the application, and the state known by the resource manager.
+ * When this bit is set, the application may assume a significant state
+ * change has occurred on this reader.
+ * <li>\ref SCARD_STATE_UNKNOWN The given reader name is not recognized by the
+ * resource manager. If this bit is set, then \ref SCARD_STATE_CHANGED and
+ * \ref SCARD_STATE_IGNORE will also be set
+ * <li>\ref SCARD_STATE_UNAVAILABLE The actual state of this reader is not
+ * available. If this bit is set, then all the following bits are clear.
+ * <li>\ref SCARD_STATE_EMPTY There is no card in the reader. If this bit is set,
+ * all the following bits will be clear
+ * <li>\ref SCARD_STATE_PRESENT There is a card in the reader
+ * <li>\ref SCARD_STATE_ATRMATCH There is a card in the reader with an ATR
+ * matching one of the target cards. If this bit is set,
+ * \ref SCARD_STATE_PRESENT will also be set. This bit is only returned on
+ * the SCardLocateCards() function.
+ * <li>\ref SCARD_STATE_EXCLUSIVE The card in the reader is allocated for
+ * exclusive use by another application. If this bit is set,
+ * \ref SCARD_STATE_PRESENT will also be set.
+ * <li>\ref SCARD_STATE_INUSE The card in the reader is in use by one or more
+ * other applications, but may be connected to in shared mode. If this
+ * bit is set, \ref SCARD_STATE_PRESENT will also be set.
+ * <li>\ref SCARD_STATE_MUTE There is an unresponsive card in the reader.
+ * </ul>
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ * @param[in] dwTimeout Maximum waiting time (in miliseconds) for status
+ * change, zero (or INFINITE) for infinite.
+ * @param rgReaderStates [inout] Structures of readers with current states.
+ * @param[in] cReaders Number of structures.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_VALUE Invalid States, reader name, etc (\ref SCARD_E_INVALID_VALUE)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hContext handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader is unavailable (\ref SCARD_E_READER_UNAVAILABLE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * SCARD_READERSTATE_A rgReaderStates[1];
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * ...
+ * rgReaderStates[0].szReader = "Reader X";
+ * rgReaderStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
+ * ...
+ * rv = SCardGetStatusChange(hContext, INFINITE, rgReaderStates, 1);
+ * printf("reader state: 0x%04X\n", rgReaderStates[0].dwEventState);
+ * @endcode
+ */
+LONG SCardGetStatusChange(SCARDCONTEXT hContext, DWORD dwTimeout,
+ LPSCARD_READERSTATE_A rgReaderStates, DWORD cReaders)
+{
+ PSCARD_READERSTATE_A currReader;
+ PREADER_STATE rContext;
+ DWORD dwTime = 0;
+ DWORD dwState;
+ DWORD dwBreakFlag = 0;
+ int j;
+ LONG dwContextIndex;
+ int currentReaderCount = 0;
+
+ PROFILE_START
+
+ if (rgReaderStates == NULL && cReaders > 0)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this context has been opened
+ */
+
+ dwContextIndex = SCardGetContextIndice(hContext);
+ if (dwContextIndex == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ /*
+ * Application is waiting for a reader - return the first available
+ * reader
+ */
+
+ if (cReaders == 0)
+ {
+ while (1)
+ {
+ int i;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if (SharedReaderState_ReaderID(readerStates[i]) != 0)
+ {
+ /*
+ * Reader was found
+ */
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return SCARD_S_SUCCESS;
+ }
+ }
+
+ if (dwTimeout == 0)
+ {
+ /*
+ * return immediately - no reader available
+ */
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ SYS_USleep(PCSCLITE_STATUS_WAIT);
+
+ if (dwTimeout != INFINITE)
+ {
+ dwTime += PCSCLITE_STATUS_WAIT;
+
+ if (dwTime >= (dwTimeout * 1000))
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return SCARD_E_TIMEOUT;
+ }
+ }
+ }
+ }
+ else
+ if (cReaders >= PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_INVALID_VALUE;
+ }
+
+ /*
+ * Check the integrity of the reader states structures
+ */
+
+ for (j = 0; j < cReaders; j++)
+ {
+ currReader = &rgReaderStates[j];
+
+ if (currReader->szReader == NULL)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_INVALID_VALUE;
+ }
+ }
+
+ /*
+ * End of search for readers
+ */
+
+ /*
+ * Clear the event state for all readers
+ */
+ for (j = 0; j < cReaders; j++)
+ {
+ currReader = &rgReaderStates[j];
+ currReader->dwEventState = 0;
+ }
+
+ /*
+ * Now is where we start our event checking loop
+ */
+
+ Log1(PCSC_LOG_DEBUG, "Event Loop Start");
+
+ psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_BLOCKING;
+
+ /* Get the initial reader count on the system */
+ for (j=0; j < PCSCLITE_MAX_READERS_CONTEXTS; j++)
+ if (SharedReaderState_ReaderID(readerStates[j]) != 0)
+ currentReaderCount++;
+
+ j = 0;
+
+ do
+ {
+ int newReaderCount = 0;
+ char ReaderCountChanged = 0;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return SCARD_E_NO_SERVICE;
+ }
+
+ if (j == 0)
+ {
+ int i;
+
+ for (i=0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ if (SharedReaderState_ReaderID(readerStates[i]) != 0)
+ newReaderCount++;
+
+ if (newReaderCount != currentReaderCount)
+ {
+ Log1(PCSC_LOG_INFO, "Reader list changed");
+ ReaderCountChanged = 1;
+ currentReaderCount = newReaderCount;
+ }
+ }
+ currReader = &rgReaderStates[j];
+
+ /************ Look for IGNORED readers ****************************/
+
+ if (currReader->dwCurrentState & SCARD_STATE_IGNORE)
+ currReader->dwEventState = SCARD_STATE_IGNORE;
+ else
+ {
+ LPSTR lpcReaderName;
+ int i;
+
+ /************ Looks for correct readernames *********************/
+
+ lpcReaderName = (char *) currReader->szReader;
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], lpcReaderName))
+ break;
+ }
+
+ /*
+ * The requested reader name is not recognized
+ */
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
+ currReader->dwEventState = SCARD_STATE_UNKNOWN;
+ else
+ {
+ currReader->dwEventState =
+ SCARD_STATE_UNKNOWN | SCARD_STATE_CHANGED;
+ /*
+ * Spec says use SCARD_STATE_IGNORE but a removed USB
+ * reader with eventState fed into currentState will
+ * be ignored forever
+ */
+ dwBreakFlag = 1;
+ }
+ }
+ else
+ {
+
+ /*
+ * The reader has come back after being away
+ */
+ if (currReader->dwCurrentState & SCARD_STATE_UNKNOWN)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
+ dwBreakFlag = 1;
+ }
+
+ /*****************************************************************/
+
+ /*
+ * Set the reader status structure
+ */
+ rContext = readerStates[i];
+
+ /*
+ * Now we check all the Reader States
+ */
+ dwState = SharedReaderState_State(rContext);
+
+ /*********** Check if the reader is in the correct state ********/
+ if (dwState & SCARD_UNKNOWN)
+ {
+ /*
+ * App thinks reader is in bad state and it is
+ */
+ if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
+ currReader->dwEventState = SCARD_STATE_UNAVAILABLE;
+ else
+ {
+ /*
+ * App thinks reader is in good state and it is
+ * not
+ */
+ currReader->dwEventState = SCARD_STATE_CHANGED |
+ SCARD_STATE_UNAVAILABLE;
+ dwBreakFlag = 1;
+ }
+ }
+ else
+ {
+ /*
+ * App thinks reader in bad state but it is not
+ */
+ if (currReader-> dwCurrentState & SCARD_STATE_UNAVAILABLE)
+ {
+ currReader->dwEventState &=
+ ~SCARD_STATE_UNAVAILABLE;
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ }
+
+ /********** Check for card presence in the reader **************/
+
+ if (dwState & SCARD_PRESENT)
+ {
+ /* card present but not yet powered up */
+ if (0 == SharedReaderState_CardAtrLength(rContext))
+ /* Allow the status thread to convey information */
+ SYS_USleep(PCSCLITE_STATUS_POLL_RATE + 10);
+
+ currReader->cbAtr = SharedReaderState_CardAtrLength(rContext);
+ memcpy(currReader->rgbAtr, SharedReaderState_CardAtr(rContext),
+ currReader->cbAtr);
+ }
+ else
+ currReader->cbAtr = 0;
+
+ /*
+ * Card is now absent
+ */
+ if (dwState & SCARD_ABSENT)
+ {
+ currReader->dwEventState |= SCARD_STATE_EMPTY;
+ currReader->dwEventState &= ~SCARD_STATE_PRESENT;
+ currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
+ currReader->dwEventState &= ~SCARD_STATE_IGNORE;
+ currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
+ currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
+ currReader->dwEventState &= ~SCARD_STATE_ATRMATCH;
+ currReader->dwEventState &= ~SCARD_STATE_MUTE;
+ currReader->dwEventState &= ~SCARD_STATE_INUSE;
+
+ /*
+ * After present the rest are assumed
+ */
+ if (currReader->dwCurrentState & SCARD_STATE_PRESENT
+ || currReader->dwCurrentState & SCARD_STATE_ATRMATCH
+ || currReader->dwCurrentState & SCARD_STATE_EXCLUSIVE
+ || currReader->dwCurrentState & SCARD_STATE_INUSE)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+
+ /*
+ * Card is now present
+ */
+ } else if (dwState & SCARD_PRESENT)
+ {
+ currReader->dwEventState |= SCARD_STATE_PRESENT;
+ currReader->dwEventState &= ~SCARD_STATE_EMPTY;
+ currReader->dwEventState &= ~SCARD_STATE_UNAWARE;
+ currReader->dwEventState &= ~SCARD_STATE_IGNORE;
+ currReader->dwEventState &= ~SCARD_STATE_UNKNOWN;
+ currReader->dwEventState &= ~SCARD_STATE_UNAVAILABLE;
+ currReader->dwEventState &= ~SCARD_STATE_MUTE;
+
+ if (currReader->dwCurrentState & SCARD_STATE_EMPTY)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+
+ if (dwState & SCARD_SWALLOWED)
+ {
+ if (currReader->dwCurrentState & SCARD_STATE_MUTE)
+ currReader->dwEventState |= SCARD_STATE_MUTE;
+ else
+ {
+ currReader->dwEventState |= SCARD_STATE_MUTE;
+ if (currReader->dwCurrentState
+ != SCARD_STATE_UNAWARE)
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ }
+ else
+ {
+ /*
+ * App thinks card is mute but it is not
+ */
+ if (currReader->dwCurrentState & SCARD_STATE_MUTE)
+ {
+ currReader->dwEventState |=
+ SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ }
+ }
+
+ /*
+ * Now figure out sharing modes
+ */
+ DWORD sharing = SharedReaderState_Sharing(rContext);
+ if (sharing == -1)
+ {
+ currReader->dwEventState |= SCARD_STATE_EXCLUSIVE;
+ currReader->dwEventState &= ~SCARD_STATE_INUSE;
+ if (currReader->dwCurrentState & SCARD_STATE_INUSE)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ }
+ else if (sharing >= 1)
+ {
+ /*
+ * A card must be inserted for it to be INUSE
+ */
+ if (dwState & SCARD_PRESENT)
+ {
+ currReader->dwEventState |= SCARD_STATE_INUSE;
+ currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
+ if (currReader-> dwCurrentState & SCARD_STATE_EXCLUSIVE)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ }
+ }
+ else if (sharing == 0)
+ {
+ currReader->dwEventState &= ~SCARD_STATE_INUSE;
+ currReader->dwEventState &= ~SCARD_STATE_EXCLUSIVE;
+
+ if (currReader->dwCurrentState & SCARD_STATE_INUSE)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ else if (currReader-> dwCurrentState
+ & SCARD_STATE_EXCLUSIVE)
+ {
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+ }
+
+ if (currReader->dwCurrentState == SCARD_STATE_UNAWARE)
+ {
+ /*
+ * Break out of the while .. loop and return status
+ * once all the status's for all readers is met
+ */
+ currReader->dwEventState |= SCARD_STATE_CHANGED;
+ dwBreakFlag = 1;
+ }
+
+ } /* End of SCARD_STATE_UNKNOWN */
+
+ } /* End of SCARD_STATE_IGNORE */
+
+ /*
+ * Counter and resetter
+ */
+ j = j + 1;
+ if (j == cReaders)
+ {
+ if (!dwBreakFlag)
+ {
+ /* break if the reader count changed,
+ * so that the calling application can update
+ * the reader list
+ */
+ if (ReaderCountChanged)
+ break;
+ }
+ j = 0;
+ }
+
+ /*
+ * Declare all the break conditions
+ */
+
+ if (psContextMap[dwContextIndex].contextBlockStatus
+ == BLOCK_STATUS_RESUME)
+ break;
+
+ /*
+ * Break if UNAWARE is set and all readers have been checked
+ */
+ if ((dwBreakFlag == 1) && (j == 0))
+ break;
+
+ /*
+ * Timeout has occurred and all readers checked
+ */
+ if ((dwTimeout == 0) && (j == 0))
+ break;
+
+ if (dwTimeout != INFINITE && dwTimeout != 0)
+ {
+ /*
+ * If time is greater than timeout and all readers have been
+ * checked
+ */
+ if ((dwTime >= (dwTimeout * 1000)) && (j == 0))
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_TIMEOUT;
+ }
+ }
+
+ /*
+ * Only sleep once for each cycle of reader checks.
+ */
+ if (j == 0)
+ {
+ SYS_USleep(PCSCLITE_STATUS_WAIT);
+ dwTime += PCSCLITE_STATUS_WAIT;
+ }
+ }
+ while (1);
+
+ Log1(PCSC_LOG_DEBUG, "Event Loop End");
+
+ if (psContextMap[dwContextIndex].contextBlockStatus ==
+ BLOCK_STATUS_RESUME)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_CANCELLED;
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return SCARD_S_SUCCESS;
+}
+
+#undef SCardControl
+
+LONG SCardControl(SCARDHANDLE hCard, const void *pbSendBuffer,
+ DWORD cbSendLength, void *pbRecvBuffer, LPDWORD pcbRecvLength)
+{
+
+ SCARD_IO_REQUEST pioSendPci, pioRecvPci;
+
+ pioSendPci.dwProtocol = SCARD_PROTOCOL_RAW;
+ pioRecvPci.dwProtocol = SCARD_PROTOCOL_RAW;
+
+ return SCardTransmit(hCard, &pioSendPci, pbSendBuffer, cbSendLength,
+ &pioRecvPci, pbRecvBuffer, pcbRecvLength);
+}
+
+/**
+ * @brief This function sends a command directly to the IFD Handler to be
+ * processed by the reader.
+ *
+ * This is useful for creating client side reader drivers for functions like
+ * PIN pads, biometrics, or other extensions to the normal smart card reader
+ * that are not normally handled by PC/SC.
+ *
+ * @note the API of this function changed. In pcsc-lite 1.2.0 and before the
+ * API was not Windows(R) PC/SC compatible. This has been corrected.
+ *
+ * @param[in] hCard Connection made from SCardConnect.
+ * @param[in] dwControlCode Control code for the operation.\n
+ * <a href="http://pcsclite.alioth.debian.org/pcsc-lite/node26.html#Some_SCardControl_commands">
+ * Click here</a> for a list of supported commands by some drivers.
+ * @param[in] pbSendBuffer Command to send to the reader.
+ * @param[in] cbSendLength Length of the command.
+ * @param[out] pbRecvBuffer Response from the reader.
+ * @param[in] cbRecvLength Length of the response buffer.
+ * @param[out] lpBytesReturned Length of the response.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NOT_TRANSACTED Data exchange not successful (\ref SCARD_E_NOT_TRANSACTED)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_INVALID_VALUE Invalid value was presented (\ref SCARD_E_INVALID_VALUE)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader has been removed(\ref SCARD_E_READER_UNAVAILABLE)
+ * @retval SCARD_W_RESET_CARD The card has been reset by another application (\ref SCARD_W_RESET_CARD)
+ * @retval SCARD_W_REMOVED_CARD The card has been removed from the reader(\ref SCARD_W_REMOVED_CARD)
+ *
+ * @test
+ * @code
+ * LONG rv;
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol, dwSendLength, dwRecvLength;
+ * BYTE pbRecvBuffer[10];
+ * BYTE pbSendBuffer[] = { 0x06, 0x00, 0x0A, 0x01, 0x01, 0x10 0x00 };
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_RAW &hCard, &dwActiveProtocol);
+ * dwSendLength = sizeof(pbSendBuffer);
+ * dwRecvLength = sizeof(pbRecvBuffer);
+ * rv = SCardControl(hCard, 0x42000001, pbSendBuffer, dwSendLength, pbRecvBuffer, sizeof(pbRecvBuffer), &dwRecvLength);
+ * @endcode
+ */
+int32_t SCardControl132(SCARDHANDLE hCard, DWORD dwControlCode, LPCVOID pbSendBuffer,
+ DWORD cbSendLength, LPVOID pbRecvBuffer, DWORD cbRecvLength,
+ LPDWORD lpBytesReturned)
+{
+ // Real implementation to be provided as part of:
+ // <rdar://problem/4711576> Support the new SCardControl function
+ //
+
+ LONG rv;
+ control_struct scControlStruct;
+ sharedSegmentMsg msgStruct;
+ int i;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ /* 0 bytes received by default */
+ if (NULL != lpBytesReturned)
+ *lpBytesReturned = 0;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
+ || (cbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+
+ if ((cbSendLength > MAX_BUFFER_SIZE) || (cbRecvLength > MAX_BUFFER_SIZE))
+ {
+ /* extended control */
+ unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
+ control_struct_extended *scControlStructExtended = (control_struct_extended *)buffer;
+ sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
+
+ scControlStructExtended->hCard = hCard;
+ scControlStructExtended->dwControlCode = dwControlCode;
+ scControlStructExtended->cbSendLength = cbSendLength;
+ scControlStructExtended->cbRecvLength = cbRecvLength;
+ scControlStructExtended->size = sizeof(*scControlStructExtended) + cbSendLength;
+ memcpy(scControlStructExtended->data, pbSendBuffer, cbSendLength);
+
+ size_t csesize = scControlStructExtended->size; // remember it from before byte swap
+ htonlControlStructExtended(scControlStructExtended);
+ rv = WrapSHMWrite(SCARD_CONTROL_EXTENDED,
+ psContextMap[dwContextIndex].dwClientID,
+ csesize,
+ PCSCLITE_CLIENT_ATTEMPTS, buffer);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ /* read the first block */
+ rv = SHMClientReadMessage(pmsgStruct, psContextMap[dwContextIndex].dwClientID, 0, PCSCLITE_CLIENT_ATTEMPTS);
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ /* we receive a sharedSegmentMsg and not a control_struct_extended */
+ scControlStructExtended = (control_struct_extended *)&(pmsgStruct -> data);
+ ntohlControlStructExtended(scControlStructExtended);
+
+ /* a second block is present */
+ if (scControlStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
+ scControlStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_CLIENT_ATTEMPTS);
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+ }
+
+ if (scControlStructExtended -> rv == SCARD_S_SUCCESS)
+ {
+ /*
+ * Copy and zero it so any secret information is not leaked
+ */
+ memcpy(pbRecvBuffer, scControlStructExtended -> data,
+ scControlStructExtended -> pdwBytesReturned);
+ memset(scControlStructExtended -> data, 0x00,
+ scControlStructExtended -> pdwBytesReturned);
+ }
+
+ if (NULL != lpBytesReturned)
+ *lpBytesReturned = scControlStructExtended -> pdwBytesReturned;
+
+ rv = scControlStructExtended -> rv;
+ }
+ else
+ {
+ scControlStruct.hCard = hCard;
+ scControlStruct.dwControlCode = dwControlCode;
+ scControlStruct.cbSendLength = cbSendLength;
+ scControlStruct.cbRecvLength = cbRecvLength;
+ memcpy(scControlStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
+ htonlControlStruct(&scControlStruct);
+
+ rv = WrapSHMWrite(SCARD_CONTROL, psContextMap[dwContextIndex].dwClientID,
+ sizeof(scControlStruct), PCSCLITE_CLIENT_ATTEMPTS, &scControlStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(control_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ memcpy(&scControlStruct, &msgStruct.data, sizeof(scControlStruct));
+ ntohlControlStruct(&scControlStruct);
+
+ if (NULL != lpBytesReturned)
+ *lpBytesReturned = scControlStruct.dwBytesReturned;
+
+ if (scControlStruct.rv == SCARD_S_SUCCESS)
+ {
+ /*
+ * Copy and zero it so any secret information is not leaked
+ */
+ memcpy(pbRecvBuffer, scControlStruct.pbRecvBuffer,
+ scControlStruct.cbRecvLength);
+ memset(scControlStruct.pbRecvBuffer, 0x00,
+ sizeof(scControlStruct.pbRecvBuffer));
+ }
+
+ rv = scControlStruct.rv;
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return rv;
+}
+
+/**
+ * This function get an attribute from the IFD Handler. The list of possible
+ * attributes is available in the file \c pcsclite.h.
+ *
+ * @param[in] hCard Connection made from SCardConnect().
+ * @param[in] dwAttrId Identifier for the attribute to get.
+ * <ul>
+ * <li>\ref SCARD_ATTR_ASYNC_PROTOCOL_TYPES
+ * <li>\ref SCARD_ATTR_ATR_STRING
+ * <li>\ref SCARD_ATTR_CHANNEL_ID
+ * <li>\ref SCARD_ATTR_CHARACTERISTICS
+ * <li>\ref SCARD_ATTR_CURRENT_BWT
+ * <li>\ref SCARD_ATTR_CURRENT_CLK
+ * <li>\ref SCARD_ATTR_CURRENT_CWT
+ * <li>\ref SCARD_ATTR_CURRENT_D
+ * <li>\ref SCARD_ATTR_CURRENT_EBC_ENCODING
+ * <li>\ref SCARD_ATTR_CURRENT_F
+ * <li>\ref SCARD_ATTR_CURRENT_IFSC
+ * <li>\ref SCARD_ATTR_CURRENT_IFSD
+ * <li>\ref SCARD_ATTR_CURRENT_IO_STATE
+ * <li>\ref SCARD_ATTR_CURRENT_N
+ * <li>\ref SCARD_ATTR_CURRENT_PROTOCOL_TYPE
+ * <li>\ref SCARD_ATTR_CURRENT_W
+ * <li>\ref SCARD_ATTR_DEFAULT_CLK
+ * <li>\ref SCARD_ATTR_DEFAULT_DATA_RATE
+ * <li>\ref SCARD_ATTR_DEVICE_FRIENDLY_NAME_A
+ * <li>\ref SCARD_ATTR_DEVICE_FRIENDLY_NAME_W
+ * <li>\ref SCARD_ATTR_DEVICE_IN_USE
+ * <li>\ref SCARD_ATTR_DEVICE_SYSTEM_NAME_A
+ * <li>\ref SCARD_ATTR_DEVICE_SYSTEM_NAME_W
+ * <li>\ref SCARD_ATTR_DEVICE_UNIT
+ * <li>\ref SCARD_ATTR_ESC_AUTHREQUEST
+ * <li>\ref SCARD_ATTR_ESC_CANCEL
+ * <li>\ref SCARD_ATTR_ESC_RESET
+ * <li>\ref SCARD_ATTR_EXTENDED_BWT
+ * <li>\ref SCARD_ATTR_ICC_INTERFACE_STATUS
+ * <li>\ref SCARD_ATTR_ICC_PRESENCE
+ * <li>\ref SCARD_ATTR_ICC_TYPE_PER_ATR
+ * <li>\ref SCARD_ATTR_MAX_CLK
+ * <li>\ref SCARD_ATTR_MAX_DATA_RATE
+ * <li>\ref SCARD_ATTR_MAX_IFSD
+ * <li>\ref SCARD_ATTR_MAXINPUT
+ * <li>\ref SCARD_ATTR_POWER_MGMT_SUPPORT
+ * <li>\ref SCARD_ATTR_SUPRESS_T1_IFS_REQUEST
+ * <li>\ref SCARD_ATTR_SYNC_PROTOCOL_TYPES
+ * <li>\ref SCARD_ATTR_USER_AUTH_INPUT_DEVICE
+ * <li>\ref SCARD_ATTR_USER_TO_CARD_AUTH_DEVICE
+ * <li>\ref SCARD_ATTR_VENDOR_IFD_SERIAL_NO
+ * <li>\ref SCARD_ATTR_VENDOR_IFD_TYPE
+ * <li>\ref SCARD_ATTR_VENDOR_IFD_VERSION
+ * <li>\ref SCARD_ATTR_VENDOR_NAME
+ * </ul>
+ *
+ * Not all the dwAttrId values listed above may be implemented in the IFD
+ * Handler you are using. And some dwAttrId values not listed here may be
+ * implemented.
+ *
+ * @param[out] pbAttr Pointer to a buffer that receives the attribute.
+ * @param pcbAttrLen [inout] Length of the \p pbAttr buffer in bytes.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NOT_TRANSACTED Data exchange not successful (\ref SCARD_E_NOT_TRANSACTED)
+ * @retval SCARD_E_INSUFFICIENT_BUFFER Reader buffer not large enough (\ref SCARD_E_INSUFFICIENT_BUFFER)
+ *
+ * @test
+ * @code
+ * LONG rv;
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * unsigned char pbAtr[MAX_ATR_SIZE];
+ * DWORD dwAtrLen;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED,
+ * SCARD_PROTOCOL_RAW &hCard, &dwActiveProtocol);
+ * rv = SCardGetAttrib(hCard, SCARD_ATTR_ATR_STRING, pbAtr, &dwAtrLen);
+ * @endcode
+ */
+
+int32_t SCardGetAttrib(SCARDHANDLE hCard, uint32_t dwAttrId, uint8_t * pbAttr,
+ uint32_t * pcbAttrLen)
+{
+ PROFILE_START
+
+ if (NULL == pcbAttrLen)
+ return SCARD_E_INVALID_PARAMETER;
+
+ /* if only get the length */
+ if (NULL == pbAttr)
+ /* this variable may not be set by the caller. use a reasonable size */
+ *pcbAttrLen = MAX_BUFFER_SIZE;
+
+ PROFILE_END
+
+ return SCardGetSetAttrib(hCard, SCARD_GET_ATTRIB, dwAttrId, pbAttr,
+ pcbAttrLen);
+}
+
+/**
+ * @brief This function set an attribute of the IFD Handler.
+ *
+ * The list of attributes you can set is dependent on the IFD Handler you are
+ * using.
+ *
+ * @param[in] hCard Connection made from SCardConnect().
+ * @param[in] dwAttrId Identifier for the attribute to set.
+ * @param[in] pbAttr Pointer to a buffer that receives the attribute.
+ * @param[in] cbAttrLen Length of the \p pbAttr buffer in bytes.
+ *
+ * @return Error code
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NOT_TRANSACTED Data exchange not successful (\ref SCARD_E_NOT_TRANSACTED)
+ *
+ * @test
+ * @code
+ * LONG rv;
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol;
+ * unsigned char pbAtr[MAX_ATR_SIZE];
+ * DWORD dwAtrLen;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED,
+ * SCARD_PROTOCOL_RAW &hCard, &dwActiveProtocol);
+ * rv = SCardSetAttrib(hCard, 0x42000001, "\x12\x34\x56", 3);
+ * @endcode
+ */
+
+int32_t SCardSetAttrib(SCARDHANDLE hCard, uint32_t dwAttrId, const uint8_t *pbAttr,
+ uint32_t cbAttrLen)
+{
+ PROFILE_START
+
+ if (NULL == pbAttr || 0 == cbAttrLen)
+ return SCARD_E_INVALID_PARAMETER;
+
+ PROFILE_END
+
+ return SCardGetSetAttrib(hCard, SCARD_SET_ATTRIB, dwAttrId, (LPBYTE)pbAttr,
+ &cbAttrLen);
+}
+
+static LONG SCardGetSetAttrib(SCARDHANDLE hCard, int command, DWORD dwAttrId,
+ LPBYTE pbAttr, LPDWORD pcbAttrLen)
+{
+ PROFILE_START
+
+ LONG rv;
+ getset_struct scGetSetStruct;
+ sharedSegmentMsg msgStruct;
+ int i;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ if (*pcbAttrLen > MAX_BUFFER_SIZE)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+
+ scGetSetStruct.hCard = hCard;
+ scGetSetStruct.dwAttrId = dwAttrId;
+ scGetSetStruct.cbAttrLen = *pcbAttrLen;
+ scGetSetStruct.rv = SCARD_E_NO_SERVICE;
+ if (SCARD_SET_ATTRIB == command)
+ memcpy(scGetSetStruct.pbAttr, pbAttr, *pcbAttrLen);
+
+ ntohlGetSetStruct(&scGetSetStruct);
+ rv = WrapSHMWrite(command,
+ psContextMap[dwContextIndex].dwClientID, sizeof(scGetSetStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, &scGetSetStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(getset_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ memcpy(&scGetSetStruct, &msgStruct.data, sizeof(scGetSetStruct));
+ ntohlGetSetStruct(&scGetSetStruct);
+
+ if ((SCARD_S_SUCCESS == scGetSetStruct.rv) && (SCARD_GET_ATTRIB == command))
+ {
+ /*
+ * Copy and zero it so any secret information is not leaked
+ */
+ if (*pcbAttrLen < scGetSetStruct.cbAttrLen)
+ {
+ scGetSetStruct.cbAttrLen = *pcbAttrLen;
+ scGetSetStruct.rv = SCARD_E_INSUFFICIENT_BUFFER;
+ }
+ else
+ *pcbAttrLen = scGetSetStruct.cbAttrLen;
+
+ if (pbAttr)
+ memcpy(pbAttr, scGetSetStruct.pbAttr, scGetSetStruct.cbAttrLen);
+
+ memset(scGetSetStruct.pbAttr, 0x00, sizeof(scGetSetStruct.pbAttr));
+ }
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return scGetSetStruct.rv;
+}
+
+/**
+ * @brief This function sends an APDU to the smart card contained in the reader
+ * connected to by SCardConnect().
+ *
+ * The card responds from the APDU and stores this response in pbRecvBuffer
+ * and it's length in SpcbRecvLength.
+ * SSendPci and SRecvPci are structures containing the following:
+ * @code
+ * typedef struct {
+ * DWORD dwProtocol; // SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1
+ * DWORD cbPciLength; // Length of this structure - not used
+ * } SCARD_IO_REQUEST;
+ * @endcode
+ *
+ * @param[in] hCard Connection made from SCardConnect().
+ * @param pioSendPci [inout] Structure of protocol information.
+ * <ul>
+ * <li>\ref SCARD_PCI_T0 - Pre-defined T=0 PCI structure.
+ * <li>\ref SCARD_PCI_T1 - Pre-defined T=1 PCI structure.
+ * </ul>
+ * @param[in] pbSendBuffer APDU to send to the card.
+ * @param[in] cbSendLength Length of the APDU.
+ * @param pioRecvPci [inout] Structure of protocol information.
+ * @param[out] pbRecvBuffer Response from the card.
+ * @param pcbRecvLength [inout] Length of the response.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid hCard handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_NOT_TRANSACTED APDU exchange not successful (\ref SCARD_E_NOT_TRANSACTED)
+ * @retval SCARD_E_PROTO_MISMATCH Connect protocol is different than desired (\ref SCARD_E_PROTO_MISMATCH)
+ * @retval SCARD_E_INVALID_VALUE Invalid Protocol, reader name, etc (\ref SCARD_E_INVALID_VALUE)
+ * @retval SCARD_E_READER_UNAVAILABLE The reader has been removed (\ref SCARD_E_READER_UNAVAILABLE)
+ * @retval SCARD_W_RESET_CARD The card has been reset by another application (\ref SCARD_W_RESET_CARD)
+ * @retval SCARD_W_REMOVED_CARD The card has been removed from the reader (\ref SCARD_W_REMOVED_CARD)
+ *
+ * @test
+ * @code
+ * LONG rv;
+ * SCARDCONTEXT hContext;
+ * SCARDHANDLE hCard;
+ * DWORD dwActiveProtocol, dwSendLength, dwRecvLength;
+ * SCARD_IO_REQUEST pioRecvPci;
+ * BYTE pbRecvBuffer[10];
+ * BYTE pbSendBuffer[] = { 0xC0, 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00 };
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardConnect(hContext, "Reader X", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
+ * dwSendLength = sizeof(pbSendBuffer);
+ * dwRecvLength = sizeof(pbRecvBuffer);
+ * rv = SCardTransmit(hCard, SCARD_PCI_T0, pbSendBuffer, dwSendLength, &pioRecvPci, pbRecvBuffer, &dwRecvLength);
+ * @endcode
+ */
+#include <syslog.h>
+LONG SCardTransmit(SCARDHANDLE hCard, LPCSCARD_IO_REQUEST pioSendPci,
+ LPCBYTE pbSendBuffer, DWORD cbSendLength,
+ LPSCARD_IO_REQUEST pioRecvPci, LPBYTE pbRecvBuffer,
+ LPDWORD pcbRecvLength)
+{
+ LONG rv;
+ int i;
+ DWORD dwContextIndex, dwChannelIndex;
+
+ PROFILE_START
+
+ if (pbSendBuffer == NULL || pbRecvBuffer == NULL ||
+ pcbRecvLength == NULL || pioSendPci == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this handle has been opened
+ */
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndex, &dwChannelIndex);
+
+ if (rv == -1)
+ {
+ *pcbRecvLength = 0;
+ return SCARD_E_INVALID_HANDLE;
+ }
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ char *r = psContextMap[dwContextIndex].psChannelMap[dwChannelIndex].readerName;
+
+ /* by default r == NULL */
+ if (SharedReaderState_ReaderNameIsEqual(readerStates[i], r))
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_READERS_CONTEXTS)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_READER_UNAVAILABLE;
+ }
+
+ if ((cbSendLength > MAX_BUFFER_SIZE_EXTENDED)
+ || (*pcbRecvLength > MAX_BUFFER_SIZE_EXTENDED))
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+
+ if ((cbSendLength > MAX_BUFFER_SIZE) || (*pcbRecvLength > MAX_BUFFER_SIZE))
+ {
+ /* extended APDU */
+ unsigned char buffer[sizeof(sharedSegmentMsg) + MAX_BUFFER_SIZE_EXTENDED];
+ const sharedSegmentMsg *pmsgStruct = (psharedSegmentMsg)buffer;
+ transmit_struct_extended *scTransmitStructExtended = (transmit_struct_extended *)buffer;
+
+ scTransmitStructExtended->hCard = hCard;
+ scTransmitStructExtended->cbSendLength = cbSendLength;
+ scTransmitStructExtended->pcbRecvLength = *pcbRecvLength;
+ scTransmitStructExtended->size = sizeof(*scTransmitStructExtended) + cbSendLength;
+ memcpy(&scTransmitStructExtended->pioSendPci, pioSendPci,
+ sizeof(SCARD_IO_REQUEST));
+ memcpy(scTransmitStructExtended->data, pbSendBuffer, cbSendLength);
+ secdebug("pcscd", "Extended APDU: initial request: hCard: 0x%08X, cbSendLength: %d",
+ hCard, cbSendLength);
+ secdebug("pcscd", " pcbRecvLength: %d", *pcbRecvLength);
+
+ if (pioRecvPci)
+ {
+ memcpy(&scTransmitStructExtended->pioRecvPci, pioRecvPci,
+ sizeof(SCARD_IO_REQUEST));
+ }
+ else
+ scTransmitStructExtended->pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
+
+ size_t tsesize = scTransmitStructExtended->size; // remember it before we byte swap
+ LogXxd(PCSC_LOG_INFO, "Extended APDU: sending: ", pbSendBuffer, cbSendLength);
+ htonlTransmitStructExtended(scTransmitStructExtended);
+ rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED,
+ psContextMap[dwContextIndex].dwClientID,
+ tsesize,
+ PCSCLITE_CLIENT_ATTEMPTS, buffer);
+ secdebug("pcscd", "Extended APDU: WrapSHMWrite result: %d [0x%08X]", rv, rv);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage((psharedSegmentMsg)buffer, psContextMap[dwContextIndex].dwClientID, 0, PCSCLITE_CLIENT_ATTEMPTS);
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ /* we receive a sharedSegmentMsg and not a transmit_struct_extended */
+ scTransmitStructExtended = (transmit_struct_extended *)pmsgStruct->data;
+ ntohlTransmitStructExtended(scTransmitStructExtended);
+ secdebug("pcscd", "Extended APDU: reply received: hCard: 0x%08X, cbSendLength: %d",
+ hCard, cbSendLength);
+ secdebug("pcscd", " reply received: pcbRecvLength: %d, size: %d",
+ scTransmitStructExtended->pcbRecvLength, scTransmitStructExtended->size);
+ secdebug("pcscd", " reply received: rv %d [0x%08X]",
+ scTransmitStructExtended -> rv, scTransmitStructExtended -> rv);
+ LogXxd(PCSC_LOG_INFO, "Extended APDU: received: ", scTransmitStructExtended->data, scTransmitStructExtended->pcbRecvLength);
+
+ /* a second block is present */
+ if (scTransmitStructExtended->size > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ rv = SHMMessageReceive(buffer + sizeof(sharedSegmentMsg),
+ scTransmitStructExtended->size-PCSCLITE_MAX_MESSAGE_SIZE,
+ psContextMap[dwContextIndex].dwClientID,
+ PCSCLITE_CLIENT_ATTEMPTS);
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+ // we don't fix up byte order here since this is in the data portion
+ }
+
+ if (scTransmitStructExtended -> rv == SCARD_S_SUCCESS)
+ {
+ /*
+ * Copy and zero it so any secret information is not leaked
+ */
+ memcpy(pbRecvBuffer, scTransmitStructExtended -> data,
+ scTransmitStructExtended -> pcbRecvLength);
+ memset(scTransmitStructExtended -> data, 0x00,
+ scTransmitStructExtended -> pcbRecvLength);
+
+ if (pioRecvPci)
+ memcpy(pioRecvPci, &scTransmitStructExtended -> pioRecvPci,
+ sizeof(SCARD_IO_REQUEST));
+ }
+
+ *pcbRecvLength = scTransmitStructExtended -> pcbRecvLength;
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ rv = scTransmitStructExtended -> rv;
+ }
+ else
+ {
+ /* short APDU */
+ transmit_struct scTransmitStruct;
+ sharedSegmentMsg msgStruct;
+
+ scTransmitStruct.hCard = hCard;
+ scTransmitStruct.cbSendLength = cbSendLength;
+ scTransmitStruct.pcbRecvLength = *pcbRecvLength;
+ memcpy(&scTransmitStruct.pioSendPci, pioSendPci,
+ sizeof(SCARD_IO_REQUEST));
+ memcpy(scTransmitStruct.pbSendBuffer, pbSendBuffer, cbSendLength);
+
+ if (pioRecvPci)
+ {
+ memcpy(&scTransmitStruct.pioRecvPci, pioRecvPci,
+ sizeof(SCARD_IO_REQUEST));
+ }
+ else
+ scTransmitStruct.pioRecvPci.dwProtocol = SCARD_PROTOCOL_ANY;
+
+ htonlTransmitStruct(&scTransmitStruct);
+ rv = WrapSHMWrite(SCARD_TRANSMIT,
+ psContextMap[dwContextIndex].dwClientID, sizeof(scTransmitStruct),
+ PCSCLITE_CLIENT_ATTEMPTS, (void *) &scTransmitStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ /*
+ * Read a message from the server
+ */
+ rv = SHMClientReadMessage(&msgStruct, psContextMap[dwContextIndex].dwClientID, sizeof(transmit_struct), PCSCLITE_CLIENT_ATTEMPTS);
+
+ memcpy(&scTransmitStruct, &msgStruct.data, sizeof(scTransmitStruct));
+ ntohlTransmitStruct(&scTransmitStruct);
+
+ if (rv == -1)
+ {
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_F_COMM_ERROR;
+ }
+
+ /*
+ * Zero it and free it so any secret information cannot be leaked
+ */
+ memset(scTransmitStruct.pbSendBuffer, 0x00, cbSendLength);
+
+ if (scTransmitStruct.rv == SCARD_S_SUCCESS)
+ {
+ /*
+ * Copy and zero it so any secret information is not leaked
+ */
+ memcpy(pbRecvBuffer, scTransmitStruct.pbRecvBuffer,
+ scTransmitStruct.pcbRecvLength);
+ memset(scTransmitStruct.pbRecvBuffer, 0x00,
+ scTransmitStruct.pcbRecvLength);
+
+ if (pioRecvPci)
+ memcpy(pioRecvPci, &scTransmitStruct.pioRecvPci,
+ sizeof(SCARD_IO_REQUEST));
+ }
+
+ *pcbRecvLength = scTransmitStruct.pcbRecvLength;
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ rv = scTransmitStruct.rv;
+ }
+
+ PROFILE_END
+
+ return rv;
+}
+
+/**
+ * This function returns a list of currently available readers on the system.
+ * \p mszReaders is a pointer to a character string that is allocated by the application.
+ * If the application sends mszGroups and mszReaders as NULL then this function will
+ * return the size of the buffer needed to allocate in pcchReaders.
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ * @param[in] mszGroups List of groups to list readers (not used).
+ * @param[out] mszReaders Multi-string with list of readers.
+ * @param pcchReaders [inout] Size of multi-string buffer including NULL's.
+ *
+ * @return Connection status.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid Scope Handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_INSUFFICIENT_BUFFER Reader buffer not large enough (\ref SCARD_E_INSUFFICIENT_BUFFER)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * LPSTR mszReaders;
+ * DWORD dwReaders;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);
+ * mszReaders = malloc(sizeof(char)*dwReaders);
+ * rv = SCardListReaders(hContext, NULL, mszReaders, &dwReaders);
+ * @endcode
+ */
+LONG SCardListReaders(SCARDCONTEXT hContext, LPCSTR mszGroups,
+ LPSTR mszReaders, LPDWORD pcchReaders)
+{
+ DWORD dwReadersLen;
+ int i, lastChrPtr;
+ LONG dwContextIndex;
+
+ PROFILE_START
+
+ /*
+ * Check for NULL parameters
+ */
+ if (pcchReaders == NULL)
+ return SCARD_E_INVALID_PARAMETER;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this context has been opened
+ */
+ dwContextIndex = SCardGetContextIndice(hContext);
+ if (dwContextIndex == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ dwReadersLen = 0;
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ if (SharedReaderState_ReaderID(readerStates[i]) != 0)
+ dwReadersLen += strlen(SharedReaderState_ReaderName(readerStates[i])) + 1;
+
+ /* for the last NULL byte */
+ dwReadersLen += 1;
+
+ if ((mszReaders == NULL) /* text array not allocated */
+ || (*pcchReaders == 0)) /* size == 0 */
+ {
+ *pcchReaders = dwReadersLen;
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_S_SUCCESS;
+ }
+
+ if (*pcchReaders < dwReadersLen)
+ {
+ *pcchReaders = dwReadersLen;
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+ return SCARD_E_INSUFFICIENT_BUFFER;
+ }
+
+ lastChrPtr = 0;
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ if (SharedReaderState_ReaderID(readerStates[i]) != 0)
+ {
+ /*
+ * Build the multi-string
+ */
+ strcpy(&mszReaders[lastChrPtr], SharedReaderState_ReaderName(readerStates[i]));
+ lastChrPtr += strlen(SharedReaderState_ReaderName(readerStates[i]))+1;
+ }
+ }
+ mszReaders[lastChrPtr] = '\0'; /* Add the last null */
+
+ *pcchReaders = dwReadersLen;
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return SCARD_S_SUCCESS;
+}
+
+/**
+ * @brief This function returns a list of currently available reader groups on the system.
+ * \p mszGroups is a pointer to a character string that is allocated by the
+ * application. If the application sends mszGroups as NULL then this function
+ * will return the size of the buffer needed to allocate in pcchGroups.
+ *
+ * The group names is a multi-string and separated by a nul character ('\\0') and ended by
+ * a double nul character. "SCard$DefaultReaders\\0Group 2\\0\\0".
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ * @param[out] mszGroups List of groups to list readers.
+ * @param pcchGroups [inout] Size of multi-string buffer including NULL's.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid Scope Handle (\ref SCARD_E_INVALID_HANDLE)
+ * @retval SCARD_E_INSUFFICIENT_BUFFER Reader buffer not large enough (\ref SCARD_E_INSUFFICIENT_BUFFER)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * LPSTR mszGroups;
+ * DWORD dwGroups;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardListReaderGroups(hContext, NULL, &dwGroups);
+ * mszGroups = malloc(sizeof(char)*dwGroups);
+ * rv = SCardListReaderGroups(hContext, mszGroups, &dwGroups);
+ * @endcode
+ */
+LONG SCardListReaderGroups(SCARDCONTEXT hContext, LPSTR mszGroups,
+ LPDWORD pcchGroups)
+{
+ LONG rv = SCARD_S_SUCCESS;
+ LONG dwContextIndex;
+
+ PROFILE_START
+
+ const char ReaderGroup[] = "SCard$DefaultReaders";
+ const int dwGroups = strlen(ReaderGroup) + 2;
+
+ if (SCardCheckDaemonAvailability() != SCARD_S_SUCCESS)
+ return SCARD_E_NO_SERVICE;
+
+ /*
+ * Make sure this context has been opened
+ */
+ dwContextIndex = SCardGetContextIndice(hContext);
+ if (dwContextIndex == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ SYS_MutexLock(psContextMap[dwContextIndex].mMutex);
+
+ if (mszGroups)
+ {
+
+ if (*pcchGroups < dwGroups)
+ rv = SCARD_E_INSUFFICIENT_BUFFER;
+ else
+ {
+ memset(mszGroups, 0, dwGroups);
+ memcpy(mszGroups, ReaderGroup, strlen(ReaderGroup));
+ }
+ }
+
+ *pcchGroups = dwGroups;
+
+ SYS_MutexUnLock(psContextMap[dwContextIndex].mMutex);
+
+ PROFILE_END
+
+ return rv;
+}
+
+/**
+ * This function cancels all pending blocking requests on the
+ * SCardGetStatusChange() function.
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid \p hContext handle (\ref SCARD_E_INVALID_HANDLE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * DWORD cReaders;
+ * SCARD_READERSTATE rgReaderStates;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rgReaderStates.szReader = strdup("Reader X");
+ * rgReaderStates.dwCurrentState = SCARD_STATE_EMPTY;
+ * ...
+ * / * Spawn off thread for following function * /
+ * ...
+ * rv = SCardGetStatusChange(hContext, 0, rgReaderStates, cReaders);
+ * rv = SCardCancel(hContext);
+ * @endcode
+ */
+LONG SCardCancel(SCARDCONTEXT hContext)
+{
+ LONG dwContextIndex;
+
+ PROFILE_START
+
+ dwContextIndex = SCardGetContextIndice(hContext);
+
+ if (dwContextIndex == -1)
+ return SCARD_E_INVALID_HANDLE;
+
+ /*
+ * Set the block status for this Context so blocking calls will
+ * complete
+ */
+ psContextMap[dwContextIndex].contextBlockStatus = BLOCK_STATUS_RESUME;
+
+ PROFILE_END
+
+ return SCARD_S_SUCCESS;
+}
+
+/**
+ * @brief check if a \ref SCARDCONTEXT is valid.
+ *
+ * Call this function to determine whether a smart card context handle is still
+ * valid. After a smart card context handle has been set by \ref
+ * SCardEstablishContext, it may become not valid if the resource manager
+ * service has been shut down.
+ *
+ * @param[in] hContext Connection context to the PC/SC Resource Manager.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Successful (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE Invalid Handle (\ref SCARD_E_INVALID_HANDLE)
+ *
+ * @test
+ * @code
+ * SCARDCONTEXT hContext;
+ * LONG rv;
+ * ...
+ * rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
+ * rv = SCardIsValidContext(hContext);
+ * @endcode
+ */
+LONG SCardIsValidContext(SCARDCONTEXT hContext)
+{
+ LONG rv;
+ LONG dwContextIndex;
+
+ PROFILE_START
+
+ rv = SCARD_S_SUCCESS;
+
+ /*
+ * Make sure this context has been opened
+ */
+ dwContextIndex = SCardGetContextIndice(hContext);
+ if (dwContextIndex == -1)
+ rv = SCARD_E_INVALID_HANDLE;
+
+ PROFILE_END
+
+ return rv;
+}
+
+/**
+ * Functions for managing instances of SCardEstablishContext These functions
+ * keep track of Context handles and associate the blocking
+ * variable contextBlockStatus to an hContext
+ */
+
+/**
+ * @brief Adds an Application Context to the vector \c psContextMap.
+ *
+ * @param[in] hContext Application Context ID.
+ * @param[in] dwClientID Client connection ID.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Success (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NO_MEMORY There is no free slot to store \p hContext (\ref SCARD_E_NO_MEMORY)
+ */
+static LONG SCardAddContext(SCARDCONTEXT hContext, DWORD dwClientID)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
+ {
+ if (psContextMap[i].hContext == 0)
+ {
+ psContextMap[i].hContext = hContext;
+ psContextMap[i].dwClientID = dwClientID;
+ psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
+ psContextMap[i].mMutex = malloc(sizeof(PCSCLITE_MUTEX));
+ SYS_MutexInit(psContextMap[i].mMutex);
+ return SCARD_S_SUCCESS;
+ }
+ }
+
+ return SCARD_E_NO_MEMORY;
+}
+
+/**
+ * @brief Get the index from the Application Context vector \c psContextMap
+ * for the passed context.
+ *
+ * This function is a thread-safe wrapper to the function
+ * SCardGetContextIndiceTH().
+ *
+ * @param[in] hContext Application Context whose index will be find.
+ *
+ * @return Index corresponding to the Application Context or -1 if it is
+ * not found.
+ */
+static LONG SCardGetContextIndice(SCARDCONTEXT hContext)
+{
+ LONG rv;
+
+ SCardLockThread();
+ rv = SCardGetContextIndiceTH(hContext);
+ SCardUnlockThread();
+
+ return rv;
+}
+
+/**
+ * @brief Get the index from the Application Context vector \c psContextMap
+ * for the passed context.
+ *
+ * This functions is not thread-safe and should not be called. Instead, call
+ * the function SCardGetContextIndice().
+ *
+ * @param[in] hContext Application Context whose index will be find.
+ *
+ * @return Index corresponding to the Application Context or -1 if it is
+ * not found.
+ */
+static LONG SCardGetContextIndiceTH(SCARDCONTEXT hContext)
+{
+ int i;
+
+ if (hContext == 0)
+ return -1;
+
+ /*
+ * Find this context and return its spot in the array
+ */
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
+ if (hContext == psContextMap[i].hContext)
+ return i;
+
+ return -1;
+}
+
+/**
+ * @brief Removes an Application Context from a control vector.
+ *
+ * @param[in] hContext Application Context to be removed.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Success (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_INVALID_HANDLE The context \p hContext was not found (\ref SCARD_E_INVALID_HANDLE)
+ */
+static LONG SCardRemoveContext(SCARDCONTEXT hContext)
+{
+ LONG retIndice;
+
+ retIndice = SCardGetContextIndiceTH(hContext);
+
+ if (retIndice == -1)
+ return SCARD_E_INVALID_HANDLE;
+ else
+ {
+ int i;
+
+ psContextMap[retIndice].hContext = 0;
+ SHMClientCloseSession(psContextMap[retIndice].dwClientID);
+ psContextMap[retIndice].dwClientID = 0;
+ free(psContextMap[retIndice].mMutex);
+ psContextMap[retIndice].mMutex = NULL;
+ psContextMap[retIndice].contextBlockStatus = BLOCK_STATUS_RESUME;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ /*
+ * Reset the \c hCard structs to zero
+ */
+ psContextMap[retIndice].psChannelMap[i].hCard = 0;
+ free(psContextMap[retIndice].psChannelMap[i].readerName);
+ psContextMap[retIndice].psChannelMap[i].readerName = NULL;
+ }
+
+ return SCARD_S_SUCCESS;
+ }
+}
+
+/*
+ * Functions for managing hCard values returned from SCardConnect.
+ */
+
+static LONG SCardAddHandle(SCARDHANDLE hCard, DWORD dwContextIndex,
+ LPSTR readerName)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ if (psContextMap[dwContextIndex].psChannelMap[i].hCard == 0)
+ {
+ psContextMap[dwContextIndex].psChannelMap[i].hCard = hCard;
+ psContextMap[dwContextIndex].psChannelMap[i].readerName = strdup(readerName);
+ return SCARD_S_SUCCESS;
+ }
+ }
+
+ return SCARD_E_NO_MEMORY;
+}
+
+static LONG SCardRemoveHandle(SCARDHANDLE hCard)
+{
+ DWORD dwContextIndice, dwChannelIndice;
+ LONG rv;
+
+ rv = SCardGetIndicesFromHandle(hCard, &dwContextIndice, &dwChannelIndice);
+
+ if (rv == -1)
+ return SCARD_E_INVALID_HANDLE;
+ else
+ {
+ psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].hCard = 0;
+ free(psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName);
+ psContextMap[dwContextIndice].psChannelMap[dwChannelIndice].readerName = NULL;
+ return SCARD_S_SUCCESS;
+ }
+}
+
+static LONG SCardGetIndicesFromHandle(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
+{
+ LONG rv;
+
+ if (0 == hCard)
+ return -1;
+
+ SCardLockThread();
+ rv = SCardGetIndicesFromHandleTH(hCard, pdwContextIndice, pdwChannelIndice);
+ SCardUnlockThread();
+
+ return rv;
+}
+
+static LONG SCardGetIndicesFromHandleTH(SCARDHANDLE hCard, PDWORD pdwContextIndice, PDWORD pdwChannelIndice)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
+ {
+ if (psContextMap[i].hContext != 0)
+ {
+ int j;
+
+ for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
+ {
+ if (psContextMap[i].psChannelMap[j].hCard == hCard)
+ {
+ *pdwContextIndice = i;
+ *pdwChannelIndice = j;
+ return SCARD_S_SUCCESS;
+ }
+ }
+
+ }
+ }
+
+ return -1;
+}
+
+/**
+ * @brief This function locks a mutex so another thread must wait to use this
+ * function.
+ *
+ * Wrapper to the function SYS_MutexLock().
+ */
+inline static LONG SCardLockThread(void)
+{
+ return SYS_MutexLock(&clientMutex);
+}
+
+/**
+ * @brief This function unlocks a mutex so another thread may use the client.
+ *
+ * Wrapper to the function SYS_MutexUnLock().
+ */
+inline static LONG SCardUnlockThread(void)
+{
+ return SYS_MutexUnLock(&clientMutex);
+}
+
+/**
+ * @brief Checks if the Server is running.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Server is running (\ref SCARD_S_SUCCESS)
+ * @retval SCARD_E_NO_SERVICE Server is not running (\ref SCARD_E_NO_SERVICE)
+ */
+static LONG SCardCheckDaemonAvailability(void)
+{
+ LONG rv;
+ struct stat statBuffer;
+
+ rv = SYS_Stat(PCSCLITE_PUBSHM_FILE, &statBuffer);
+
+ if (rv != 0)
+ {
+ Log1(PCSC_LOG_ERROR, "PCSC Not Running");
+ return SCARD_E_NO_SERVICE;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+/**
+ * free resources allocated by the library
+ * You _shall_ call this function if you use dlopen/dlclose to load/unload the
+ * library. Otherwise you will exhaust the ressources available.
+ */
+#ifdef __SUNPRO_C
+#pragma fini (SCardUnload)
+#endif
+
+void DESTRUCTOR SCardUnload(void)
+{
+ int i;
+
+ if (!isExecuted)
+ return;
+
+ /* unmap public shared file from memory */
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ if (readerStates[i] != NULL)
+ {
+ SYS_PublicMemoryUnmap(readerStates[i], sizeof(READER_STATE));
+ readerStates[i] = NULL;
+ }
+ }
+
+ SYS_CloseFile(mapAddr);
+ isExecuted = 0;
+}
+
+static int SCardInitializeOnce()
+{
+ int pageSize;
+ int i;
+
+ /*
+ * Do any system initilization here
+ */
+ SYS_Initialize();
+
+ /*
+ * Set up the memory mapped reader stats structures
+ */
+ mapAddr = SYS_OpenFile(PCSCLITE_PUBSHM_FILE, O_RDONLY, 0);
+ if (mapAddr < 0)
+ {
+ Log2(PCSC_LOG_ERROR, "Cannot open public shared file: %s",
+ PCSCLITE_PUBSHM_FILE);
+ return SCARD_E_NO_SERVICE;
+ }
+
+ pageSize = SYS_GetPageSize();
+
+ /*
+ * Allocate each reader structure in the memory map
+ */
+ for (i = 0; i < PCSCLITE_MAX_READERS_CONTEXTS; i++)
+ {
+ readerStates[i] =
+ (PREADER_STATE)SYS_PublicMemoryMap(sizeof(READER_STATE),
+ mapAddr, (i * pageSize));
+ if (readerStates[i] == NULL)
+ {
+ Log1(PCSC_LOG_ERROR, "Cannot public memory map");
+ SYS_CloseFile(mapAddr); /* Close the memory map file */
+ return SCARD_F_INTERNAL_ERROR;
+ }
+ }
+
+ /*
+ * Initializes the application contexts and all channels for each one
+ */
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
+ {
+ int j;
+
+ /*
+ * Initially set the context struct to zero
+ */
+ psContextMap[i].dwClientID = 0;
+ psContextMap[i].hContext = 0;
+ psContextMap[i].contextBlockStatus = BLOCK_STATUS_RESUME;
+ psContextMap[i].mMutex = NULL;
+
+ for (j = 0; j < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; j++)
+ {
+ /*
+ * Initially set the hcard structs to zero
+ */
+ psContextMap[i].psChannelMap[j].hCard = 0;
+ psContextMap[i].psChannelMap[j].readerName = NULL;
+ }
+ }
+
+ /*
+ * Is there a free slot for this connection ?
+ */
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXTS; i++)
+ {
+ if (psContextMap[i].dwClientID == 0)
+ break;
+ }
+
+ if (i == PCSCLITE_MAX_APPLICATION_CONTEXTS)
+ {
+ return SCARD_E_NO_MEMORY;
+ }
+
+ return SCARD_S_SUCCESS;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ Title : winscard_msg.c
+ Package: PC/SC Lite
+ Author : David Corcoran
+ Date : 04/19/01
+ License: Copyright (C) 2001 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This is responsible for client/server transport.
+
+$Id: winscard_msg.c,v 1.4 2004/10/21 01:17:53 mb Exp $
+
+********************************************************************/
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "config.h"
+
+#ifdef PCSC_TARGET_SOLARIS
+#include <sys/filio.h>
+#endif
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "winscard.h"
+#include "winscard_msg.h"
+#include "sys_generic.h"
+#include "debuglog.h"
+
+int MSGSendData(int filedes, int blockAmount, const void *data,
+ unsigned int dataSize)
+{
+ /*
+ * default is success
+ */
+ int retval = 0;
+ /*
+ * record the time when we started
+ */
+ time_t start = time(0);
+ /*
+ * data to be written
+ */
+ unsigned char *buffer = (unsigned char *) data;
+ /*
+ * how many bytes remains to be written
+ */
+ size_t remaining = dataSize;
+
+ /*
+ * repeat until all data is written
+ */
+ while (remaining > 0)
+ {
+ fd_set write_fd;
+ struct timeval timeout;
+ int selret;
+
+ FD_ZERO(&write_fd);
+ FD_SET(filedes, &write_fd);
+
+ timeout.tv_usec = 0;
+ if ((timeout.tv_sec = start + blockAmount - time(0)) < 0)
+ {
+ /*
+ * we already timed out
+ */
+ retval = -1;
+ break;
+ }
+
+ selret = select(filedes + 1, NULL, &write_fd, NULL, &timeout);
+
+ /*
+ * try to write only when the file descriptor is writable
+ */
+ if (selret > 0)
+ {
+ int written;
+
+ if (!FD_ISSET(filedes, &write_fd))
+ {
+ /*
+ * very strange situation. it should be an assert really
+ */
+ retval = -1;
+ break;
+ }
+ written = write(filedes, buffer, remaining);
+
+ if (written > 0)
+ {
+ /*
+ * we wrote something
+ */
+ buffer += written;
+ remaining -= written;
+ } else if (written == 0)
+ {
+ /*
+ * peer closed the socket
+ */
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * we ignore the signals and socket full situations, all
+ * other errors are fatal
+ */
+ if (errno != EINTR && errno != EAGAIN)
+ {
+ retval = -1;
+ break;
+ }
+ }
+ } else if (selret == 0)
+ {
+ /*
+ * timeout
+ */
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * ignore signals
+ */
+ if (errno != EINTR)
+ {
+ DebugLogB
+ ("MSGServerProcessEvents: Select returns with failure: %s",
+ strerror(errno));
+ retval = -1;
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+int MSGRecieveData(int filedes, int blockAmount, void *data,
+ unsigned int dataSize)
+{
+ /*
+ * default is success
+ */
+ int retval = 0;
+ /*
+ * record the time when we started
+ */
+ time_t start = time(0);
+ /*
+ * buffer where we place the readed bytes
+ */
+ unsigned char *buffer = (unsigned char *) data;
+ /*
+ * how many bytes we must read
+ */
+ size_t remaining = dataSize;
+
+ /*
+ * repeat until we get the whole message
+ */
+ while (remaining > 0)
+ {
+ fd_set read_fd;
+ struct timeval timeout;
+ int selret;
+
+ FD_ZERO(&read_fd);
+ FD_SET(filedes, &read_fd);
+
+ timeout.tv_usec = 0;
+ if ((timeout.tv_sec = start + blockAmount - time(0)) < 0)
+ {
+ /*
+ * we already timed out
+ */
+ retval = -1;
+ break;
+ }
+
+ selret = select(filedes + 1, &read_fd, NULL, NULL, &timeout);
+
+ /*
+ * try to read only when socket is readable
+ */
+ if (selret > 0)
+ {
+ int readed;
+
+ if (!FD_ISSET(filedes, &read_fd))
+ {
+ /*
+ * very strange situation. it should be an assert really
+ */
+ retval = -1;
+ break;
+ }
+ readed = read(filedes, buffer, remaining);
+
+ if (readed > 0)
+ {
+ /*
+ * we got something
+ */
+ buffer += readed;
+ remaining -= readed;
+ } else if (readed == 0)
+ {
+ /*
+ * peer closed the socket
+ */
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * we ignore the signals and empty socket situations, all
+ * other errors are fatal
+ */
+ if (errno != EINTR && errno != EAGAIN)
+ {
+ retval = -1;
+ break;
+ }
+ }
+ } else if (selret == 0)
+ {
+ /*
+ * timeout
+ */
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * we ignore signals, all other errors are fatal
+ */
+ if (errno != EINTR)
+ {
+ DebugLogB
+ ("MSGServerProcessEvents: Select returns with failure: %s",
+ strerror(errno));
+ retval = -1;
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1002 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * winscard_msg.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2001-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ * Ludoic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard_msg.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This is responsible for client/server communication.
+ *
+ * A file based socket (\c commonSocket) is used to send/receive only messages
+ * among clients and server.\n
+ * The messages' data are passed throw a memory mapped file: \c sharedSegmentMsg.
+ */
+
+#include "config.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "pcscexport.h"
+#include "winscard.h"
+#include "debug.h"
+#include "winscard_msg.h"
+#include "sys_generic.h"
+
+#include <security_utilities/debugging.h>
+
+/**
+ * @brief Wrapper for the SHMMessageReceive() function.
+ *
+ * Called by clients to read the server responses.
+ *
+ * @param[out] msgStruct Message read.
+ * @param[in] dwClientID Client socket handle.
+ * @param[in] blockamount Timeout in milliseconds.
+ *
+ * @return Same error codes as SHMMessageReceive().
+ */
+INTERNAL int SHMClientRead(psharedSegmentMsg msgStruct, DWORD dwClientID, int blockamount)
+{
+ int rv = SHMMessageReceive(msgStruct, sizeof(*msgStruct), dwClientID, blockamount);
+ SHSharedSegmentMsgToHostOrder(msgStruct);
+ return rv;
+}
+
+/**
+ * @brief Wrapper for the SHMMessageReceive() function.
+ *
+ * Called by clients to read the server responses. This reads the exact number of bytes expected for the struct
+ *
+ * @param[out] msgStruct Message read.
+ * @param[in] dwClientID Client socket handle.
+ * @param[in] dataSize Size of the data at msgStruct->data
+ * @param[in] blockamount Timeout in milliseconds.
+ *
+ * @return Same error codes as SHMMessageReceive().
+ */
+INTERNAL int SHMClientReadMessage(psharedSegmentMsg msgStruct, DWORD dwClientID, size_t dataSize, int blockamount)
+{
+ // Read the basic header first so we know the size of the rest
+ // The special case of "dataSize == 0" means that we should deduce the size of the
+ // data from the header
+ size_t headerSize = sizeof(sharedSegmentMsg) - sizeof(msgStruct->data);
+ Log2(PCSC_LOG_DEBUG, "SHMClientReadMessage: Issuing read for %d bytes (header)", headerSize);
+ secdebug("pcscd", "SHMClientReadMessage: Issuing read for %ld bytes (header)", headerSize);
+ int rv = SHMMessageReceive(msgStruct, headerSize, dwClientID, blockamount);
+ Log3(rv?PCSC_LOG_CRITICAL:PCSC_LOG_DEBUG, "SHMClientReadMessage: read message header error: 0x%08X [0x%08X]", rv, rv);
+ secdebug("pcscd", "SHMClientReadMessage: read message header error: 0x%08X [0x%08X]", rv, rv);
+ if (rv)
+ return rv;
+ SHSharedSegmentMsgToHostOrder(msgStruct);
+ // Integrity check
+ if (msgStruct->headerTag != WINSCARD_MSG_HEADER_TAG)
+ {
+ Log3(PCSC_LOG_CRITICAL, "Error: read message header tag of: 0x%08X for possible command 0x%08X",
+ msgStruct->headerTag, msgStruct->command);
+ secdebug("pcscd", "Error: read message header tag of: 0x%08X for possible command 0x%08X",
+ msgStruct->headerTag, msgStruct->command);
+ return SCARD_F_INTERNAL_ERROR;
+ }
+ if (dataSize == 0)
+ dataSize = msgStruct->msgSize - headerSize; // message size includes header
+ else
+ if (msgStruct->msgSize != (headerSize + dataSize))
+ {
+ Log2(PCSC_LOG_CRITICAL, "Error: create on client socket: %s", strerror(errno));
+ secdebug("pcscd", "Error: create on client socket: %s", strerror(errno));
+ return SCARD_F_INTERNAL_ERROR;
+ }
+ Log2(PCSC_LOG_DEBUG, "SHMClientReadMessage: Issuing read for %d bytes", dataSize);
+ secdebug("pcscd", "SHMClientReadMessage: Issuing read for %ld bytes", dataSize);
+ if (blockamount == 0)
+ blockamount = PCSCLITE_SERVER_ATTEMPTS;
+ rv = SHMMessageReceive(msgStruct->data, dataSize, dwClientID, blockamount);
+ Log3(rv?PCSC_LOG_CRITICAL:PCSC_LOG_DEBUG, "SHMClientReadMessage: read message body error: 0x%08X [0x%08X]", rv, rv);
+ secdebug("pcscd", "SHMClientReadMessage: read message body error: 0x%08X [0x%08X]", rv, rv);
+ return rv;
+}
+
+/**
+ * @brief Prepares a communication channel for the client to talk to the server.
+ *
+ * This is called by the application to create a socket for local IPC with the
+ * server. The socket is associated to the file \c PCSCLITE_CSOCK_NAME.
+ *
+ * @param[out] pdwClientID Client Connection ID.
+ *
+ * @retval 0 Success.
+ * @retval -1 Can not create the socket.
+ * @retval -1 The socket can not open a connection.
+ * @retval -1 Can not set the socket to non-blocking.
+ */
+INTERNAL int SHMClientSetupSession(PDWORD pdwClientID)
+{
+ struct sockaddr_un svc_addr;
+ int one;
+ int ret;
+
+ ret = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (ret < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Error: create on client socket: %s",
+ strerror(errno));
+ return -1;
+ }
+ *pdwClientID = ret;
+
+ svc_addr.sun_family = AF_UNIX;
+ strncpy(svc_addr.sun_path, PCSCLITE_CSOCK_NAME,
+ sizeof(svc_addr.sun_path));
+
+ if (connect(*pdwClientID, (struct sockaddr *) &svc_addr,
+ sizeof(svc_addr.sun_family) + strlen(svc_addr.sun_path) + 1) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Error: connect to client socket: %s",
+ strerror(errno));
+ SYS_CloseFile(*pdwClientID);
+ return -1;
+ }
+
+ one = 1;
+ if (ioctl(*pdwClientID, FIONBIO, &one) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Error: cannot set socket nonblocking: %s",
+ strerror(errno));
+ SYS_CloseFile(*pdwClientID);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Closes the socket used by the client to communicate with the server.
+ *
+ * @param[in] dwClientID Client socket handle to be closed.
+ *
+ * @retval 0 Success.
+ */
+INTERNAL int SHMClientCloseSession(DWORD dwClientID)
+{
+ SYS_CloseFile(dwClientID);
+ return 0;
+}
+
+/**
+ * @brief CalculateMessageSize
+ *
+ * @param[in] dataSize Size of the additional data to send in the message.
+ *
+ * @retval total message size.
+ */
+INTERNAL size_t SHMCalculateMessageSize(size_t dataSize)
+{
+ // PCSCLITE_MAX_MESSAGE_SIZE == sizeof(sharedSegmentMsg.data)
+ return sizeof(sharedSegmentMsg) - PCSCLITE_MAX_MESSAGE_SIZE + dataSize;;
+}
+
+
+/**
+ * @brief Sends a menssage from client to server or vice-versa.
+ *
+ * Writes the message in the shared file \c filedes.
+ *
+ * @param[in] buffer_void Message to be sent.
+ * @param[in] buffer_size Size of the message to send
+ * @param[in] filedes Socket handle.
+ * @param[in] blockAmount Timeout in milliseconds.
+ *
+ * @retval 0 Success
+ * @retval -1 Timeout.
+ * @retval -1 Socket is closed.
+ * @retval -1 A signal was received.
+ */
+INTERNAL int SHMMessageSend(void *buffer_void, size_t buffer_size,
+ int filedes, int blockAmount)
+{
+ char *buffer = (char *)buffer_void;
+
+ /*
+ * default is success
+ */
+ int retval = 0;
+ /*
+ * record the time when we started
+ */
+ time_t start = time(0);
+ /*
+ * how many bytes remains to be written
+ */
+ size_t remaining = buffer_size;
+
+ LogXxd(PCSC_LOG_DEBUG, "==> SHMMessageSend:\n", (const unsigned char *)buffer, buffer_size);
+
+ /*
+ * repeat until all data is written
+ */
+ while (remaining > 0)
+ {
+ fd_set write_fd;
+ struct timeval timeout;
+ int selret;
+
+ FD_ZERO(&write_fd);
+ FD_SET(filedes, &write_fd);
+
+ timeout.tv_usec = 0;
+ if ((timeout.tv_sec = start + blockAmount - time(0)) < 0)
+ {
+ /*
+ * we already timed out
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: we already timed out");
+ retval = -1;
+ break;
+ }
+
+ selret = select(filedes + 1, NULL, &write_fd, NULL, &timeout);
+
+ /*
+ * try to write only when the file descriptor is writable
+ */
+ if (selret > 0)
+ {
+ int written;
+
+ if (!FD_ISSET(filedes, &write_fd))
+ {
+ /*
+ * very strange situation. it should be an assert really
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: very strange situation: !FD_ISSET");
+ retval = -1;
+ break;
+ }
+ written = write(filedes, buffer, remaining);
+
+ if (written > 0)
+ {
+ /*
+ * we wrote something
+ */
+ buffer += written;
+ remaining -= written;
+ } else if (written == 0)
+ {
+ /*
+ * peer closed the socket
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: peer closed the socket");
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * we ignore the signals and socket full situations, all
+ * other errors are fatal
+ */
+ if (errno != EINTR && errno != EAGAIN)
+ {
+ retval = -1;
+ break;
+ }
+ }
+ } else if (selret == 0)
+ {
+ /*
+ * timeout
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: selret == 0 [timeout]");
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * ignore signals
+ */
+ if (errno != EINTR)
+ {
+ Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
+ strerror(errno));
+ retval = -1;
+ break;
+ }
+ }
+ }
+
+ if (remaining > 0)
+ Log3(PCSC_LOG_ERROR, "failure to write all bytes, remaining: %d, err: ", remaining, strerror(errno));
+
+ return retval;
+}
+
+/**
+ * @brief Called by the Client to get the reponse from the server or vice-versa.
+ *
+ * Reads the message from the file \c filedes.
+ *
+ * @param[out] buffer_void Message read.
+ * @param[in] buffer_size Size to read
+ * @param[in] filedes Socket handle.
+ * @param[in] blockAmount Timeout in milliseconds.
+ *
+ * @retval 0 Success.
+ * @retval -1 Timeout.
+ * @retval -1 Socket is closed.
+ * @retval -1 A signal was received.
+ */
+INTERNAL int SHMMessageReceive(void *buffer_void, size_t buffer_size,
+ int filedes, int blockAmount)
+{
+ char *buffer = (char *)buffer_void;
+
+ /*
+ * default is success
+ */
+ int retval = 0;
+ /*
+ * record the time when we started
+ */
+ time_t start = time(0);
+ /*
+ * how many bytes we must read
+ */
+ size_t remaining = buffer_size;
+
+ /*
+ * repeat until we get the whole message
+ */
+ while (remaining > 0)
+ {
+ fd_set read_fd;
+ struct timeval timeout;
+ int selret;
+
+ FD_ZERO(&read_fd);
+ FD_SET(filedes, &read_fd);
+
+ timeout.tv_usec = 0;
+ if ((timeout.tv_sec = start + blockAmount - time(0)) < 0)
+ {
+ /*
+ * we already timed out
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: we already timed out");
+ retval = -1;
+ break;
+ }
+
+ selret = select(filedes + 1, &read_fd, NULL, NULL, &timeout);
+
+ /*
+ * try to read only when socket is readable
+ */
+ if (selret > 0)
+ {
+ int readed;
+
+ if (!FD_ISSET(filedes, &read_fd))
+ {
+ /*
+ * very strange situation. it should be an assert really
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: very strange situation: !FD_ISSET");
+ retval = -1;
+ break;
+ }
+ readed = read(filedes, buffer, remaining);
+
+ if (readed > 0)
+ {
+ /*
+ * we got something
+ */
+ buffer += readed;
+ remaining -= readed;
+ } else if (readed == 0)
+ {
+ /*
+ * peer closed the socket
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: peer closed the socket");
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * we ignore the signals and empty socket situations, all
+ * other errors are fatal
+ */
+ if (errno != EINTR && errno != EAGAIN)
+ {
+ retval = -1;
+ break;
+ }
+ }
+ } else if (selret == 0)
+ {
+ /*
+ * timeout
+ */
+ Log1(PCSC_LOG_ERROR, "SHMMessageReceive: selret == 0 [timeout]");
+ retval = -1;
+ break;
+ } else
+ {
+ /*
+ * we ignore signals, all other errors are fatal
+ */
+ if (errno != EINTR)
+ {
+ Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
+ strerror(errno));
+ retval = -1;
+ break;
+ }
+ }
+ }
+
+ size_t bytesRead = (buffer_size - remaining);
+ Log3(PCSC_LOG_DEBUG, "SHMMessageReceive errno: 0x%08X: %s", errno, errno?strerror(errno):"no error");
+ Log3(retval?PCSC_LOG_ERROR:PCSC_LOG_DEBUG, "SHMMessageReceive retval: 0x%08X, bytes read: %d", retval, bytesRead);
+ LogXxd(PCSC_LOG_DEBUG, "<== SHMMessageReceive:\n", (const unsigned char *)buffer_void, bytesRead);
+ return retval;
+}
+
+/**
+ * @brief Wrapper for the SHMMessageSend() function.
+ *
+ * Called by clients to send messages to the server.
+ * The parameters \p command and \p data are set in the \c sharedSegmentMsg
+ * struct in order to be sent.
+ *
+ * @param[in] command Command to be sent.
+ * @param[in] dwClientID Client socket handle.
+ * @param[in] size Size of the message (\p data).
+ * @param[in] blockAmount Timeout to the operation in ms.
+ * @param[in] data_void Data to be sent.
+ *
+ * @return Same error codes as SHMMessageSend().
+ */
+INTERNAL int WrapSHMWrite(unsigned int command, DWORD dwClientID,
+ unsigned int dataSize, unsigned int blockAmount, void *data_void)
+{
+ char *data = (char *)data_void;
+
+ sharedSegmentMsg msgStruct;
+ int ret;
+
+ /*
+ * Set the appropriate packet parameters
+ */
+
+ memset(&msgStruct, 0, sizeof(msgStruct));
+ msgStruct.headerTag = WINSCARD_MSG_HEADER_TAG;
+ msgStruct.msgSize = sizeof(sharedSegmentMsg) - sizeof(msgStruct.data) + dataSize;
+ msgStruct.mtype = (command == CMD_VERSION)?CMD_VERSION:CMD_FUNCTION;
+ msgStruct.user_id = SYS_GetUID();
+ msgStruct.group_id = SYS_GetGID();
+ msgStruct.command = command;
+ msgStruct.date = time(NULL);
+
+ if ((SCARD_TRANSMIT_EXTENDED == command)
+ || (SCARD_CONTROL_EXTENDED == command))
+ {
+ /* first block */
+ size_t sizeToSend = (msgStruct.msgSize <= PCSCLITE_MAX_MESSAGE_SIZE)?msgStruct.msgSize:PCSCLITE_MAX_MESSAGE_SIZE;
+ size_t sizeRemaining = (msgStruct.msgSize <= PCSCLITE_MAX_MESSAGE_SIZE)?0:
+ (msgStruct.msgSize - PCSCLITE_MAX_MESSAGE_SIZE);
+ memcpy(msgStruct.data, data, sizeToSend);
+ SHSharedSegmentMsgToNetworkOrder(&msgStruct);
+ ret = SHMMessageSend(&msgStruct, sizeToSend, dwClientID,
+ blockAmount);
+ if (ret)
+ return ret;
+
+ // Warning: this code only works for sizes of 2 blocks or less
+ if (sizeRemaining > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ Log2(PCSC_LOG_ERROR, "WrapSHMWrite: cannot send message of size %d", msgStruct.msgSize);
+ return -1;
+ }
+
+ /* do not send an empty second block */
+ if (sizeRemaining > 0)
+ {
+ /* second block */
+ ret = SHMMessageSend(data+PCSCLITE_MAX_MESSAGE_SIZE,
+ sizeRemaining, dwClientID, blockAmount);
+ if (ret)
+ return ret;
+ }
+ }
+ else
+ if (msgStruct.msgSize > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ Log3(PCSC_LOG_ERROR, "WrapSHMWrite: cannot send message of size %d with this command: %d", msgStruct.msgSize, command);
+ return -1;
+ }
+ else
+ {
+ size_t savedSize = msgStruct.msgSize;
+
+ memcpy(msgStruct.data, data, dataSize);
+ SHSharedSegmentMsgToNetworkOrder(&msgStruct);
+ ret = SHMMessageSend(&msgStruct, savedSize, dwClientID, blockAmount);
+ }
+ return ret;
+}
+
+/**
+ * @brief Closes the communications channel used by the server to talk to the
+ * clients.
+ *
+ * The socket used is closed and the file it is bound to is removed.
+ *
+ * @param[in] sockValue Socket to be closed.
+ * @param[in] pcFilePath File used by the socket.
+ */
+INTERNAL void SHMCleanupSharedSegment(int sockValue, const char *pcFilePath)
+{
+ SYS_CloseFile(sockValue);
+ SYS_Unlink((char *)pcFilePath);
+}
+
+#pragma mark -------------------- Byte ordering functions --------------------
+
+/**
+ * @brief Convert fields in the psharedSegmentMsg struct to network byte order for sending
+ *
+ * Call this before each call to SHMMessageSend. Note: the data fields are not processed
+ * and need to be done individually. Also have to look for WrapSHMWrite.
+ *
+ * @param[in/out] msgStruct Message read.
+ *
+ */
+INTERNAL void SHSharedSegmentMsgToNetworkOrder(psharedSegmentMsg msg)
+{
+ if (msg)
+ {
+ msg->headerTag = htonl(msg->headerTag);
+ msg->msgSize = htonl(msg->msgSize);
+ msg->mtype = htonl(msg->mtype);
+ msg->user_id = htonl(msg->user_id);
+ msg->group_id = htonl(msg->group_id);
+ msg->command = htonl(msg->command);
+ msg->dummy = htonl(msg->dummy);
+ msg->date = htonl(msg->date);
+ }
+}
+
+/**
+ * @brief Convert fields in the psharedSegmentMsg struct to host byte order on receive
+ *
+ * Call this after each call to SHMMessageReceive. Note: the data fields are not processed
+ * and need to be done individually, e.g. in MSGFunctionDemarshall
+ *
+ * @param[in/out] msgStruct Message read.
+ *
+ */
+INTERNAL void SHSharedSegmentMsgToHostOrder(psharedSegmentMsg msg)
+{
+ if (msg)
+ {
+ msg->headerTag = ntohl(msg->headerTag);
+ msg->msgSize = ntohl(msg->msgSize);
+ msg->mtype = ntohl(msg->mtype);
+ msg->user_id = ntohl(msg->user_id);
+ msg->group_id = ntohl(msg->group_id);
+ msg->command = ntohl(msg->command);
+ msg->dummy = ntohl(msg->dummy);
+ msg->date = ntohl(msg->date);
+ }
+}
+
+INTERNAL void htonlControlStructExtended(control_struct_extended *cs)
+{
+ if (cs)
+ {
+ cs->hCard = htonl(cs->hCard);
+ cs->dwControlCode = htonl(cs->dwControlCode);
+ cs->cbSendLength = htonl(cs->cbSendLength);
+ cs->cbRecvLength = htonl(cs->cbRecvLength);
+ cs->size = htonl(cs->size);
+ cs->rv = htonl(cs->rv); // so we don't forget about it
+ }
+}
+
+INTERNAL void ntohlControlStructExtended(control_struct_extended *cs)
+{
+ if (cs)
+ {
+ cs->hCard = ntohl(cs->hCard);
+ cs->dwControlCode = ntohl(cs->dwControlCode);
+ cs->cbSendLength = ntohl(cs->cbSendLength);
+ cs->cbRecvLength = ntohl(cs->cbRecvLength);
+ cs->size = ntohl(cs->size);
+ cs->rv = ntohl(cs->rv);
+ }
+}
+
+INTERNAL void htonlTransmitStruct(transmit_struct *ts)
+{
+ if (ts)
+ {
+ ts->hCard = htonl(ts->hCard);
+ htonlSCARD_IO_REQUEST(&ts->pioSendPci);
+ ts->cbSendLength = htonl(ts->cbSendLength);
+ htonlSCARD_IO_REQUEST(&ts->pioRecvPci);
+ ts->pcbRecvLength = htonl(ts->pcbRecvLength);
+ ts->rv = htonl(ts->rv); // so we don't forget about it
+ }
+}
+
+INTERNAL void ntohlTransmitStruct(transmit_struct *ts)
+{
+ if (ts)
+ {
+ ts->hCard = ntohl(ts->hCard);
+ ntohlSCARD_IO_REQUEST(&ts->pioSendPci);
+ ts->cbSendLength = ntohl(ts->cbSendLength);
+ ntohlSCARD_IO_REQUEST(&ts->pioRecvPci);
+ ts->pcbRecvLength = ntohl(ts->pcbRecvLength);
+ ts->rv = ntohl(ts->rv);
+ }
+}
+
+INTERNAL void htonlTransmitStructExtended(transmit_struct_extended *ts)
+{
+ if (ts)
+ {
+ ts->hCard = htonl(ts->hCard);
+ htonlSCARD_IO_REQUEST(&ts->pioSendPci);
+ ts->cbSendLength = htonl(ts->cbSendLength);
+ htonlSCARD_IO_REQUEST(&ts->pioRecvPci);
+ ts->pcbRecvLength = htonl(ts->pcbRecvLength);
+ ts->size = htonl(ts->size);
+ ts->rv = htonl(ts->rv); // so we don't forget about it
+ }
+}
+
+INTERNAL void ntohlTransmitStructExtended(transmit_struct_extended *ts)
+{
+ if (ts)
+ {
+ ts->hCard = ntohl(ts->hCard);
+ ntohlSCARD_IO_REQUEST(&ts->pioSendPci);
+ ts->cbSendLength = ntohl(ts->cbSendLength);
+ ntohlSCARD_IO_REQUEST(&ts->pioRecvPci);
+ ts->pcbRecvLength = ntohl(ts->pcbRecvLength);
+ ts->size = ntohl(ts->size);
+ ts->rv = ntohl(ts->rv);
+ }
+}
+
+INTERNAL void htonlSCARD_IO_REQUEST(SCARD_IO_REQUEST *req)
+{
+ if (req)
+ {
+ req->dwProtocol = htonl(req->dwProtocol);
+ req->cbPciLength = htonl(req->cbPciLength);
+ }
+}
+
+INTERNAL void ntohlSCARD_IO_REQUEST(SCARD_IO_REQUEST *req)
+{
+ if (req)
+ {
+ req->dwProtocol = ntohl(req->dwProtocol);
+ req->cbPciLength = ntohl(req->cbPciLength);
+ }
+}
+
+INTERNAL void htonlEstablishStruct(establish_struct *es)
+{
+ if (es)
+ {
+ es->dwScope = htonl(es->dwScope);
+ es->phContext = htonl(es->phContext);
+ es->rv = htonl(es->rv);
+ }
+}
+
+INTERNAL void ntohlEstablishStruct(establish_struct *es)
+{
+ if (es)
+ {
+ es->dwScope = ntohl(es->dwScope);
+ es->phContext = ntohl(es->phContext);
+ es->rv = ntohl(es->rv);
+ }
+}
+
+INTERNAL void htonlReleaseStruct(release_struct *rs)
+{
+ if (rs)
+ {
+ rs->hContext = htonl(rs->hContext);
+ rs->rv = htonl(rs->rv);
+ }
+}
+
+INTERNAL void ntohlReleaseStruct(release_struct *rs)
+{
+ if (rs)
+ {
+ rs->hContext = ntohl(rs->hContext);
+ rs->rv = ntohl(rs->rv);
+ }
+}
+
+INTERNAL void htonlConnectStruct(connect_struct *cs)
+{
+ if (cs)
+ {
+ cs->hContext = htonl(cs->hContext);
+ cs->dwShareMode = htonl(cs->dwShareMode);
+ cs->dwPreferredProtocols = htonl(cs->dwPreferredProtocols);
+ cs->phCard = htonl(cs->phCard);
+ cs->pdwActiveProtocol = htonl(cs->pdwActiveProtocol);
+ cs->rv = htonl(cs->rv);
+ }
+}
+
+INTERNAL void ntohlConnectStruct(connect_struct *cs)
+{
+ if (cs)
+ {
+ cs->hContext = ntohl(cs->hContext);
+ cs->dwShareMode = ntohl(cs->dwShareMode);
+ cs->dwPreferredProtocols = ntohl(cs->dwPreferredProtocols);
+ cs->phCard = ntohl(cs->phCard);
+ cs->pdwActiveProtocol = ntohl(cs->pdwActiveProtocol);
+ cs->rv = ntohl(cs->rv);
+ }
+}
+
+INTERNAL void htonlReconnectStruct(reconnect_struct *rc)
+{
+ if (rc)
+ {
+ rc->hCard = htonl(rc->hCard);
+ rc->dwShareMode = htonl(rc->dwShareMode);
+ rc->dwPreferredProtocols = htonl(rc->dwPreferredProtocols);
+ rc->dwInitialization = htonl(rc->dwInitialization);
+ rc->pdwActiveProtocol = htonl(rc->pdwActiveProtocol);
+ rc->rv = htonl(rc->rv);
+ }
+}
+
+INTERNAL void ntohlReconnectStruct(reconnect_struct *rc)
+{
+ if (rc)
+ {
+ rc->hCard = ntohl(rc->hCard);
+ rc->dwShareMode = ntohl(rc->dwShareMode);
+ rc->dwPreferredProtocols = ntohl(rc->dwPreferredProtocols);
+ rc->dwInitialization = ntohl(rc->dwInitialization);
+ rc->pdwActiveProtocol = ntohl(rc->pdwActiveProtocol);
+ rc->rv = ntohl(rc->rv);
+ }
+}
+
+INTERNAL void htonlDisconnectStruct(disconnect_struct *dc)
+{
+ if (dc)
+ {
+ dc->hCard = htonl(dc->hCard);
+ dc->dwDisposition = htonl(dc->dwDisposition);
+ dc->rv = htonl(dc->rv);
+ }
+}
+
+INTERNAL void ntohlDisconnectStruct(disconnect_struct *dc)
+{
+ if (dc)
+ {
+ dc->hCard = ntohl(dc->hCard);
+ dc->dwDisposition = ntohl(dc->dwDisposition);
+ dc->rv = ntohl(dc->rv);
+ }
+}
+
+INTERNAL void htonlBeginStruct(begin_struct *bs)
+{
+ if (bs)
+ {
+ bs->hCard = htonl(bs->hCard);
+ bs->rv = htonl(bs->rv);
+ }
+}
+
+INTERNAL void ntohlBeginStruct(begin_struct *bs)
+{
+ if (bs)
+ {
+ bs->hCard = ntohl(bs->hCard);
+ bs->rv = ntohl(bs->rv);
+ }
+}
+
+INTERNAL void htonlCancelStruct(cancel_struct *cs)
+{
+ if (cs)
+ {
+ cs->hCard = htonl(cs->hCard);
+ cs->rv = htonl(cs->rv);
+ }
+}
+
+INTERNAL void ntohlCancelStruct(cancel_struct *cs)
+{
+ if (cs)
+ {
+ cs->hCard = ntohl(cs->hCard);
+ cs->rv = ntohl(cs->rv);
+ }
+}
+
+INTERNAL void htonlEndStruct(end_struct *es)
+{
+ if (es)
+ {
+ es->hCard = htonl(es->hCard);
+ es->dwDisposition = htonl(es->dwDisposition);
+ es->rv = htonl(es->rv);
+ }
+}
+
+INTERNAL void ntohlEndStruct(end_struct *es)
+{
+ if (es)
+ {
+ es->hCard = ntohl(es->hCard);
+ es->dwDisposition = ntohl(es->dwDisposition);
+ es->rv = ntohl(es->rv);
+ }
+}
+
+INTERNAL void htonlStatusStruct(status_struct *ss)
+{
+ if (ss)
+ {
+ ss->hCard = htonl(ss->hCard);
+ ss->pcchReaderLen = htonl(ss->pcchReaderLen);
+ ss->pdwState = htonl(ss->pdwState);
+ ss->pdwProtocol = htonl(ss->pdwProtocol);
+ ss->pcbAtrLen = htonl(ss->pcbAtrLen);
+ ss->rv = htonl(ss->rv);
+ }
+}
+
+INTERNAL void ntohlStatusStruct(status_struct *ss)
+{
+ if (ss)
+ {
+ ss->hCard = ntohl(ss->hCard);
+ ss->pcchReaderLen = ntohl(ss->pcchReaderLen);
+ ss->pdwState = ntohl(ss->pdwState);
+ ss->pdwProtocol = ntohl(ss->pdwProtocol);
+ ss->pcbAtrLen = ntohl(ss->pcbAtrLen);
+ ss->rv = ntohl(ss->rv);
+ }
+}
+
+INTERNAL void htonlControlStruct(control_struct *cs)
+{
+ if (cs)
+ {
+ cs->hCard = htonl(cs->hCard);
+ cs->dwControlCode = htonl(cs->dwControlCode);
+ cs->cbSendLength = htonl(cs->cbSendLength);
+ cs->cbRecvLength = htonl(cs->cbRecvLength);
+ cs->dwBytesReturned = htonl(cs->dwBytesReturned);
+ cs->rv = htonl(cs->rv);
+ }
+}
+
+INTERNAL void ntohlControlStruct(control_struct *cs)
+{
+ if (cs)
+ {
+ cs->hCard = ntohl(cs->hCard);
+ cs->dwControlCode = ntohl(cs->dwControlCode);
+ cs->cbSendLength = ntohl(cs->cbSendLength);
+ cs->cbRecvLength = ntohl(cs->cbRecvLength);
+ cs->dwBytesReturned = ntohl(cs->dwBytesReturned);
+ cs->rv = ntohl(cs->rv);
+ }
+}
+
+INTERNAL void htonlGetSetStruct(getset_struct *gs)
+{
+ if (gs)
+ {
+ gs->hCard = htonl(gs->hCard);
+ gs->dwAttrId = htonl(gs->dwAttrId);
+ gs->cbAttrLen = htonl(gs->cbAttrLen);
+ gs->rv = htonl(gs->rv);
+ }
+}
+
+INTERNAL void ntohlGetSetStruct(getset_struct *gs)
+{
+ if (gs)
+ {
+ gs->hCard = ntohl(gs->hCard);
+ gs->dwAttrId = ntohl(gs->dwAttrId);
+ gs->cbAttrLen = ntohl(gs->cbAttrLen);
+ gs->rv = ntohl(gs->rv);
+ }
+}
+
+INTERNAL void htonlVersionStruct(version_struct *vs)
+{
+ if (vs)
+ {
+ vs->major = htonl(vs->major);
+ vs->minor = htonl(vs->minor);
+ vs->rv = htonl(vs->rv);
+ }
+}
+
+INTERNAL void ntohlVersionStruct(version_struct *vs)
+{
+ if (vs)
+ {
+ vs->major = ntohl(vs->major);
+ vs->minor = ntohl(vs->minor);
+ vs->rv = ntohl(vs->rv);
+ }
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * winscard_msg.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2001-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard_msg.h 2308 2007-01-06 20:26:57Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This defines some structures and \#defines to be used over
+ * the transport layer.
+ */
+
+#ifndef __winscard_msg_h__
+#define __winscard_msg_h__
+
+#include "pcscexport.h"
+
+/** Major version of the current message protocol */
+#define PROTOCOL_VERSION_MAJOR 2
+/** Minor version of the current message protocol */
+#define PROTOCOL_VERSION_MINOR 2
+
+#define WINSCARD_MSG_HEADER_TAG 0x12345678
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ /**
+ * @brief General structure for client/serve message data exchange.
+ *
+ * It is used in the calls of \c SHMMessageSend and \c SHMMessageReceive.
+ * The field \c data is interpreted according to the values of the fields
+ * \c mtype and \c command. The possible structs the \c data field can
+ * represent are: \c version_struct \c client_struct \c establish_struct
+ * \c release_struct \c connect_struct \c reconnect_struct
+ * \c disconnect_struct \c begin_struct \c end_struct \c cancel_struct
+ * \c status_struct \c transmit_struct \c control_struct \c getset_struct
+ */
+ typedef struct rxSharedSegment
+ {
+ uint32_t headerTag; /** Always WINSCARD_MSG_HEADER_TAG */
+ uint32_t msgSize; /** size of the whole message being sent/received */
+ uint32_t mtype; /** one of the \c pcsc_adm_commands */
+ uint32_t user_id;
+ uint32_t group_id;
+ uint32_t command; /** one of the \c pcsc_msg_commands */
+ uint32_t dummy; /* was request_id in pcsc-lite <= 1.2.0 */
+ time_t date;
+ unsigned char key[PCSCLITE_MSG_KEY_LEN];
+ unsigned char data[PCSCLITE_MAX_MESSAGE_SIZE];
+ }
+ sharedSegmentMsg, *psharedSegmentMsg;
+
+ /**
+ * Command types available to use in the field \c sharedSegmentMsg.mtype.
+ */
+ enum pcsc_adm_commands
+ {
+ CMD_FUNCTION = 0xF1,
+ CMD_FAILED = 0xF2,
+ CMD_SERVER_DIED = 0xF3,
+ CMD_CLIENT_DIED = 0xF4,
+ CMD_READER_EVENT = 0xF5,
+ CMD_SYN = 0xF6,
+ CMD_ACK = 0xF7,
+ CMD_VERSION = 0xF8
+ };
+
+ /**
+ * @brief Commands available to use in the field \c sharedSegmentMsg.command.
+ */
+ enum pcsc_msg_commands
+ {
+ SCARD_ESTABLISH_CONTEXT = 0x01,
+ SCARD_RELEASE_CONTEXT = 0x02,
+ SCARD_LIST_READERS = 0x03,
+ SCARD_CONNECT = 0x04,
+ SCARD_RECONNECT = 0x05,
+ SCARD_DISCONNECT = 0x06,
+ SCARD_BEGIN_TRANSACTION = 0x07,
+ SCARD_END_TRANSACTION = 0x08,
+ SCARD_TRANSMIT = 0x09,
+ SCARD_CONTROL = 0x0A,
+ SCARD_STATUS = 0x0B,
+ SCARD_GET_STATUS_CHANGE = 0x0C,
+ SCARD_CANCEL = 0x0D,
+ SCARD_CANCEL_TRANSACTION = 0x0E,
+ SCARD_GET_ATTRIB = 0x0F,
+ SCARD_SET_ATTRIB = 0x10,
+ SCARD_TRANSMIT_EXTENDED = 0x11,
+ SCARD_CONTROL_EXTENDED = 0x12
+ };
+
+ /**
+ * @brief Information transmitted in \c CMD_VERSION Messages.
+ */
+ struct version_struct
+ {
+ int major;
+ int minor;
+ LONG rv;
+ };
+ typedef struct version_struct version_struct;
+
+ struct client_struct
+ {
+ SCARDCONTEXT hContext;
+ };
+ typedef struct client_struct client_struct;
+
+ /**
+ * @brief Information contained in \c SCARD_ESTABLISH_CONTEXT Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct establish_struct
+ {
+ DWORD dwScope;
+ SCARDCONTEXT phContext;
+ LONG rv;
+ };
+ typedef struct establish_struct establish_struct;
+
+ /**
+ * @brief Information contained in \c SCARD_RELEASE_CONTEXT Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct release_struct
+ {
+ SCARDCONTEXT hContext;
+ LONG rv;
+ };
+ typedef struct release_struct release_struct;
+
+ /**
+ * @brief contained in \c SCARD_CONNECT Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct connect_struct
+ {
+ SCARDCONTEXT hContext;
+ char szReader[MAX_READERNAME];
+ DWORD dwShareMode;
+ DWORD dwPreferredProtocols;
+ SCARDHANDLE phCard;
+ DWORD pdwActiveProtocol;
+ LONG rv;
+ };
+ typedef struct connect_struct connect_struct;
+
+ /**
+ * @brief contained in \c SCARD_RECONNECT Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct reconnect_struct
+ {
+ SCARDHANDLE hCard;
+ DWORD dwShareMode;
+ DWORD dwPreferredProtocols;
+ DWORD dwInitialization;
+ DWORD pdwActiveProtocol;
+ LONG rv;
+ };
+ typedef struct reconnect_struct reconnect_struct;
+
+ /**
+ * @brief contained in \c SCARD_DISCONNECT Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct disconnect_struct
+ {
+ SCARDHANDLE hCard;
+ DWORD dwDisposition;
+ LONG rv;
+ };
+ typedef struct disconnect_struct disconnect_struct;
+
+ /**
+ * @brief contained in \c SCARD_BEGIN_TRANSACTION Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct begin_struct
+ {
+ SCARDHANDLE hCard;
+ LONG rv;
+ };
+ typedef struct begin_struct begin_struct;
+
+ /**
+ * @brief contained in \c SCARD_END_TRANSACTION Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct end_struct
+ {
+ SCARDHANDLE hCard;
+ DWORD dwDisposition;
+ LONG rv;
+ };
+ typedef struct end_struct end_struct;
+
+ /**
+ * @brief contained in \c SCARD_CANCEL Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct cancel_struct
+ {
+ SCARDHANDLE hCard;
+ LONG rv;
+ };
+ typedef struct cancel_struct cancel_struct;
+
+ /**
+ * @brief contained in \c SCARD_STATUS Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct status_struct
+ {
+ SCARDHANDLE hCard;
+ char mszReaderNames[MAX_READERNAME];
+ DWORD pcchReaderLen;
+ DWORD pdwState;
+ DWORD pdwProtocol;
+ UCHAR pbAtr[MAX_ATR_SIZE];
+ DWORD pcbAtrLen;
+ LONG rv;
+ };
+ typedef struct status_struct status_struct;
+
+ /**
+ * @brief contained in \c SCARD_TRANSMIT Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct transmit_struct
+ {
+ SCARDHANDLE hCard;
+ SCARD_IO_REQUEST pioSendPci;
+ UCHAR pbSendBuffer[MAX_BUFFER_SIZE];
+ DWORD cbSendLength;
+ SCARD_IO_REQUEST pioRecvPci;
+ BYTE pbRecvBuffer[MAX_BUFFER_SIZE];
+ DWORD pcbRecvLength;
+ LONG rv;
+ };
+ typedef struct transmit_struct transmit_struct;
+
+ /**
+ * @brief contained in \c SCARD_TRANSMIT_EXTENDED Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct transmit_struct_extended
+ {
+ SCARDHANDLE hCard;
+ SCARD_IO_REQUEST pioSendPci;
+ DWORD cbSendLength;
+ SCARD_IO_REQUEST pioRecvPci;
+ DWORD pcbRecvLength;
+ LONG rv;
+ size_t size;
+ BYTE data[1];
+ };
+ typedef struct transmit_struct_extended transmit_struct_extended;
+
+ /**
+ * @brief contained in \c SCARD_CONTROL Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct control_struct
+ {
+ SCARDHANDLE hCard;
+ DWORD dwControlCode;
+ UCHAR pbSendBuffer[MAX_BUFFER_SIZE];
+ DWORD cbSendLength;
+ UCHAR pbRecvBuffer[MAX_BUFFER_SIZE];
+ DWORD cbRecvLength;
+ DWORD dwBytesReturned;
+ LONG rv;
+ };
+ typedef struct control_struct control_struct;
+
+ /**
+ * @brief contained in \c SCARD_CONTROL_EXTENDED Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct control_struct_extended
+ {
+ SCARDHANDLE hCard;
+ DWORD dwControlCode;
+ DWORD cbSendLength;
+ DWORD cbRecvLength;
+ DWORD pdwBytesReturned;
+ LONG rv;
+ size_t size;
+ BYTE data[1];
+ };
+ typedef struct control_struct_extended control_struct_extended;
+
+ /**
+ * @brief contained in \c SCARD_GET_ATTRIB and \c Messages.
+ *
+ * These data are passed throw the field \c sharedSegmentMsg.data.
+ */
+ struct getset_struct
+ {
+ SCARDHANDLE hCard;
+ DWORD dwAttrId;
+ UCHAR pbAttr[MAX_BUFFER_SIZE];
+ DWORD cbAttrLen;
+ LONG rv;
+ };
+ typedef struct getset_struct getset_struct;
+
+ /*
+ * Now some function definitions
+ */
+
+ int SHMClientReadMessage(psharedSegmentMsg msgStruct, DWORD dwClientID, size_t dataSize, int blockamount);
+ int SHMClientRead(psharedSegmentMsg, DWORD, int);
+ int SHMClientSetupSession(PDWORD);
+ int SHMClientCloseSession(DWORD);
+ int SHMInitializeCommonSegment(void);
+ int SHMProcessEventsContext(PDWORD, psharedSegmentMsg, int);
+ int SHMProcessEventsServer(PDWORD, int);
+ int SHMMessageSend(void *buffer, size_t buffer_size, int filedes,
+ int blockAmount);
+ int SHMMessageReceive(void *buffer, size_t buffer_size,
+ int filedes, int blockAmount);
+ int WrapSHMWrite(unsigned int command, DWORD dwClientID, unsigned int dataSize,
+ unsigned int blockAmount, void *data);
+ void SHMCleanupSharedSegment(int, const char *);
+
+ void SHSharedSegmentMsgToNetworkOrder(psharedSegmentMsg msg);
+ void SHSharedSegmentMsgToHostOrder(psharedSegmentMsg msg);
+ size_t SHMCalculateMessageSize(size_t dataSize);
+ int SHMCommunicationTimeout();
+
+ // Fix up byte ordering
+ INTERNAL void htonlControlStructExtended(control_struct_extended *cs);
+ INTERNAL void ntohlControlStructExtended(control_struct_extended *cs);
+ INTERNAL void htonlTransmitStructExtended(transmit_struct_extended *ts);
+ INTERNAL void ntohlTransmitStructExtended(transmit_struct_extended *ts);
+ INTERNAL void htonlSCARD_IO_REQUEST(SCARD_IO_REQUEST *req);
+ INTERNAL void ntohlSCARD_IO_REQUEST(SCARD_IO_REQUEST *req);
+ INTERNAL void htonlEstablishStruct(establish_struct *es);
+ INTERNAL void ntohlEstablishStruct(establish_struct *es);
+ INTERNAL void htonlTransmitStruct(transmit_struct *ts);
+ INTERNAL void ntohlTransmitStruct(transmit_struct *ts);
+ INTERNAL void htonlReleaseStruct(release_struct *rs);
+ INTERNAL void ntohlReleaseStruct(release_struct *rs);
+ INTERNAL void htonlConnectStruct(connect_struct *Cs);
+ INTERNAL void ntohlConnectStruct(connect_struct *cs);
+ INTERNAL void htonlReconnectStruct(reconnect_struct *rc);
+ INTERNAL void ntohlReconnectStruct(reconnect_struct *rc);
+ INTERNAL void htonlDisconnectStruct(disconnect_struct *dc);
+ INTERNAL void ntohlDisconnectStruct(disconnect_struct *dc);
+ INTERNAL void htonlBeginStruct(begin_struct *bs);
+ INTERNAL void ntohlBeginStruct(begin_struct *bs);
+ INTERNAL void htonlCancelStruct(cancel_struct *cs);
+ INTERNAL void ntohlCancelStruct(cancel_struct *cs);
+ INTERNAL void htonlEndStruct(end_struct *es);
+ INTERNAL void ntohlEndStruct(end_struct *es);
+ INTERNAL void htonlStatusStruct(status_struct *ss);
+ INTERNAL void ntohlStatusStruct(status_struct *ss);
+ INTERNAL void htonlControlStruct(control_struct *cs);
+ INTERNAL void ntohlControlStruct(control_struct *cs);
+ INTERNAL void htonlGetSetStruct(getset_struct *gs);
+ INTERNAL void ntohlGetSetStruct(getset_struct *gs);
+ INTERNAL void htonlVersionStruct(version_struct *vs);
+ INTERNAL void ntohlVersionStruct(version_struct *vs);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg_srv.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg_srv.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_msg_srv.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,305 @@
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2001-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ * Ludoic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard_msg_srv.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief client/server communication (on the server side only)
+ *
+ * A file based socket (\c commonSocket) is used to send/receive only messages
+ * among clients and server.\n
+ * The messages' data are passed throw a memory mapped file: \c sharedSegmentMsg.
+ */
+
+#include "config.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#ifdef HAVE_SYS_FILIO_H
+#include <sys/filio.h>
+#endif
+
+#include "wintypes.h"
+#include "pcscexport.h"
+#include "winscard.h"
+#include "debuglog.h"
+#include "winscard_msg.h"
+#include "sys_generic.h"
+
+/**
+ * Socket to a file, used for clients-server comminication.
+ */
+static int commonSocket = 0;
+extern char AraKiri;
+extern char ReCheckSerialReaders;
+
+/**
+ * @brief Accepts a Client connection.
+ *
+ * Called by \c SHMProcessEventsServer().
+ *
+ * @param[out] pdwClientID Connection ID used to reference the Client.
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 Can not establish the connection.
+ * @retval -1 Can not set the connection to non-blocking mode.
+ */
+static int SHMProcessCommonChannelRequest(PDWORD pdwClientID)
+{
+ socklen_t clnt_len;
+ int new_sock;
+ struct sockaddr_un clnt_addr;
+ int one;
+
+ clnt_len = sizeof(clnt_addr);
+
+ if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
+ &clnt_len)) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ *pdwClientID = new_sock;
+
+ one = 1;
+ if (ioctl(*pdwClientID, FIONBIO, &one) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Error: cannot set socket nonblocking: %s",
+ strerror(errno));
+ SYS_CloseFile(*pdwClientID);
+ *pdwClientID = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * @brief Prepares the communication channel used by the server to talk to the
+ * clients.
+ *
+ * This is called by the server to create a socket for local IPC with the
+ * clients. The socket is associated to the file \c PCSCLITE_CSOCK_NAME.
+ * Each client will open a connection to this socket.
+ *
+ * @return Error code.
+ * @retval 0 Success
+ * @retval -1 Can not create the socket.
+ * @retval -1 Can not bind the socket to the file \c PCSCLITE_CSOCK_NAME.
+ * @retval -1 Can not put the socket in listen mode.
+ */
+INTERNAL int SHMInitializeCommonSegment(void)
+{
+ static struct sockaddr_un serv_adr;
+
+ /*
+ * Create the common shared connection socket
+ */
+ if ((commonSocket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ serv_adr.sun_family = AF_UNIX;
+ strncpy(serv_adr.sun_path, PCSCLITE_CSOCK_NAME,
+ sizeof(serv_adr.sun_path));
+ SYS_Unlink(PCSCLITE_CSOCK_NAME);
+
+ if (bind(commonSocket, (struct sockaddr *) &serv_adr,
+ sizeof(serv_adr.sun_family) + strlen(serv_adr.sun_path) + 1) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
+ strerror(errno));
+ SHMCleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
+ return -1;
+ }
+
+ if (listen(commonSocket, 1) < 0)
+ {
+ Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
+ strerror(errno));
+ SHMCleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME);
+ return -1;
+ }
+
+ /*
+ * Chmod the public entry channel
+ */
+ SYS_Chmod(PCSCLITE_CSOCK_NAME, S_IRWXO | S_IRWXG | S_IRWXU);
+
+ return 0;
+}
+
+/**
+ * @brief Looks for messages sent by clients.
+ *
+ * This is called by the Server's function \c SVCServiceRunLoop().
+ *
+ * @param[out] pdwClientID Connection ID used to reference the Client.
+ * @param[in] blocktime Timeout (not used).
+ *
+ * @return Error code.
+ * @retval 0 Success.
+ * @retval -1 Error accessing the communication channel.
+ * @retval -1 Can not set the connection to non-blocking mode.
+ * @retval 2 Timeout.
+ */
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+#define DO_TIMEOUT
+#endif
+INTERNAL int SHMProcessEventsServer(PDWORD pdwClientID, int blocktime)
+{
+ fd_set read_fd;
+ int selret;
+#ifdef DO_TIMEOUT
+ struct timeval tv;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+#endif
+
+ FD_ZERO(&read_fd);
+
+ /*
+ * Set up the bit masks for select
+ */
+ FD_SET(commonSocket, &read_fd);
+
+ selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
+ (fd_set *) NULL,
+#ifdef DO_TIMEOUT
+ &tv
+#else
+ NULL
+#endif
+ );
+
+ if (selret < 0)
+ {
+ if (EINTR == errno)
+ return -2;
+
+ Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ if (selret == 0)
+ /* timeout. On *BSD only */
+ return 2;
+
+ /*
+ * A common pipe packet has arrived - it could be a new application
+ */
+ if (FD_ISSET(commonSocket, &read_fd))
+ {
+ Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
+ if (SHMProcessCommonChannelRequest(pdwClientID) == -1)
+ {
+ Log2(PCSC_LOG_ERROR,
+ "error in SHMProcessCommonChannelRequest: %d", *pdwClientID);
+ return -1;
+ } else
+ {
+ Log2(PCSC_LOG_DEBUG,
+ "SHMProcessCommonChannelRequest detects: %d", *pdwClientID);
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+/**
+ * @brief
+ *
+ * Called by \c ContextThread().
+ */
+INTERNAL int SHMProcessEventsContext(PDWORD pdwClientID, psharedSegmentMsg msgStruct, int blocktime)
+{
+ fd_set read_fd;
+ int selret, rv;
+ struct timeval tv;
+
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ FD_ZERO(&read_fd);
+ FD_SET(*pdwClientID, &read_fd);
+
+ selret = select(*pdwClientID + 1, &read_fd, (fd_set *) NULL,
+ (fd_set *) NULL, &tv);
+
+ if (selret < 0)
+ {
+ Log2(PCSC_LOG_ERROR, "select returns with failure: %s",
+ strerror(errno));
+ return -1;
+ }
+
+ if (selret == 0)
+ {
+// Log3(PCSC_LOG_ERROR, "SHMProcessEventsContext: select timed out, errno: %d, %s", errno,
+// strerror(errno));
+ /* timeout */
+ return 2;
+ }
+
+ if (FD_ISSET(*pdwClientID, &read_fd))
+ {
+ /*
+ * Return the current handle
+ */
+ rv = SHMClientReadMessage(msgStruct, *pdwClientID, 0, SHMCommunicationTimeout());
+ if (rv == -1)
+ { /* The client has died */
+ Log2(PCSC_LOG_DEBUG, "Client has disappeared: %d",
+ *pdwClientID);
+ msgStruct->mtype = CMD_CLIENT_DIED;
+ msgStruct->command = 0;
+ SYS_CloseFile(*pdwClientID);
+
+ return 0;
+ }
+
+ /*
+ * Set the identifier handle
+ */
+ Log2(PCSC_LOG_DEBUG, "correctly processed client: %d",
+ *pdwClientID);
+ return 1;
+ }
+
+ return -1;
+}
+
+INTERNAL int SHMCommunicationTimeout()
+{
+ int timeOut = PCSCLITE_SERVER_ATTEMPTS;
+#if !defined(NDEBUG)
+// timeOut = 120 * 1000L; // 120000 mS == 2 minutes
+// timeOut = 5 * 1000L; // 120000 mS == 2 minutes
+#endif
+ return timeOut;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,867 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * winscard_svc.c
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2001-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ * Ludovic Rousseau <ludovic.rousseau at free.fr>
+ *
+ * $Id: winscard_svc.c 2377 2007-02-05 13:13:56Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This demarshalls functions over the message queue and keeps
+ * track of clients and their handles.
+ *
+ * Each Client message is deald by creating a thread (\c CreateContextThread).
+ * The thread establishes reands and demarshalls the message and calls the
+ * appropriate function to threat it.
+ */
+
+#include "config.h"
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "wintypes.h"
+#include "pcsclite.h"
+#include "winscard.h"
+#include "debuglog.h"
+#include "winscard_msg.h"
+#include "winscard_svc.h"
+#include "sys_generic.h"
+#include "thread_generic.h"
+#include "readerfactory.h"
+#include "hotplug.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/ioctl.h>
+#include <stdlib.h>
+
+/**
+ * @brief Represents the an Application Context on the Server side.
+ *
+ * An Application Context contains Channels (\c hCard).
+ */
+static struct _psContext
+{
+ SCARDCONTEXT hContext;
+ SCARDHANDLE hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS];
+ DWORD dwClientID; /* Connection ID used to reference the Client. */
+ PCSCLITE_THREAD_T pthThread; /* Event polling thread's ID */
+ sharedSegmentMsg msgStruct; /* Msg sent by the Client */
+ int protocol_major, protocol_minor; /* Protocol number agreed between client and server*/
+} psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS];
+
+LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD);
+LONG MSGFunctionDemarshall(psharedSegmentMsg, DWORD, uint32_t *replySize);
+LONG MSGAddContext(SCARDCONTEXT, DWORD);
+LONG MSGRemoveContext(SCARDCONTEXT, DWORD);
+LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD);
+LONG MSGRemoveHandle(SCARDHANDLE, DWORD);
+LONG MSGCleanupClient(DWORD);
+
+static void ContextThread(LPVOID pdwIndex);
+
+LONG ContextsInitialize(void)
+{
+ memset(psContext, 0, sizeof(struct _psContext)*PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
+ return 1;
+}
+
+/**
+ * @brief Creates threads to handle messages received from Clients.
+ *
+ * @param[in] pdwClientID Connection ID used to reference the Client.
+ *
+ * @return Error code.
+ * @retval SCARD_S_SUCCESS Success.
+ * @retval SCARD_F_INTERNAL_ERROR Exceded the maximum number of simultaneous Application Contexts.
+ * @retval SCARD_E_NO_MEMORY Error creating the Context Thread.
+ */
+LONG CreateContextThread(PDWORD pdwClientID)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++)
+ {
+ if (psContext[i].dwClientID == 0)
+ {
+ psContext[i].dwClientID = *pdwClientID;
+ *pdwClientID = 0;
+ break;
+ }
+ }
+
+ if (i == PCSCLITE_MAX_APPLICATIONS_CONTEXTS)
+ {
+ SYS_CloseFile(psContext[i].dwClientID);
+ psContext[i].dwClientID = 0;
+ Log2(PCSC_LOG_CRITICAL, "No more context available (max: %d)",
+ PCSCLITE_MAX_APPLICATIONS_CONTEXTS);
+ return SCARD_F_INTERNAL_ERROR;
+ }
+
+ if (SYS_ThreadCreate(&psContext[i].pthThread, THREAD_ATTR_DETACHED,
+ (PCSCLITE_THREAD_FUNCTION( )) ContextThread,
+ (LPVOID) i) != 1)
+ {
+ SYS_CloseFile(psContext[i].dwClientID);
+ psContext[i].dwClientID = 0;
+ Log1(PCSC_LOG_CRITICAL, "SYS_ThreadCreate failed");
+ return SCARD_E_NO_MEMORY;
+ }
+
+ return SCARD_S_SUCCESS;
+}
+
+/*
+ * A list of local functions used to keep track of clients and their
+ * connections
+ */
+
+/**
+ * @brief Handles messages received from Clients.
+ *
+ * For each Client message a new instance of this thread is created.
+ *
+ * @param[in] dwIndex Index of an avaiable Application Context slot in
+ * \c psContext.
+ */
+
+/*
+ To handle the possible case where the client is one architecture and the server is another
+ (e.g. a PPC app running through Rosetta on OS X talking to a native i386 pcscd), we convert
+ everything going OUT over the pipe to network byte order. Conversely, everything coming IN
+ over the pipe is converted to host byte order.
+*/
+
+static void ContextThread(LPVOID dwIndex)
+{
+ LONG rv;
+ DWORD dwContextIndex = (DWORD)dwIndex;
+
+ Log2(PCSC_LOG_DEBUG, "Thread is started: %d",
+ psContext[dwContextIndex].dwClientID);
+
+ while (1)
+ {
+ sharedSegmentMsg msgStruct = {0,};
+
+ systemAwakeAndReadyCheck();
+
+ /*
+ Note: SHSharedSegmentMsgToHostOrder(&msgStruct) was called in SHMProcessEventsContext
+ This means that msgStruct contains host-order fields
+ */
+ switch (rv = SHMProcessEventsContext(&psContext[dwContextIndex].dwClientID, &msgStruct, 0))
+ {
+ case 0:
+ if (msgStruct.mtype == CMD_CLIENT_DIED)
+ {
+ /*
+ * Clean up the dead client
+ */
+ Log2(PCSC_LOG_DEBUG, "Client die: %d",
+ psContext[dwContextIndex].dwClientID);
+ MSGCleanupClient(dwContextIndex);
+ SYS_ThreadExit((LPVOID) NULL);
+ }
+ break;
+
+ case 1:
+ if (msgStruct.mtype == CMD_FUNCTION)
+ {
+ /*
+ * Command must be found
+ */
+ uint32_t replySize = 0;
+ MSGFunctionDemarshall(&msgStruct, dwContextIndex, &replySize);
+
+ /* the SCARD_TRANSMIT_EXTENDED anwser is already sent by
+ * MSGFunctionDemarshall */
+ if ((msgStruct.command != SCARD_TRANSMIT_EXTENDED)
+ && (msgStruct.command != SCARD_CONTROL_EXTENDED))
+ {
+ sharedSegmentMsg tmpMsgStruct;
+ replySize += (sizeof(sharedSegmentMsg) - sizeof(msgStruct.data));
+ memcpy(&tmpMsgStruct, &msgStruct, replySize);
+ SHSharedSegmentMsgToNetworkOrder(&tmpMsgStruct);
+ rv = SHMMessageSend(&tmpMsgStruct, replySize,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ }
+ }
+ else
+ /* pcsc-lite client/server protocol version */
+ if (msgStruct.mtype == CMD_VERSION)
+ {
+ version_struct *veStr;
+ veStr = (version_struct *) msgStruct.data;
+ ntohlVersionStruct(veStr);
+
+ /* get the client protocol version */
+ psContext[dwContextIndex].protocol_major = veStr->major;
+ psContext[dwContextIndex].protocol_minor = veStr->minor;
+
+ Log3(PCSC_LOG_DEBUG,
+ "Client is protocol version %d:%d",
+ veStr->major, veStr->minor);
+
+ veStr->rv = SCARD_S_SUCCESS;
+
+ /* client is newer than server */
+ if ((veStr->major > PROTOCOL_VERSION_MAJOR)
+ || (veStr->major == PROTOCOL_VERSION_MAJOR
+ && veStr->minor > PROTOCOL_VERSION_MINOR))
+ {
+ Log3(PCSC_LOG_CRITICAL,
+ "Client protocol is too new %d:%d",
+ veStr->major, veStr->minor);
+ Log3(PCSC_LOG_CRITICAL,
+ "Server protocol is %d:%d",
+ PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR);
+ veStr->rv = SCARD_E_NO_SERVICE;
+ }
+
+ /* set the server protocol version */
+ veStr->major = PROTOCOL_VERSION_MAJOR;
+ veStr->minor = PROTOCOL_VERSION_MINOR;
+ htonlVersionStruct(veStr);
+
+ /* send back the response */
+ sharedSegmentMsg tmpMsgStruct = msgStruct;
+ SHSharedSegmentMsgToNetworkOrder(&tmpMsgStruct);
+ rv = SHMMessageSend(&tmpMsgStruct, SHMCalculateMessageSize(sizeof(version_struct)),
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ }
+ else
+ continue;
+
+ break;
+
+ case 2:
+ /*
+ * timeout in SHMProcessEventsContext(): do nothing
+ * this is used to catch the Ctrl-C signal at some time when
+ * nothing else happens
+ */
+ break;
+
+ case -1:
+ Log1(PCSC_LOG_ERROR, "Error in SHMProcessEventsContext");
+ break;
+
+ default:
+ Log2(PCSC_LOG_ERROR,
+ "SHMProcessEventsContext unknown retval: %d", rv);
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Find out which message was sent by the Client and execute the right task.
+ *
+ * According to the command type sent by the client (\c pcsc_msg_commands),
+ * cast the message data to the correct struct so that is can be demarshalled.
+ * Then call the appropriate function to handle the request.
+ *
+ * Possible structs are: \c establish_struct \c release_struct
+ * \c connect_struct \c reconnect_struct \c disconnect_struct \c begin_struct
+ * \c cancel_struct \c end_struct \c status_struct \c transmit_struct
+ * \c control_struct \c getset_struct.
+ *
+ * @param[in] msgStruct Message to be demarshalled and executed.
+ * @param[in] dwContextIndex
+ */
+LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct, DWORD dwContextIndex, uint32_t *replySize)
+{
+ LONG rv;
+ establish_struct *esStr;
+ release_struct *reStr;
+ connect_struct *coStr;
+ reconnect_struct *rcStr;
+ disconnect_struct *diStr;
+ begin_struct *beStr;
+ cancel_struct *caStr;
+ end_struct *enStr;
+ status_struct *stStr;
+ transmit_struct *trStr;
+ control_struct *ctStr;
+ getset_struct *gsStr;
+
+ /*
+ * Zero out everything
+ */
+ rv = 0;
+ *replySize = 0;
+
+ /*
+ Note that we need to convert structs back out to network byte order
+ after the various calls are made, as this is how results are passed back
+ to the client
+ */
+ switch (msgStruct->command)
+ {
+
+ case SCARD_ESTABLISH_CONTEXT:
+ esStr = ((establish_struct *) msgStruct->data);
+ ntohlEstablishStruct(esStr);
+ esStr->rv = SCardEstablishContext(esStr->dwScope, 0, 0,
+ &esStr->phContext);
+
+ if (esStr->rv == SCARD_S_SUCCESS)
+ esStr->rv =
+ MSGAddContext(esStr->phContext, dwContextIndex);
+ htonlEstablishStruct(esStr);
+ *replySize = sizeof(establish_struct);
+ break;
+
+ case SCARD_RELEASE_CONTEXT:
+ reStr = ((release_struct *) msgStruct->data);
+ ntohlReleaseStruct(reStr);
+
+ reStr->rv = SCardReleaseContext(reStr->hContext);
+
+ if (reStr->rv == SCARD_S_SUCCESS)
+ reStr->rv =
+ MSGRemoveContext(reStr->hContext, dwContextIndex);
+
+ htonlReleaseStruct(reStr);
+ *replySize = sizeof(release_struct);
+ break;
+
+ case SCARD_CONNECT:
+ coStr = ((connect_struct *) msgStruct->data);
+ ntohlConnectStruct(coStr);
+ Log3(PCSC_LOG_DEBUG, "SCardConnect hContext: 0x%08X, phCard: 0x%08X", coStr->hContext, coStr->phCard);
+ coStr->rv = SCardConnect(coStr->hContext, coStr->szReader,
+ coStr->dwShareMode, coStr->dwPreferredProtocols,
+ &coStr->phCard, &coStr->pdwActiveProtocol);
+ Log3(PCSC_LOG_DEBUG, "SCardConnect result: %d [0x%08X]", coStr->rv, coStr->rv);
+
+ if (coStr->rv == SCARD_S_SUCCESS)
+ {
+ coStr->rv =
+ MSGAddHandle(coStr->hContext, coStr->phCard, dwContextIndex);
+ Log3(PCSC_LOG_DEBUG, "MSGAddHandle result: %d [0x%08X]", coStr->rv, coStr->rv);
+ }
+ htonlConnectStruct(coStr);
+ *replySize = sizeof(connect_struct);
+ break;
+
+ case SCARD_RECONNECT:
+ rcStr = ((reconnect_struct *) msgStruct->data);
+ ntohlReconnectStruct(rcStr);
+ rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+
+ rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode,
+ rcStr->dwPreferredProtocols,
+ rcStr->dwInitialization, &rcStr->pdwActiveProtocol);
+ htonlReconnectStruct(rcStr);
+ *replySize = sizeof(reconnect_struct);
+ break;
+
+ case SCARD_DISCONNECT:
+ diStr = ((disconnect_struct *) msgStruct->data);
+ ntohlDisconnectStruct(diStr);
+ rv = MSGCheckHandleAssociation(diStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ diStr->rv = SCardDisconnect(diStr->hCard, diStr->dwDisposition);
+
+ if (diStr->rv == SCARD_S_SUCCESS)
+ diStr->rv =
+ MSGRemoveHandle(diStr->hCard, dwContextIndex);
+ htonlDisconnectStruct(diStr);
+ *replySize = sizeof(disconnect_struct);
+ break;
+
+ case SCARD_BEGIN_TRANSACTION:
+ {
+ beStr = ((begin_struct *) msgStruct->data);
+ int ix;
+ unsigned char *px = &msgStruct->data[sizeof(begin_struct)];
+ for (ix = 0; ix < 32; ++ix)
+ *px++ = 0xEE;
+ beStr->rv = -99; // test
+ ntohlBeginStruct(beStr);
+ rv = MSGCheckHandleAssociation(beStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ beStr->rv = SCardBeginTransaction(beStr->hCard);
+ htonlBeginStruct(beStr);
+ }
+ *replySize = sizeof(begin_struct);
+ break;
+
+ case SCARD_END_TRANSACTION:
+ enStr = ((end_struct *) msgStruct->data);
+ ntohlEndStruct(enStr);
+ rv = MSGCheckHandleAssociation(enStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ enStr->rv =
+ SCardEndTransaction(enStr->hCard, enStr->dwDisposition);
+ htonlEndStruct(enStr);
+ *replySize = sizeof(end_struct);
+ break;
+
+ case SCARD_CANCEL_TRANSACTION:
+ caStr = ((cancel_struct *) msgStruct->data);
+ ntohlCancelStruct(caStr);
+ rv = MSGCheckHandleAssociation(caStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ caStr->rv = SCardCancelTransaction(caStr->hCard);
+ htonlCancelStruct(caStr);
+ *replySize = sizeof(cancel_struct);
+ break;
+
+ case SCARD_STATUS:
+ stStr = ((status_struct *) msgStruct->data);
+ ntohlStatusStruct(stStr);
+ rv = MSGCheckHandleAssociation(stStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames,
+ &stStr->pcchReaderLen, &stStr->pdwState,
+ &stStr->pdwProtocol, stStr->pbAtr, &stStr->pcbAtrLen);
+ htonlStatusStruct(stStr);
+ *replySize = sizeof(status_struct);
+ break;
+
+ case SCARD_TRANSMIT:
+ trStr = ((transmit_struct *) msgStruct->data);
+ ntohlTransmitStruct(trStr);
+ Log2(PCSC_LOG_DEBUG, "SCardTransmit cbSendLength: %d", trStr->cbSendLength);
+ rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ trStr->rv = SCardTransmit(trStr->hCard, &trStr->pioSendPci,
+ trStr->pbSendBuffer, trStr->cbSendLength,
+ &trStr->pioRecvPci, trStr->pbRecvBuffer,
+ &trStr->pcbRecvLength);
+ Log2(PCSC_LOG_DEBUG, "SCardTransmit pcbRecvLength: %d", trStr->pcbRecvLength);
+ htonlTransmitStruct(trStr);
+ *replySize = sizeof(transmit_struct);
+ break;
+
+ case SCARD_CONTROL:
+ ctStr = ((control_struct *) msgStruct->data);
+ ntohlControlStruct(ctStr);
+ rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode,
+ ctStr->pbSendBuffer, ctStr->cbSendLength,
+ ctStr->pbRecvBuffer, ctStr->cbRecvLength,
+ &ctStr->dwBytesReturned);
+ htonlControlStruct(ctStr);
+ *replySize = sizeof(control_struct);
+ break;
+
+ case SCARD_GET_ATTRIB:
+ gsStr = ((getset_struct *) msgStruct->data);
+ ntohlGetSetStruct(gsStr);
+ rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ gsStr->rv = SCardGetAttrib(gsStr->hCard, gsStr->dwAttrId,
+ gsStr->pbAttr, &gsStr->cbAttrLen);
+ htonlGetSetStruct(gsStr);
+ *replySize = sizeof(getset_struct);
+ break;
+
+ case SCARD_SET_ATTRIB:
+ gsStr = ((getset_struct *) msgStruct->data);
+ ntohlGetSetStruct(gsStr);
+ rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+ gsStr->rv = SCardSetAttrib(gsStr->hCard, gsStr->dwAttrId,
+ gsStr->pbAttr, gsStr->cbAttrLen);
+ htonlGetSetStruct(gsStr);
+ *replySize = sizeof(getset_struct);
+ break;
+
+ case SCARD_TRANSMIT_EXTENDED:
+ {
+ transmit_struct_extended *treStr;
+ unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
+ unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
+
+ treStr = ((transmit_struct_extended *) msgStruct->data);
+ ntohlTransmitStructExtended(treStr);
+ Log2(PCSC_LOG_DEBUG, "SCardTransmitExt cbSendLength: %d", treStr->cbSendLength);
+ rv = MSGCheckHandleAssociation(treStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+
+ /* one more block to read? */
+ if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ /* copy the first APDU part */
+ memcpy(pbSendBuffer, treStr->data,
+ PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr));
+
+ /* receive the second block */
+ rv = SHMMessageReceive(
+ pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*treStr),
+ treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "reception failed");
+ }
+ else
+ memcpy(pbSendBuffer, treStr->data, treStr->cbSendLength);
+
+ treStr->rv = SCardTransmit(treStr->hCard, &treStr->pioSendPci,
+ pbSendBuffer, treStr->cbSendLength,
+ &treStr->pioRecvPci, pbRecvBuffer,
+ &treStr->pcbRecvLength);
+
+ treStr->size = sizeof(*treStr) + treStr->pcbRecvLength;
+ Log3(PCSC_LOG_DEBUG, "SCardTransmitExt pcbRecvLength: %d, size: %d",
+ treStr->pcbRecvLength, treStr->size);
+ Log3(PCSC_LOG_DEBUG, "SCardTransmitExt SCardTransmit result: %d [0x%08X]",
+ treStr->rv, treStr->rv);
+ if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ /* two blocks */
+ memcpy(treStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
+ - sizeof(*treStr));
+
+ // sharedSegmentMsg tmpMsgStruct = *msgStruct;
+ // we don't copy because of the size, and because it is not used after here
+ // SHSharedSegmentMsgToNetworkOrder(&tmpMsgStruct);
+ SHSharedSegmentMsgToNetworkOrder(msgStruct);
+ htonlTransmitStructExtended(treStr);
+ rv = SHMMessageSend(msgStruct, sizeof(*msgStruct),
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "transmission failed");
+
+ rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
+ - sizeof(*treStr),
+ treStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "transmission failed");
+ }
+ else
+ {
+ /* one block only */
+ size_t dataSize = treStr->pcbRecvLength;
+ memcpy(treStr->data, pbRecvBuffer, dataSize);
+
+ // the 4 is to drop the "BYTE data[1]", which rounds to 4 bytes
+ size_t replySize = dataSize + sizeof(transmit_struct_extended) - 4;
+ Log3(PCSC_LOG_DEBUG, "SCardTransmitExt/SHMMessageSend one block: data: %d, total: %d",
+ dataSize, replySize);
+ htonlTransmitStructExtended(treStr);
+ rv = WrapSHMWrite(SCARD_TRANSMIT_EXTENDED, psContext[dwContextIndex].dwClientID,
+ replySize, SHMCommunicationTimeout(), treStr);
+
+#if 0
+ // the 4 is to drop the "BYTE data[1]", which rounds to 4 bytes
+ size_t replySize = sizeof(sharedSegmentMsg) - sizeof(msgStruct->data) + // header portion of msgStruct
+ dataSize + sizeof(transmit_struct_extended) - 4;
+
+ Log3(PCSC_LOG_DEBUG, "SCardTransmitExt/SHMMessageSend one block: data: %d, total: %d",
+ dataSize, replySize);
+ // we don't copy because of the potential size
+ SHSharedSegmentMsgToNetworkOrder(msgStruct);
+ htonlTransmitStructExtended(treStr);
+ rv = SHMMessageSend(msgStruct, replySize,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+#endif
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "transmission failed");
+ // We flip back the header, since the SHMProcessEventsContext loop
+ // tests msgStruct.command after MSGFunctionDemarshall is called
+#if 0
+ SHSharedSegmentMsgToHostOrder(msgStruct);
+#endif
+ }
+ }
+ break;
+
+ case SCARD_CONTROL_EXTENDED:
+ {
+ control_struct_extended *cteStr;
+ unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED];
+ unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED];
+
+ cteStr = ((control_struct_extended *) msgStruct->data);
+ ntohlControlStructExtended(cteStr);
+ Log2(PCSC_LOG_DEBUG, "SCardControlExt cbSendLength: %d", cteStr->cbSendLength);
+ rv = MSGCheckHandleAssociation(cteStr->hCard, dwContextIndex);
+ if (rv != 0) return rv;
+
+ /* one more block to read? */
+ if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ /* copy the first data part */
+ memcpy(pbSendBuffer, cteStr->data,
+ PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr));
+
+ /* receive the second block */
+ rv = SHMMessageReceive(
+ pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr),
+ cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "reception failed");
+ }
+ else
+ memcpy(pbSendBuffer, cteStr->data, cteStr->cbSendLength);
+
+ cteStr->rv = SCardControl(cteStr->hCard, cteStr->dwControlCode,
+ pbSendBuffer, cteStr->cbSendLength,
+ pbRecvBuffer, cteStr->cbRecvLength,
+ &cteStr->pdwBytesReturned);
+
+ cteStr->size = sizeof(*cteStr) + cteStr->pdwBytesReturned;
+ Log3(PCSC_LOG_DEBUG, "SCardControlExt pdwBytesReturned: %d, size: %d",
+ cteStr->pdwBytesReturned, cteStr->size);
+ if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE)
+ {
+ /* two blocks */
+ memcpy(cteStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE
+ - sizeof(*cteStr));
+
+ sharedSegmentMsg tmpMsgStruct = *msgStruct;
+ SHSharedSegmentMsgToNetworkOrder(&tmpMsgStruct);
+ htonlControlStructExtended(cteStr);
+ rv = SHMMessageSend(&tmpMsgStruct, sizeof(tmpMsgStruct),
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "transmission failed");
+
+ rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE
+ - sizeof(*cteStr),
+ cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "transmission failed");
+ }
+ else
+ {
+ /* one block only */
+ size_t dataSize = cteStr->pdwBytesReturned;
+ memcpy(cteStr->data, pbRecvBuffer, dataSize);
+ dataSize = dataSize + sizeof(*cteStr) - sizeof(cteStr->data);
+
+ sharedSegmentMsg tmpMsgStruct = *msgStruct;
+ dataSize = SHMCalculateMessageSize(dataSize);
+ tmpMsgStruct.msgSize = dataSize;
+ SHSharedSegmentMsgToNetworkOrder(&tmpMsgStruct);
+ cteStr = ((control_struct_extended *) tmpMsgStruct.data);
+ htonlControlStructExtended(cteStr);
+ rv = SHMMessageSend(&tmpMsgStruct, dataSize,
+ psContext[dwContextIndex].dwClientID,
+ SHMCommunicationTimeout());
+ if (rv)
+ Log1(PCSC_LOG_CRITICAL, "transmission failed");
+ }
+ }
+ break;
+
+ default:
+ Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command);
+ return -1;
+ }
+
+ return 0;
+}
+
+LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
+{
+ psContext[dwContextIndex].hContext = hContext;
+ return SCARD_S_SUCCESS;
+}
+
+LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwContextIndex)
+{
+ int i;
+ LONG rv;
+
+ if (psContext[dwContextIndex].hContext == hContext)
+ {
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ /*
+ * Disconnect each of these just in case
+ */
+
+ if (psContext[dwContextIndex].hCard[i] != 0)
+ {
+ PREADER_CONTEXT rContext = NULL;
+ DWORD dwLockId;
+
+ /*
+ * Unlock the sharing
+ */
+ rv = RFReaderInfoById(psContext[dwContextIndex].hCard[i],
+ &rContext);
+ if (rv != SCARD_S_SUCCESS)
+ return rv;
+
+ dwLockId = rContext->dwLockId;
+ rContext->dwLockId = 0;
+
+ if (psContext[dwContextIndex].hCard[i] != dwLockId)
+ {
+ /*
+ * if the card is locked by someone else we do not reset it
+ * and simulate a card removal
+ */
+ rv = SCARD_W_REMOVED_CARD;
+ }
+ else
+ {
+ /*
+ * We will use SCardStatus to see if the card has been
+ * reset there is no need to reset each time
+ * Disconnect is called
+ */
+ rv = SCardStatus(psContext[dwContextIndex].hCard[i], NULL,
+ NULL, NULL, NULL, NULL, NULL);
+ }
+
+ if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD)
+ SCardDisconnect(psContext[dwContextIndex].hCard[i],
+ SCARD_LEAVE_CARD);
+ else
+ SCardDisconnect(psContext[dwContextIndex].hCard[i],
+ SCARD_RESET_CARD);
+
+ psContext[dwContextIndex].hCard[i] = 0;
+ }
+ }
+
+ psContext[dwContextIndex].hContext = 0;
+ return SCARD_S_SUCCESS;
+ }
+
+ return SCARD_E_INVALID_VALUE;
+}
+
+LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard, DWORD dwContextIndex)
+{
+ int i;
+
+ if (psContext[dwContextIndex].hContext == hContext)
+ {
+
+ /*
+ * Find an empty spot to put the hCard value
+ */
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ if (psContext[dwContextIndex].hCard[i] == 0)
+ {
+ psContext[dwContextIndex].hCard[i] = hCard;
+ break;
+ }
+ }
+
+ if (i == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS)
+ {
+ return SCARD_F_INTERNAL_ERROR;
+ } else
+ {
+ return SCARD_S_SUCCESS;
+ }
+
+ }
+
+ return SCARD_E_INVALID_VALUE;
+}
+
+LONG MSGRemoveHandle(SCARDHANDLE hCard, DWORD dwContextIndex)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ if (psContext[dwContextIndex].hCard[i] == hCard)
+ {
+ psContext[dwContextIndex].hCard[i] = 0;
+ return SCARD_S_SUCCESS;
+ }
+ }
+
+ return SCARD_E_INVALID_VALUE;
+}
+
+
+LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, DWORD dwContextIndex)
+{
+ int i;
+
+ for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++)
+ {
+ if (psContext[dwContextIndex].hCard[i] == hCard)
+ {
+ return 0;
+ }
+ }
+
+ /* Must be a rogue client, debug log and sleep a couple of seconds */
+ Log2(PCSC_LOG_ERROR, "Client failed to authenticate (hCard: 0x%08X)", hCard);
+ SYS_Sleep(2);
+
+ return SCARD_E_INVALID_HANDLE;
+}
+
+LONG MSGCleanupClient(DWORD dwContextIndex)
+{
+ if (psContext[dwContextIndex].hContext != 0)
+ {
+ SCardReleaseContext(psContext[dwContextIndex].hContext);
+ MSGRemoveContext(psContext[dwContextIndex].hContext, dwContextIndex);
+ }
+
+ psContext[dwContextIndex].dwClientID = 0;
+ psContext[dwContextIndex].protocol_major = 0;
+ psContext[dwContextIndex].protocol_minor = 0;
+
+ return 0;
+}
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/winscard_svc.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000-2007 Apple Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * winscard_svc.h
+ * SmartCardServices
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 2001-2004
+ * David Corcoran <corcoran at linuxnet.com>
+ * Damien Sauveron <damien.sauveron at labri.fr>
+ *
+ * $Id: winscard_svc.h 1421 2005-04-12 12:09:21Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This demarshalls functions over the message queue and
+ * keeps track of clients and their handles.
+ */
+
+#ifndef __winscard_svc_h__
+#define __winscard_svc_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+ LONG ContextsInitialize(void);
+ LONG CreateContextThread(PDWORD);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/wintypes.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/wintypes.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/wintypes.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * The contents of this file constitute Original Code as defined in and
+ * are subject to the Apple Public Source License Version 1.1 (the
+ * "License"). You may not use this file except in compliance with the
+ * License. Please obtain a copy of the License at
+ * http://www.apple.com/publicsource and read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*
+ * MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ *
+ * Copyright (C) 1999
+ * David Corcoran <corcoran at linuxnet.com>
+ *
+ * $Id: wintypes.h 2071 2006-06-06 09:20:19Z rousseau $
+ */
+
+/**
+ * @file
+ * @brief This keeps a list of Windows(R) types.
+ */
+
+#ifndef __wintypes_h__
+#define __wintypes_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#if !defined(WIN32)
+
+#include <stdint.h>
+
+#ifndef BYTE
+ typedef uint8_t BYTE;
+#endif
+ typedef uint8_t UCHAR;
+ typedef uint8_t *PUCHAR;
+ typedef uint16_t USHORT;
+
+#ifndef __COREFOUNDATION_CFPLUGINCOM__
+ typedef uint32_t ULONG;
+ typedef void *LPVOID;
+ typedef int16_t BOOL;
+#endif
+
+ typedef uint32_t *PULONG;
+ typedef const void *LPCVOID;
+ typedef uint32_t DWORD;
+ typedef uint32_t *PDWORD;
+ typedef uint16_t WORD;
+ typedef int32_t LONG;
+ typedef int32_t RESPONSECODE;
+ typedef const char *LPCSTR;
+ typedef const BYTE *LPCBYTE;
+ typedef BYTE *LPBYTE;
+ typedef DWORD *LPDWORD;
+ typedef char *LPSTR;
+
+ /* these types are deprecated but still used by old drivers and applications
+ * You should use LPSTR instead */
+ typedef char *LPTSTR
+#ifdef __GNUC__
+ /* __attribute__ is a GCC only extension */
+ __attribute__ ((deprecated))
+#endif
+ ;
+ typedef const char *LPCTSTR
+#ifdef __GNUC__
+ /* __attribute__ is a GCC only extension */
+ __attribute__ ((deprecated))
+#endif
+ ;
+ typedef char *LPCWSTR
+#ifdef __GNUC__
+ /* __attribute__ is a GCC only extension */
+ __attribute__ ((deprecated))
+#endif
+ ;
+
+#else
+#include <windows.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.cpp
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.cpp (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.cpp 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+// xiodevices - additional code for finding and tracking devices via IOKit
+// >>> move this iodevices.cpp when final
+//
+#include "xiodevices.h"
+#include <security_utilities/cfutilities.h>
+#include <security_utilities/mach++.h>
+#include <IOKit/IOMessage.h>
+#include <IOKit/usb/IOUSBLib.h>
+
+using namespace MachPlusPlus;
+
+namespace Security {
+namespace IOKit {
+
+void XNotificationPort::add(DeviceMatch match, XReceiver &receiver, const char *type)
+{
+ // The kIOProviderClassKey key is required in a matching dictionary. We extract it
+ // here only for debugging purposes
+
+ CFTypeRef valueRef = NULL;
+ const char *pclass = "";
+ CFRef<CFMutableDictionaryRef> theDict = match.dict();
+ if (theDict && CFDictionaryGetValueIfPresent(theDict, CFSTR(kIOProviderClassKey), &valueRef) &&
+ CFGetTypeID(valueRef) == CFStringGetTypeID())
+ pclass = cfString(static_cast<CFStringRef>(valueRef)).c_str();
+
+ // type is usually IOServiceMatched
+ mach_port_t pp = NotificationPort::port();
+ secdebug("iokit", "XNotificationPort::add - type: %s [port: %p (0x%08X), class: %s]",
+ type, mPortRef, pp, pclass);
+
+// CFShow(match.dict());
+ // p (void)CFShow(match.dict())
+ io_iterator_t iterator;
+ Error::check(::IOServiceAddMatchingNotification(mPortRef, type,
+ match, ioNotify, &receiver, &iterator));
+ CFRetain(match); // compensate for IOSAMN not retaining its argument
+
+ // run initial iterator to process existing devices
+ secdebug("iokit", "dispatching INITIAL device match iterator %p", reinterpret_cast<void *>(iterator));
+ DeviceIterator it(iterator);
+ receiver.ioChange(it);
+}
+
+void XNotificationPort::addInterestNotification(XReceiver &receiver, io_service_t service,
+ const io_name_t interestType)
+{
+ io_iterator_t iterator;
+ mach_port_t pp = NotificationPort::port();
+// MachPlusPlus::Port(pp).dump(0);
+ secdebug("iokit", "XNotificationPort::addInterest - type: %s [port: %p (0x%08X), service: 0x%08X]",
+ interestType, mPortRef, pp, service); // IOServiceMatched
+#if 1
+ CFRunLoopSourceRef notificationRunLoopSource = IONotificationPortGetRunLoopSource(mPortRef);
+ CFRunLoopSourceRef classRunLoopSource = NotificationPort::source();
+// IONotificationPortRef r_notify_port = IONotificationPortCreate(0);
+ kern_return_t kr = ::IOServiceAddInterestNotification(mPortRef, //,r_notify_port
+ service, interestType, ioDeviceNotification, &receiver, &iterator);
+ const char *msgstr = mach_error_string(kr);
+ const char *msgtyp = mach_error_type(kr);
+ if (msgstr && msgtyp)
+ secdebug("iokit", " msg: %s, typ: %s", msgstr, msgtyp);
+// Error::check(kr);
+// if(r_notify_port) IOObjectRelease((io_object_t)r_notify_port);
+#else
+ Error::check(::IOServiceAddInterestNotification(mPortRef,
+ service, interestType, ioDeviceNotification, &receiver, &iterator));
+#endif
+}
+
+// callbacks
+
+void XNotificationPort::ioNotify(void *refCon, io_iterator_t iterator)
+{
+ secdebug("iokit", "dispatching NEW device match iterator %p", reinterpret_cast<void *>(iterator));
+ DeviceIterator it(iterator);
+ reinterpret_cast<XReceiver *>(refCon)->ioChange(it);
+}
+
+void XNotificationPort::ioDeviceNotification(void *refCon, io_service_t service,
+ natural_t messageType, void *messageArgument)
+{
+ secdebug("iokit", "dispatching NEW device notification iterator, service 0x%08X, msg: 0x%04X, arg: %p",
+ service, messageType, messageArgument);
+
+ const char *msgstr = mach_error_string(messageType);
+ const char *msgtyp = mach_error_type(messageType);
+ if (msgstr && msgtyp)
+ secdebug("iokit", " msg: %s, typ: %s", msgstr, msgtyp);
+
+#if 0
+ secdebug("iokit", "kIOMessageServiceIsTerminated: 0x%04X", kIOMessageServiceIsTerminated);
+ secdebug("iokit", "kIOMessageServiceIsSuspended: 0x%04X", kIOMessageServiceIsSuspended);
+ secdebug("iokit", "kIOMessageServiceIsResumed: 0x%04X", kIOMessageServiceIsResumed);
+ secdebug("iokit", "kIOMessageServiceIsRequestingClose: 0x%04X", kIOMessageServiceIsRequestingClose);
+ secdebug("iokit", "kIOMessageServiceIsAttemptingOpen: 0x%04X", kIOMessageServiceIsAttemptingOpen);
+ secdebug("iokit", "kIOMessageServiceWasClosed: 0x%04X", kIOMessageServiceWasClosed);
+ secdebug("iokit", "kIOMessageServiceBusyStateChange: 0x%04X", kIOMessageServiceBusyStateChange);
+ secdebug("iokit", "kIOMessageServicePropertyChange: 0x%04X", kIOMessageServicePropertyChange);
+ secdebug("iokit", "kIOMessageCanDevicePowerOff: 0x%04X", kIOMessageCanDevicePowerOff);
+ secdebug("iokit", "kIOMessageDeviceWillPowerOff: 0x%04X", kIOMessageDeviceWillPowerOff);
+ secdebug("iokit", "kIOMessageDeviceWillNotPowerOff: 0x%04X", kIOMessageDeviceWillNotPowerOff);
+ secdebug("iokit", "kIOMessageDeviceHasPoweredOn: 0x%04X", kIOMessageDeviceHasPoweredOn);
+ secdebug("iokit", "kIOMessageCanSystemPowerOff: 0x%04X", kIOMessageCanSystemPowerOff);
+ secdebug("iokit", "iokit_vendor_specific_msg(0x000A): 0x%04X", iokit_vendor_specific_msg(0x000A));
+#endif
+
+// assert(service!=io_service_t(-1));
+ if (service!=io_service_t(-1))
+ reinterpret_cast<XReceiver *>(refCon)->ioServiceChange(refCon, service, messageType, messageArgument);
+}
+
+
+} // end namespace IOKit
+} // end namespace Security
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PCSC/xiodevices.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All Rights Reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+//
+// xiodevices - code for finding and tracking devices via IOKit
+//
+#ifndef _H_XIODEVICES
+#define _H_XIODEVICES
+
+#include <security_utilities/iodevices.h>
+
+#if defined(__cplusplus)
+
+namespace Security {
+namespace IOKit {
+
+//
+// An IOKit notification port object
+//
+class XNotificationPort : public MachPortNotificationPort
+{
+public:
+ XNotificationPort() : MachPortNotificationPort() {}
+ ~XNotificationPort() {}
+
+ class XReceiver : public Receiver
+ {
+ public:
+ virtual void ioChange(DeviceIterator &iterator) = 0;
+ virtual void ioServiceChange(void *refCon, io_service_t service, //IOServiceInterestCallback
+ natural_t messageType, void *messageArgument) = 0;
+ };
+
+ void add(DeviceMatch match, XReceiver &receiver, const char *type = kIOFirstMatchNotification);
+ void addInterestNotification(XReceiver &receiver, io_service_t service,
+ const io_name_t interestType = kIOGeneralInterest);
+
+private:
+
+ static void ioDeviceNotification(void *refCon, io_service_t service,
+ natural_t messageType, void *messageArgument);
+ static void ioNotify(void *refCon, io_iterator_t iterator);
+};
+
+} // end namespace MachPlusPlus
+} // end namespace Security
+
+#endif /* __cplusplus__ */
+
+#endif //_H_XIODEVICES
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,394 @@
+/******************************************************************************
+**
+** $Id: cryptoki.h,v 1.2 2003/02/13 20:06:37 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Main cryptoki header (include in all source files)
+**
+******************************************************************************/
+
+#ifndef __CRYPTOKI_H__
+#define __CRYPTOKI_H__
+
+/******************************************************************************
+** Include all "standard" RSA PKCS #11 headers
+******************************************************************************/
+#ifndef WIN32
+#include "cryptoki_unix.h"
+#else
+#include "cryptoki_win32.h"
+#endif
+
+
+/******************************************************************************
+** Regular headers
+******************************************************************************/
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <pthread.h>
+
+#ifndef __APPLE__
+#include <musclecard.h>
+#else
+#include <PCSC/wintypes.h>
+#include <PCSC/musclecard.h>
+#endif
+
+#include <sys/types.h>
+
+
+/******************************************************************************
+** Logging (OSX needs -no-cpp-precomp for VA_ARGS to work)
+******************************************************************************/
+#ifndef NO_LOG
+#define P11_LOG_START(x) log_Start(x)
+#define P11_LOG_END(x) log_End(x,rv)
+#define P11_ERR(x) log_Err(x,__FILE__,__LINE__)
+/* #define P11_LOG(x,...) log_Log(x,##__VA_ARGS__) */
+#else
+#define P11_LOG_START(x)
+#define P11_LOG_END(x)
+#define P11_ERR(x)
+/* #define P11_LOG(x,...) */
+#endif
+
+#define LOG_LOW 0
+#define LOG_MED 5
+#define LOG_HIGH 9
+
+
+/******************************************************************************
+** Error checking macros
+******************************************************************************/
+#define PCSC_ERROR_NOLOG(x) ((x) != SCARD_S_SUCCESS)
+#define CKR_ERROR_NOLOG(x) ((x) != CKR_OK)
+#define MSC_ERROR_NOLOG(x) ((x) != MSC_SUCCESS)
+
+#ifndef NO_LOG
+#define PCSC_ERROR(x) ((error_LogCmd((x),SCARD_S_SUCCESS,(CK_CHAR*)__FILE__,__LINE__,pcsc_stringify_error)) != SCARD_S_SUCCESS)
+#define CKR_ERROR(x) ((error_LogCmd((x),CKR_OK,(CK_CHAR*)__FILE__,__LINE__,error_Stringify)) != CKR_OK)
+#define MSC_ERROR(x) ((error_LogCmd((x),MSC_SUCCESS,(CK_CHAR*)__FILE__,__LINE__,msc_error)) != MSC_SUCCESS)
+#else
+#define PCSC_ERROR(x) PCSC_ERROR_NOLOG(x)
+#define CKR_ERROR(x) CKR_ERROR_NOLOG(x)
+#define MSC_ERROR(x) MSC_ERROR_NOLOG(x)
+#endif
+
+#define INVALID_SLOT ((!st.slots) || (!slotID) || (slotID > st.slot_count))
+#define INVALID_SESSION (!(hSession && (((P11_Session *)hSession)->check == (P11_Session *)hSession)))
+#define INVALID_OBJECT (!(hObject && (((P11_Object *)hObject)->check == (P11_Object *)hObject)))
+#define READ_ONLY_SESSION 0 /* Fixme: implement this */
+#define USER_MODE (hSession && ((((P11_Session *)hSession)->session.state == CKS_RO_USER_FUNCTIONS) || (((P11_Session *)hSession)->session.state == CKS_RW_USER_FUNCTIONS)))
+
+
+/******************************************************************************
+** Utility macros
+******************************************************************************/
+#ifndef max
+#define max(a,b) (((a)>(b))?(a):(b))
+#endif
+#ifndef min
+#define min(a,b) (((a)<(b))?(a):(b))
+#endif
+
+#ifdef SUPERDEBUG
+#define malloc(a) debug_Malloc((a), __LINE__, __FILE__)
+#define calloc(a,b) debug_Calloc((a)*(b), __LINE__, __FILE__)
+#define free(a) debug_Free((a), __LINE__, __FILE__)
+#endif
+
+#define P11_MAX_ULONG ((CK_ULONG)(~0))
+
+/* Preference settings */
+#define P11_SLOT_WATCH_THREAD_FULL 0
+#define P11_SLOT_WATCH_THREAD_PARTIAL 1
+#define P11_OBJ_SORT_NEWEST_FIRST 0
+#define P11_OBJ_SORT_NEWEST_LAST 1
+#define P11_DEFAULT_ATTRIB_OBJ_SIZE 512
+#define P11_DEFAULT_PRK_ATTRIB_OBJ_SIZE 912
+#define P11_DEFAULT_CERT_ATTRIB_OBJ_SIZE 712
+#define P11_DEFAULT_LOG_FILENAME "PKCS11.log"
+
+
+/******************************************************************************
+** Library information
+******************************************************************************/
+#define PKCS11_MAJOR 0x02
+#define PKCS11_MINOR 0x0b
+#define PKCS11_LIB_MAJOR 0x01
+#define PKCS11_LIB_MINOR 0x00
+#define PKCS11_MFR_ID "SCHLUMBERGER"
+#define PKCS11_DESC "SLB PKCS #11 module"
+#define PKCS11_MAX_PIN_TRIES 8
+#define PKCS11_SO_USER_PIN 0
+#define PKCS11_USER_PIN 1
+
+
+/******************************************************************************
+** P11 typedefs
+******************************************************************************/
+
+typedef void* P11_Mutex;
+
+/* PKCS #11 mechanism info list */
+typedef struct _P11_MechInfo
+{
+ CK_MECHANISM_TYPE type; /* Mechanism type */
+ CK_MECHANISM_INFO info; /* Mechanism info */
+
+ struct _P11_MechInfo *prev;
+ struct _P11_MechInfo *next;
+} P11_MechInfo;
+
+/* PKCS #11 object attribute */
+typedef struct _P11_Attrib
+{
+ CK_ATTRIBUTE attrib; /* Object attribute data */
+ CK_BBOOL token; /* Store attribute on token? */
+
+ struct _P11_Attrib *prev;
+ struct _P11_Attrib *next;
+} P11_Attrib;
+
+/* A PKCS #11 object (session or on-card) */
+typedef struct _P11_Object
+{
+ CK_SESSION_HANDLE session; /* Session that owns this object. Not used with token objects */
+ P11_Attrib *attrib; /* List of attributes */
+ MSCObjectInfo *msc_obj; /* On-token object info. Not used with session objects */
+ MSCKeyInfo *msc_key; /* On-token key info. Not used with session objects */
+ CK_ULONG sensitive; /* True/false if this object is PIN protected */
+
+ struct _P11_Object *prev;
+ struct _P11_Object *next;
+ struct _P11_Object *check; /* Should contain the memory address of this structure */
+} P11_Object;
+
+/* Cached PIN */
+typedef struct _P11_Pin
+{
+ CK_BYTE pin[256]; /* Fixme: don't hardcode, use MAX_Musclecard_PIN) */
+ CK_ULONG pin_size;
+} P11_Pin;
+
+/* A card reader. */
+typedef struct
+{
+ CK_ULONG pin_state; /* NONE (0), USER (1), SO (2) */
+ CK_SLOT_INFO slot_info; /* CK slot structure */
+ CK_TOKEN_INFO token_info; /* CK token structure */
+ P11_Object *objects; /* List of objects */
+ P11_MechInfo *mechanisms; /* List of mechanisms */
+ P11_Pin pins[2]; /* Array of cached PIN's */
+ MSCStatusInfo status_info; /* Status of token */
+ MSCTokenConnection conn; /* Connection to token */
+} P11_Slot;
+
+/* A session with one slot. */
+typedef struct _P11_Session
+{
+ CK_SESSION_INFO session; /* CK session info */
+ CK_VOID_PTR application; /* Passed to notify callback */
+ CK_NOTIFY notify; /* Notify callback */
+
+ P11_Object *search_object; /* Current object (used with C_FindObjects) */
+ CK_ATTRIBUTE *search_attrib; /* Current search attributes */
+ CK_ULONG search_attrib_count; /* Current search attribute count */
+
+ CK_MECHANISM sign_mech; /* Active signing mechanism */
+ CK_OBJECT_HANDLE sign_key; /* Active signing key */
+
+ struct _P11_Session *prev;
+ struct _P11_Session *next;
+ struct _P11_Session *check; /* Should contain the memory address of this structure */
+} P11_Session;
+
+/* Preferences. */
+typedef struct _P11_Preferences
+{
+ CK_ULONG multi_app;
+ CK_ULONG threaded;
+ CK_ULONG log_level;
+ CK_ULONG obj_sort_order;
+ CK_ULONG slot_watch_scheme;
+ CK_ULONG cache_pin;
+ CK_ULONG version_major;
+ CK_ULONG version_minor;
+ CK_ULONG max_pin_tries;
+ CK_ULONG so_user_pin_num;
+ CK_ULONG user_pin_num;
+ CK_ULONG cert_attrib_size;
+ CK_ULONG pubkey_attrib_size;
+ CK_ULONG prvkey_attrib_size;
+ CK_ULONG data_attrib_size;
+ CK_ULONG disable_security;
+ CK_CHAR log_filename[256];
+} P11_Preferences;
+
+/* Master PKCS #11 module state information */
+typedef struct
+{
+ CK_ULONG initialized; /* Has Cryptoki been intialized */
+ P11_Preferences prefs; /* Preferences */
+ P11_Slot *slots; /* Array of all slots */
+ CK_ULONG slot_count; /* Number of slots in array */
+ P11_Session *sessions; /* List of all sessions with all slots */
+ char *slot_status; /* Says if the token state changed for a slot */
+ P11_Mutex log_lock; /* Log mutex */
+ P11_Mutex async_lock; /* Asychronous mutex */
+ CK_ULONG native_locks;
+ CK_ULONG create_threads;
+} P11_State;
+
+/* Global state variable : see p11x_state.c */
+extern P11_State st;
+
+/******************************************************************************
+** Prototypes (extensions in addition to the standard PKCS #11 functions)
+******************************************************************************/
+
+/* p11x_async.c */
+CK_RV async_StartSlotWatcher();
+CK_RV async_StopSlotWatcher();
+ void *async_WatchSlots(void *parent_pid);
+ void async_SignalHandler(int sig);
+MSCULong32 async_TokenEventCallback(MSCTokenInfo *tokenInfo, MSCULong32 len, void *data);
+
+/* p11x_debug.c */
+void debug_Init();
+void debug_CheckCorrupt(size_t i);
+void debug_Check();
+void *debug_Malloc(size_t size, int line, char *file);
+void debug_Free(void *ptr, int line, char *file);
+void *debug_Calloc(size_t size, int line, char *file);
+
+/* p11x_error.c */
+CK_RV error_LogCmd(CK_RV err, CK_RV cond, CK_CHAR *file, CK_LONG line, char *(*stringifyFn)(CK_RV));
+ char *error_Stringify(CK_RV rv);
+
+/* p11x_log.c */
+void log_Start(char *func);
+void log_End(char *func, CK_RV rv);
+void log_Err(char *msg, char *file, CK_LONG line);
+void log_Log(CK_ULONG level, char *format, ...);
+
+/* p11x_object.c */
+ void object_FreeAllObjects(CK_SLOT_ID slotID, P11_Object *list);
+ void object_FreeObject(CK_SLOT_ID slotID, P11_Object *object);
+ void object_FreeAllAttributes(P11_Attrib *list);
+CK_RV object_AddObject(CK_SLOT_ID slotID, CK_OBJECT_HANDLE *phObject);
+CK_RV object_UpdateKeyInfo(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE *hObject, MSCKeyInfo *pKeyInfo);
+CK_RV object_UpdateObjectInfo(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE *hObject, MSCObjectInfo *pObjectInfo);
+CK_RV object_FreeTokenObjects();
+CK_RV object_AddAttribute(P11_Object *object, CK_ATTRIBUTE_TYPE type, CK_BBOOL token, CK_BYTE *value, CK_ULONG value_len, P11_Attrib **attrib);
+CK_RV object_MatchAttrib(CK_ATTRIBUTE *attrib, P11_Object *object);
+CK_RV object_TemplateGetAttrib(CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE *attrib, CK_ULONG attrib_count, CK_ATTRIBUTE **attrib_out);
+CK_RV object_RSAGenKeyPair(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE *pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE *pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE *phPublicKey, CK_OBJECT_HANDLE *phPrivateKey);
+CK_RV object_GetAttrib(CK_ATTRIBUTE_TYPE type, P11_Object *object, P11_Attrib **attrib);
+CK_RV object_SetAttrib(P11_Object *object, CK_ATTRIBUTE *attrib);
+void object_LogObjects(CK_SLOT_ID slotID);
+void object_LogObject(P11_Object *object);
+void object_LogAttribute(CK_ATTRIBUTE *attrib);
+CK_RV object_AddBoolAttribute(CK_ATTRIBUTE_TYPE type, CK_BBOOL value, P11_Object *object);
+ void object_BinToHex(CK_BYTE *data, CK_ULONG data_len, CK_BYTE *out);
+CK_RV object_AddAttributes(P11_Object *object, CK_BYTE *data, CK_ULONG len);
+CK_RV object_ReadAttributes(CK_SESSION_HANDLE hSession, CK_BYTE *obj_id, P11_Object *object);
+CK_RV object_InferAttributes(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_InferKeyAttributes(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_InferObjAttributes(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_WriteAttributes(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_InferClassAttributes(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_GetCertIssuer(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len);
+CK_RV object_GetCertSubject(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len);
+CK_RV object_GetCertSerial(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len);
+CK_RV object_GetCertModulus(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len);
+CK_RV object_GetCertPubExponent(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len);
+CK_RV object_CreateCertificate(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_CreatePublicKey(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_CreatePrivateKey(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_RV object_CreateObject(CK_SESSION_HANDLE hSession, P11_Object *object);
+CK_ULONG object_MapPIN(CK_ULONG pinNum);
+CK_ULONG object_UserMode(CK_SESSION_HANDLE hSession);
+
+/* p11x_prefs.c */
+void util_ParsePreference(char *buf, CK_ULONG buf_size);
+CK_RV util_ReadPreferences();
+
+/* p11x_state.c */
+CK_RV state_Init();
+CK_RV state_Free();
+
+/* p11x_slot.c */
+ CK_RV slot_BeginTransaction(CK_ULONG slotID);
+ CK_RV slot_EndTransaction(CK_ULONG slotID, CK_ULONG action);
+CK_BBOOL slot_CheckRWSOsession(CK_ULONG slotID);
+ CK_RV slot_EstablishConnection(CK_ULONG slotID);
+ CK_RV slot_ReleaseConnection(CK_ULONG slotID);
+ CK_RV slot_UpdateSlot(CK_ULONG slotID);
+ CK_RV slot_VerifyPIN(CK_SLOT_ID slotID, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen);
+CK_ULONG slot_MinRSAKeySize(MSCULong32 cap);
+CK_ULONG slot_MaxRSAKeySize(MSCULong32 cap);
+ CK_RV slot_UpdateMechanisms(CK_ULONG slotID);
+CK_ULONG slot_MechanismCount(P11_MechInfo *mech);
+ void slot_FreeAllMechanisms(P11_MechInfo *list);
+ CK_RV slot_AddMechanism(P11_Slot *slot, CK_MECHANISM_TYPE type, P11_MechInfo **mech_info);
+ CK_RV slot_UpdateToken(CK_ULONG slotID);
+ CK_RV slot_UpdateSlotList();
+ CK_RV slot_FreeAllSlots();
+ CK_RV slot_DisconnectSlot(CK_ULONG slotID, CK_ULONG action);
+ CK_RV slot_PublicMode(CK_ULONG slotID);
+ CK_RV slot_UserMode(CK_ULONG slotID);
+ CK_RV slot_TokenPresent(CK_ULONG slotID);
+ CK_RV slot_TokenChanged();
+ CK_RV slot_AsyncUpdateSlot();
+ void slot_BlankTokenInfo(CK_TOKEN_INFO *token_info);
+ CK_RV slot_ReverifyPins();
+
+/* p11x_session.c */
+CK_RV session_AddSession(CK_SESSION_HANDLE *phSession);
+CK_RV session_FreeSession(CK_SESSION_HANDLE hSession);
+
+/* p11x_thread_xxx.c */
+CK_RV thread_Initialize();
+CK_RV thread_InitFunctions(CK_CREATEMUTEX fn_init,
+ CK_DESTROYMUTEX fn_destroy,
+ CK_LOCKMUTEX fn_lock,
+ CK_UNLOCKMUTEX fn_unlock);
+CK_RV thread_Finalize();
+CK_RV thread_MutexInit(P11_Mutex *mutex);
+CK_RV thread_MutexDestroy(P11_Mutex mutex);
+CK_RV thread_MutexLock(P11_Mutex mutex);
+CK_RV thread_MutexUnlock(P11_Mutex mutex);
+
+/* p11x_util.c */
+ void util_byterev(CK_BYTE *data, CK_ULONG len);
+CK_ULONG util_strpadlen(CK_CHAR *string, CK_ULONG max_len);
+ CK_RV util_PadStrSet(CK_CHAR *string, CK_CHAR *value, CK_ULONG size);
+ CK_RV util_StripPKCS1(CK_BYTE *data, CK_ULONG len, CK_BYTE *output, CK_ULONG *out_len);
+#ifndef __USE_GNU
+#ifndef WIN32
+ size_t strnlen(__const char *__string, size_t __maxlen);
+#else
+ size_t strnlen(const char *__string, size_t __maxlen);
+#endif
+#endif /* __USE_GNU */
+CK_BBOOL util_IsLittleEndian();
+
+/* p11x_msc.c */
+#include "p11x_msc.h"
+
+
+/******************************************************************************
+** dmalloc debugging
+******************************************************************************/
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+#endif /* __CRYPTOKI_H__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_unix.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_unix.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_unix.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,38 @@
+/******************************************************************************
+**
+** $Id: cryptoki_unix.h,v 1.2 2003/02/13 20:06:37 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: UNIX specific cryptoki definitions
+**
+******************************************************************************/
+
+#ifndef __CRYPTOKI_UNIX_H__
+#define __CRYPTOKI_UNIX_H__
+#ifndef WIN32
+
+#define CK_PTR *
+
+#define CK_DEFINE_FUNCTION(returnType, name) \
+ returnType name
+
+#define CK_DECLARE_FUNCTION(returnType, name) \
+ returnType name
+
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ returnType (* name)
+
+#define CK_CALLBACK_FUNCTION(returnType, name) \
+ returnType (* name)
+
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+#include "pkcs11.h"
+
+#endif /* ifndef WIN32 */
+#endif /* __CRYPTOKI_UNIX_H__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_win32.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_win32.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/cryptoki_win32.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,58 @@
+/******************************************************************************
+**
+** $Id: cryptoki_win32.h,v 1.2 2003/02/13 20:06:37 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: WIN32 specific cryptoki definitions
+**
+******************************************************************************/
+
+#ifndef __CRYPTOKI_WIN32_H__
+#define __CRYPTOKI_WIN32_H__
+#ifdef WIN32
+
+#pragma pack(push, cryptoki, 1)
+
+/* Specifies that the function is a DLL entry point. */
+#define CK_IMPORT_SPEC __declspec(dllimport)
+
+/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
+ * not define it in applications.
+ */
+#ifdef CRYPTOKI_EXPORTS
+/* Specified that the function is an exported DLL entry point. */
+#define CK_EXPORT_SPEC __declspec(dllexport)
+#else
+#define CK_EXPORT_SPEC CK_IMPORT_SPEC
+#endif
+
+/* Ensures the calling convention for Win32 builds */
+#define CK_CALL_SPEC __cdecl
+
+#define CK_PTR *
+
+#define CK_DEFINE_FUNCTION(returnType, name) \
+ returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+
+#define CK_DECLARE_FUNCTION(returnType, name) \
+ returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+
+#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
+
+#define CK_CALLBACK_FUNCTION(returnType, name) \
+ returnType (CK_CALL_SPEC CK_PTR name)
+
+#ifndef NULL_PTR
+#define NULL_PTR 0
+#endif
+
+#include "pkcs11.h"
+
+#pragma pack(pop, cryptoki)
+
+#endif /* WIN32 */
+#endif /* __CRYPTOKI_WIN32_H__ */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_crypt.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_crypt.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_crypt.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,442 @@
+/******************************************************************************
+**
+** $Id: p11_crypt.c,v 1.3 2004/10/14 20:33:36 mb Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Encryption and decryption
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+#include <openssl/rsa.h>
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_EncryptInit");
+
+ thread_MutexLock(st.async_lock);
+
+ log_Log(LOG_LOW, "Encrypt mech: %X", *pMechanism);
+ log_Log(LOG_LOW, "Encrypt key: %lX", hKey);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pMechanism || !hKey)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!USER_MODE)
+ rv = CKR_USER_NOT_LOGGED_IN;
+ else if (pMechanism->mechanism != CKM_RSA_PKCS)
+ rv = CKR_MECHANISM_INVALID;
+ else
+ {
+ /* Fixme: need to verify that the card supports the mechanism and its parameters */
+ /* Fixme: should probably add session.encrypt_mech and session.encrypt_key */
+ session->sign_mech = *pMechanism;
+ session->sign_key = hKey;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_EncryptInit");
+
+ return rv;
+}
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_DEFINE_FUNCTION(CK_RV, C_Encrypt)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext */
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *key = (P11_Object *)session->sign_key;
+ MSCCryptInit cryptInit;
+ CK_BYTE *t_data1 = 0;
+ CK_ULONG t_data1_len;
+
+ P11_LOG_START("C_Encrypt");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pEncryptedData || !pData)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!key)
+ rv = CKR_OPERATION_NOT_INITIALIZED;
+ else if (!USER_MODE)
+ rv = CKR_USER_NOT_LOGGED_IN;
+ else if ((CK_ULONG)(key->msc_key->keySize / 8) > ulDataLen)
+ rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else if (session->sign_mech.mechanism == CKM_RSA_PKCS)
+ {
+ /* Fixme: this is not fully implemented since it doesn't look at the mechanism parameter */
+
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherMode = MSC_MODE_RSA_NOPAD;
+ cryptInit.cipherDirection = MSC_DIR_SIGN;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ log_Log(LOG_LOW, "Using key number: %d", cryptInit.keyNum);
+
+ t_data1_len = key->msc_key->keySize / 8;
+ t_data1 = (CK_BYTE *)malloc(t_data1_len);
+
+ if (!t_data1)
+ rv = CKR_HOST_MEMORY;
+ else if (t_data1_len > *pulEncryptedDataLen)
+ rv = CKR_BUFFER_TOO_SMALL;
+ else if (!RSA_padding_add_PKCS1_type_1(t_data1, t_data1_len, pData, ulDataLen))
+ rv = CKR_FUNCTION_FAILED;
+ else if (MSC_ERROR(msc_ComputeCrypt(&st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ t_data1,
+ t_data1_len,
+ pEncryptedData,
+ (MSCPULong32)pulEncryptedDataLen)))
+ {
+ P11_ERR("MSCComputeCrypt failed");
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ if (t_data1)
+ free(t_data1);
+
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+ else
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ rv = CKR_MECHANISM_INVALID;
+ }
+
+ session->sign_key = 0;
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Encrypt");
+
+ return rv;
+}
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext data len */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_EncryptUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_EncryptUpdate");
+
+ return rv;
+}
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_EncryptFinal)
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_EncryptFinal");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_EncryptFinal");
+
+ return rv;
+}
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_DecryptInit");
+
+ thread_MutexLock(st.async_lock);
+
+ log_Log(LOG_LOW, "Decrypt mech: %X", *pMechanism);
+ log_Log(LOG_LOW, "Decrypt key: %lX", hKey);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pMechanism || !hKey)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!USER_MODE)
+ rv = CKR_USER_NOT_LOGGED_IN;
+ else if (pMechanism->mechanism != CKM_RSA_PKCS)
+ rv = CKR_MECHANISM_INVALID;
+ else
+ {
+ /* Fixme: need to verify that the card supports the mechanism and its parameters */
+ /* Fixme: should probably add session.decrypt_mech and session.decrypt_key */
+ session->sign_mech = *pMechanism;
+ session->sign_key = hKey;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DecryptInit");
+
+ return rv;
+}
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_DEFINE_FUNCTION(CK_RV, C_Decrypt)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
+ CK_BYTE_PTR pData, /* gets plaintext */
+ CK_ULONG_PTR pulDataLen /* gets p-text size */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *key = (P11_Object *)session->sign_key;
+ MSCCryptInit cryptInit;
+ CK_BYTE *t_data1 = 0, *t_data2 = 0;
+ CK_ULONG t_data1_len, t_data2_len;
+
+ P11_LOG_START("C_Decrypt");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pEncryptedData || !pData)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!key)
+ rv = CKR_OPERATION_NOT_INITIALIZED;
+ else if (!USER_MODE)
+ rv = CKR_USER_NOT_LOGGED_IN;
+ else if ((CK_ULONG)(key->msc_key->keySize / 8) > ulEncryptedDataLen)
+ rv = CKR_ENCRYPTED_DATA_LEN_RANGE;
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else if (session->sign_mech.mechanism == CKM_RSA_PKCS)
+ {
+ MSCULong32 ulValue, lenValue;
+ /* Fixme: this is not fully implemented since it doesn't look at the mechanism parameter */
+ if (MSC_ERROR(msc_GetCapabilities(&st.slots[session->session.slotID - 1].conn,
+ MSC_TAG_CAPABLE_RSA,
+ (CK_BYTE_PTR) &ulValue,
+ &lenValue)))
+ rv = CKR_FUNCTION_FAILED;
+ else if (ulValue & MSC_CAPABLE_RSA_NOPAD)
+ {
+ log_Log(LOG_LOW, "Decrypt: RSA NOPAD; key %i; keysize %i",
+ key->msc_key->keyNum, key->msc_key->keySize);
+
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherMode = MSC_MODE_RSA_NOPAD;
+ cryptInit.cipherDirection = MSC_DIR_DECRYPT;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ t_data1 = (CK_BYTE *)malloc(key->msc_key->keySize / 8);
+ t_data2 = (CK_BYTE *)malloc(key->msc_key->keySize / 8);
+ t_data2_len = key->msc_key->keySize / 8; /* FIX - bugzilla 1701 */
+
+ if (!t_data1 || !t_data2)
+ rv = CKR_HOST_MEMORY;
+ else if (MSC_ERROR(msc_ComputeCrypt(
+ &st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ pEncryptedData,
+ ulEncryptedDataLen,
+ t_data1,
+ (MSCPULong32)&t_data1_len)))
+ {
+ P11_ERR("MSCComputeCrypt failed");
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else if (CKR_ERROR(rv = util_StripPKCS1(t_data1, t_data1_len,
+ t_data2, &t_data2_len)))
+ /* Intentionally blank */;
+ else if (t_data2_len > *pulDataLen)
+ rv = CKR_BUFFER_TOO_SMALL;
+ else
+ {
+ memcpy(pData, t_data2, t_data2_len);
+ *pulDataLen = t_data2_len;
+ }
+ }
+ else if (ulValue & MSC_CAPABLE_RSA_PKCS1)
+ {
+ log_Log(LOG_LOW, "Decrypt: RSA PKCS1; key %i; keysize %i",
+ key->msc_key->keyNum, key->msc_key->keySize);
+
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherDirection = MSC_DIR_DECRYPT;
+ cryptInit.cipherMode = MSC_MODE_RSA_PAD_PKCS1;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ t_data1 = (CK_BYTE *)malloc(key->msc_key->keySize / 8);
+
+ if (!t_data1)
+ rv = CKR_HOST_MEMORY;
+ else if (MSC_ERROR(msc_ComputeCrypt(
+ &st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ pEncryptedData,
+ ulEncryptedDataLen,
+ t_data1,
+ (MSCPULong32)&t_data1_len)))
+ {
+ P11_ERR("MSCComputeCrypt failed");
+ rv = CKR_FUNCTION_FAILED;
+ }
+ if (t_data1_len > *pulDataLen)
+ rv = CKR_BUFFER_TOO_SMALL;
+ else
+ {
+ memcpy(pData, t_data1, t_data1_len);
+ *pulDataLen = t_data1_len;
+ }
+ }
+ else
+ rv = CKR_MECHANISM_PARAM_INVALID;
+
+ if (t_data1)
+ free(t_data1);
+
+ if (t_data2)
+ free(t_data2);
+
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+ else
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ rv = CKR_MECHANISM_INVALID;
+ }
+
+ session->sign_key = 0;
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Decrypt");
+
+ return rv;
+}
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* input length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* p-text size */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DecryptUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DecryptUpdate");
+
+ return rv;
+}
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptFinal)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* gets plaintext */
+ CK_ULONG_PTR pulLastPartLen /* p-text size */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DecryptFinal");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DecryptFinal");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_digest.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_digest.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_digest.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,142 @@
+/******************************************************************************
+**
+** $Id: p11_digest.c,v 1.2 2003/02/13 20:06:37 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Message digesting
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DigestInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DigestInit");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DigestInit");
+
+ return rv;
+}
+
+
+/* C_Digest digests data in a single part. */
+CK_DEFINE_FUNCTION(CK_RV, C_Digest)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to digest */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets digest length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_Digest");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Digest");
+
+ return rv;
+}
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DigestUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DigestUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DigestUpdate");
+
+ return rv;
+}
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested. */
+CK_DEFINE_FUNCTION(CK_RV, C_DigestKey)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* secret key to digest */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DigestKey");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DigestKey");
+
+ return rv;
+}
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DigestFinal)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DigestFinal");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DigestFinal");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_dual.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_dual.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_dual.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,125 @@
+/******************************************************************************
+**
+** $Id: p11_dual.c,v 1.2 2003/02/13 20:06:38 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Dual-function cryptographic operation
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DigestEncryptUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DigestEncryptUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DigestEncryptUpdate");
+
+ return rv;
+}
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptDigestUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DecryptDigestUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DecryptDigestUpdate");
+
+ return rv;
+}
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_SignEncryptUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SignEncryptUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SignEncryptUpdate");
+
+ return rv;
+}
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_DEFINE_FUNCTION(CK_RV, C_DecryptVerifyUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets p-text length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DecryptVerifyUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DecryptVerifyUpdate");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_ext.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_ext.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_ext.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,38 @@
+/******************************************************************************
+**
+** $Id: p11_ext.c,v 1.2 2003/02/13 20:06:38 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Functions added in for Cryptoki Version 2.01 or later
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_WaitForSlotEvent");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_WaitForSlotEvent");
+
+ return rv;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_general.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_general.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_general.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,242 @@
+/******************************************************************************
+**
+** $Id: p11_general.c,v 1.2 2003/02/13 20:06:38 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: General-purpose
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* Win32 defines CreateMutex as a macro (CreateMutexA) */
+/* We need the preprocessor to not process the variable name in pInitArgs */
+#ifdef WIN32
+#undef CreateMutex
+#endif
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_DEFINE_FUNCTION(CK_RV, C_Initialize)
+(
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets * cast to CK_C_INITIALIZE_ARGS_PTR * and dereferenced */
+)
+{
+ CK_RV rv = CKR_OK;
+ CK_C_INITIALIZE_ARGS blank_init_args;
+ CK_C_INITIALIZE_ARGS *init_args;
+
+ memset(&blank_init_args, 0x00, sizeof(blank_init_args));
+
+ /* Must initialize the state and preferences before any logging starts */
+ rv = state_Init();
+
+ P11_LOG_START("C_Initialize");
+
+ if (CKR_ERROR(rv))
+ /* Do nothing */;
+ else if (st.initialized)
+ rv = CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ else
+ {
+ if (!pInitArgs)
+ init_args = &blank_init_args;
+ else
+ {
+ init_args = (CK_C_INITIALIZE_ARGS *)pInitArgs;
+ log_Log(LOG_LOW, "Init flags: 0x%X", init_args->flags);
+ }
+
+ /* If preferences request non-threaded mode then force this flag */
+ if (!st.prefs.threaded)
+ init_args->flags |= CKF_LIBRARY_CANT_CREATE_OS_THREADS;
+
+ if ((CKF_OS_LOCKING_OK & init_args->flags))
+ {
+ log_Log(LOG_LOW, "Native thread locks are fine");
+ st.native_locks = 1;
+ }
+ else
+ {
+ log_Log(LOG_LOW, "Using non-native (application supplied) thread locks");
+ st.native_locks = 0;
+ }
+
+ if ((CKF_LIBRARY_CANT_CREATE_OS_THREADS & init_args->flags))
+ {
+ log_Log(LOG_LOW, "Application does not allow thread creation; disabling threaded slot watcher");
+ st.create_threads = 0;
+ }
+ else
+ {
+ log_Log(LOG_LOW, "Creating threads is fine; using threaded slot watcher");
+ st.create_threads = 1;
+ }
+
+ if (init_args->pReserved)
+ rv = CKR_ARGUMENTS_BAD;
+ else if ((init_args->CreateMutex || init_args->DestroyMutex || init_args->LockMutex || init_args->UnlockMutex) &&
+ (!init_args->CreateMutex || !init_args->DestroyMutex || !init_args->LockMutex || !init_args->UnlockMutex))
+ {
+ rv = CKR_ARGUMENTS_BAD;
+ }
+ else
+ {
+ if (!st.prefs.threaded)
+ log_Log(LOG_LOW, "All threading disabled");
+ else
+ {
+ if (st.native_locks)
+ rv = thread_Initialize();
+ else
+ rv = thread_InitFunctions(init_args->CreateMutex,
+ init_args->DestroyMutex,
+ init_args->LockMutex,
+ init_args->UnlockMutex);
+
+ if (CKR_ERROR(rv))
+ log_Log(LOG_MED, "Could not initialize thread subsystem");
+ else
+ {
+ thread_MutexInit(&st.log_lock);
+ thread_MutexInit(&st.async_lock);
+ }
+ }
+
+ if (!CKR_ERROR_NOLOG(rv))
+ {
+ if (CKR_ERROR(rv = slot_UpdateSlotList()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (!CKR_ERROR(rv = async_StartSlotWatcher()))
+ {
+ st.initialized = TRUE;
+ (void)CKR_ERROR(slot_TokenChanged());
+ }
+ }
+ }
+ }
+
+ P11_LOG_END("C_Initialize");
+ return rv;
+}
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library. */
+CK_DEFINE_FUNCTION(CK_RV, C_Finalize)
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_Finalize");
+
+ /* Pause in case there are pending active operations */
+ thread_MutexLock(st.async_lock);
+ thread_MutexUnlock(st.async_lock);
+
+ if (!st.initialized)
+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+ else if (pReserved)
+ rv = CKR_ARGUMENTS_BAD;
+ else
+ {
+ (void)CKR_ERROR(async_StopSlotWatcher());
+
+ if (st.log_lock)
+ {
+ thread_MutexDestroy(st.log_lock);
+ st.log_lock = 0;
+ }
+
+ if (st.async_lock)
+ {
+ thread_MutexDestroy(st.async_lock);
+ st.async_lock = 0;
+ }
+
+ if (st.prefs.threaded)
+ thread_Finalize();
+
+ (void)CKR_ERROR(state_Free());
+ }
+
+ P11_LOG_END("C_Finalize");
+
+ return rv;
+}
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)
+(
+ CK_INFO_PTR pInfo /* location that receives information */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GetInfo");
+
+ thread_MutexLock(st.async_lock);
+
+ if (!st.initialized)
+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+ else if(!pInfo)
+ rv = CKR_ARGUMENTS_BAD;
+ else
+ {
+ log_Log(LOG_LOW, "PKCS #11 version: %d.%d", st.prefs.version_major, st.prefs.version_minor);
+ pInfo->cryptokiVersion.major = (CK_BYTE)st.prefs.version_major;
+ pInfo->cryptokiVersion.minor = (CK_BYTE)st.prefs.version_minor;
+ util_PadStrSet(pInfo->manufacturerID, (CK_CHAR *)PKCS11_MFR_ID, sizeof(pInfo->manufacturerID));
+ pInfo->flags = 0;
+ util_PadStrSet(pInfo->libraryDescription, (CK_CHAR *)PKCS11_DESC, sizeof(pInfo->libraryDescription));
+ pInfo->libraryVersion.major = PKCS11_LIB_MAJOR;
+ pInfo->libraryVersion.minor = PKCS11_LIB_MINOR;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetInfo");
+ return rv;
+}
+
+
+/* C_GetFunctionList returns the function list. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionList)
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
+ * function list */
+)
+{
+ CK_RV rv = CKR_OK;
+ static CK_FUNCTION_LIST fnList;
+
+ /* Must initialize the state and preferences before any logging starts */
+ rv = state_Init();
+
+ P11_LOG_START("C_GetFunctionList");
+
+ if (CKR_ERROR(rv))
+ /* Do nothing */;
+ else if (!ppFunctionList)
+ rv = CKR_ARGUMENTS_BAD;
+ else
+ {
+ fnList.version.major = (CK_BYTE)st.prefs.version_major;
+ fnList.version.minor = (CK_BYTE)st.prefs.version_minor;
+
+#define CK_PKCS11_FUNCTION_INFO(name) fnList.name = name;
+#include "pkcs11f.h"
+#undef CK_PKCS11_FUNCTION_INFO
+
+ *ppFunctionList = &fnList;
+ }
+
+ P11_LOG_END("C_GetFunctionList");
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_key.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_key.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_key.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,350 @@
+/******************************************************************************
+**
+** $Id: p11_key.c,v 1.2 2003/02/13 20:06:38 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Key management
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object. */
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateKey)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
+ CK_ULONG ulCount, /* # of attrs in template */
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GenerateKey");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GenerateKey");
+
+ return rv;
+}
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateKeyPair)
+(
+ CK_SESSION_HANDLE hSession, /* session
+ * handle */
+ CK_MECHANISM_PTR pMechanism, /* key-gen
+ * mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
+ * for pub.
+ * key */
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
+ * attrs. */
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
+ * for priv.
+ * key */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
+ * attrs. */
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
+ * key
+ * handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
+ * priv. key
+ * handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ CK_ULONG i;
+ CK_ATTRIBUTE *attrib;
+
+ P11_LOG_START("C_GenerateKeyPair");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pMechanism || !pPublicKeyTemplate ||
+ !pPrivateKeyTemplate || !phPublicKey || !phPrivateKey)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (READ_ONLY_SESSION)
+ rv = CKR_SESSION_READ_ONLY;
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else
+ {
+ log_Log(LOG_LOW, "Mech type: %lX", pMechanism->mechanism);
+ log_Log(LOG_LOW, "Param Len: %lu", pMechanism->ulParameterLen);
+ log_Log(LOG_LOW, "Pub attrib count: %lu", ulPublicKeyAttributeCount);
+ for (i = 0; i < ulPublicKeyAttributeCount; i++)
+ log_Log(LOG_LOW, "Attrib type: %lX", pPublicKeyTemplate[i].type);
+ log_Log(LOG_LOW, "Priv attrib count: %lu", ulPrivateKeyAttributeCount);
+ for (i = 0; i < ulPrivateKeyAttributeCount; i++)
+ log_Log(LOG_LOW, "Attrib type: %lX", pPrivateKeyTemplate[i].type);
+
+ /* Fixme: Only supports generating keys on card */
+ if (CKR_ERROR(object_TemplateGetAttrib(CKA_TOKEN, pPublicKeyTemplate, ulPublicKeyAttributeCount, &attrib)) ||
+ CKR_ERROR(object_TemplateGetAttrib(CKA_TOKEN, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, &attrib)))
+ rv = CKR_ATTRIBUTE_VALUE_INVALID;
+ else if (pMechanism->mechanism == CKM_RSA_PKCS_KEY_PAIR_GEN)
+ (void)CKR_ERROR(rv = object_RSAGenKeyPair(hSession, pPublicKeyTemplate,
+ ulPublicKeyAttributeCount,
+ pPrivateKeyTemplate,
+ ulPrivateKeyAttributeCount,
+ phPublicKey,
+ phPrivateKey));
+ else
+ rv = CKR_MECHANISM_INVALID;
+
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+
+ log_Log(LOG_LOW, "Returning handles for public key: %lX and private key: %lX", *phPublicKey, *phPrivateKey);
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GenerateKeyPair");
+
+ return rv;
+}
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_DEFINE_FUNCTION(CK_RV, C_WrapKey)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_WrapKey");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_WrapKey");
+
+ return rv;
+}
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object. */
+CK_DEFINE_FUNCTION(CK_RV, C_UnwrapKey)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Object *object;
+ P11_Attrib *attrib;
+ MSCCryptInit cryptInit;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *key = (P11_Object *)hUnwrappingKey;
+ CK_BYTE *output = 0, *final_output = 0;
+ MSCULong32 output_len;
+ CK_ULONG final_output_len;
+ CK_ULONG i;
+
+ P11_LOG_START("C_UnwrapKey");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pMechanism ||
+ !hUnwrappingKey || !pWrappedKey || !pTemplate)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (READ_ONLY_SESSION)
+ rv = CKR_SESSION_READ_ONLY;
+ else if (pMechanism->mechanism == CKM_RSA_PKCS)
+ {
+ log_Log(LOG_LOW, "UnwrapKey: %X", hUnwrappingKey);
+ log_Log(LOG_LOW, "WrappedLen: %lu", ulWrappedKeyLen);
+
+ if (CKR_ERROR(object_AddObject(session->session.slotID, (CK_OBJECT_HANDLE *)&object)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ {
+ for (i = 0; i < ulAttributeCount; i++)
+ if (CKR_ERROR(rv = object_AddAttribute(object,
+ pTemplate[i].type,
+ FALSE,
+ (CK_BYTE *)pTemplate[i].pValue,
+ pTemplate[i].ulValueLen,
+ &attrib)))
+ break;
+
+ if (!CKR_ERROR(rv))
+ {
+ MSCULong32 ulValue, lenValue;
+ if (MSC_ERROR(msc_GetCapabilities(
+ &st.slots[session->session.slotID - 1].conn,
+ MSC_TAG_CAPABLE_RSA,
+ (CK_BYTE_PTR) &ulValue,
+ &lenValue)))
+ rv = CKR_FUNCTION_FAILED;
+ else if (ulValue & MSC_CAPABLE_RSA_NOPAD)
+ {
+ log_Log(LOG_LOW, "UnwrapKey num: %lu", key->msc_key->keyNum);
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherMode = MSC_MODE_RSA_NOPAD;
+ cryptInit.cipherDirection = MSC_DIR_DECRYPT;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ output_len = key->msc_key->keySize / 8;
+ output = (CK_BYTE *)malloc(output_len);
+ final_output_len = output_len;
+ final_output = (CK_BYTE *)malloc(final_output_len);
+
+ if (!output || !final_output)
+ rv = CKR_HOST_MEMORY;
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else if (MSC_ERROR(msc_ComputeCrypt(
+ &st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ pWrappedKey,
+ ulWrappedKeyLen,
+ output,
+ &output_len)))
+ {
+ P11_ERR("MSCComputeCrypt failed");
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+
+ if (!CKR_ERROR(rv = util_StripPKCS1(output, output_len,
+ final_output, &final_output_len)))
+ {
+ rv = object_AddAttribute(object, CKA_VALUE, FALSE,
+ final_output, final_output_len, &attrib);
+ *phKey = (CK_OBJECT_HANDLE)object;
+ }
+ }
+ }
+ else if (ulValue & MSC_CAPABLE_RSA_PKCS1)
+ {
+ log_Log(LOG_LOW, "UnwrapKey num: %lu", key->msc_key->keyNum);
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherDirection = MSC_DIR_DECRYPT;
+ cryptInit.cipherMode = MSC_MODE_RSA_PAD_PKCS1;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ output_len = key->msc_key->keySize / 8;
+ output = (CK_BYTE *)malloc(output_len);
+
+ if (!output)
+ rv = CKR_HOST_MEMORY;
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else if (MSC_ERROR(msc_ComputeCrypt(
+ &st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ pWrappedKey,
+ ulWrappedKeyLen,
+ output,
+ &output_len)))
+ {
+ P11_ERR("MSCComputeCrypt failed");
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+
+ rv = object_AddAttribute(object, CKA_VALUE, FALSE,
+ output, output_len, &attrib);
+ *phKey = (CK_OBJECT_HANDLE)object;
+ }
+ }
+ else
+ rv = CKR_MECHANISM_PARAM_INVALID;
+
+ if (output)
+ free(output);
+
+ if (final_output)
+ free(final_output);
+ }
+ }
+ }
+ else
+ {
+ log_Log(LOG_LOW, "Invalid mechanism specified: 0x%lX", pMechanism->mechanism);
+ rv = CKR_MECHANISM_INVALID;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_UnwrapKey");
+
+ return rv;
+}
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object. */
+CK_DEFINE_FUNCTION(CK_RV, C_DeriveKey)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
+ CK_OBJECT_HANDLE hBaseKey, /* base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_DeriveKey");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DeriveKey");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_object.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_object.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_object.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,628 @@
+/******************************************************************************
+**
+** $Id: p11_object.c,v 1.2 2003/02/13 20:06:38 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Object management
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_CreateObject creates a new object. */
+CK_DEFINE_FUNCTION(CK_RV, C_CreateObject)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *object;
+ P11_Attrib *attrib;
+ CK_BBOOL is_token = 0, token_attrib;
+ CK_ULONG i;
+ CK_ULONG obj_class;
+ CK_ATTRIBUTE t_attrib;
+
+ P11_LOG_START("C_CreateObject");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pTemplate)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (READ_ONLY_SESSION)
+ rv = CKR_SESSION_READ_ONLY;
+ else if (!CKR_ERROR(object_TemplateGetAttrib(CKA_CLASS, pTemplate, ulCount, 0)))
+ {
+ if (!CKR_ERROR(rv = object_AddObject(session->session.slotID, (CK_OBJECT_HANDLE *)&object)))
+ {
+ for (i = 0; i < ulCount; i++)
+ {
+ if (pTemplate[i].type == CKA_TOKEN)
+ is_token = ((CK_BYTE *)(pTemplate[i].pValue))[0];
+
+ if ((pTemplate[i].type == CKA_VALUE) ||
+ (pTemplate[i].type == CKA_SUBJECT) ||
+ (pTemplate[i].type == CKA_ISSUER) ||
+ (pTemplate[i].type == CKA_SERIAL_NUMBER) ||
+ (pTemplate[i].type == CKA_PUBLIC_EXPONENT) ||
+ (pTemplate[i].type == CKA_PRIVATE_EXPONENT) ||
+ (pTemplate[i].type == CKA_PRIME_1) ||
+ (pTemplate[i].type == CKA_PRIME_2) ||
+ (pTemplate[i].type == CKA_EXPONENT_1) ||
+ (pTemplate[i].type == CKA_EXPONENT_2) ||
+ (pTemplate[i].type == CKA_COEFFICIENT))
+ {
+ token_attrib = FALSE;
+ }
+ else
+ token_attrib = TRUE;
+
+ if (CKR_ERROR(rv = object_AddAttribute(object,
+ pTemplate[i].type,
+ token_attrib,
+ (CK_BYTE *)pTemplate[i].pValue,
+ pTemplate[i].ulValueLen,
+ &attrib)))
+ break;
+
+ object_LogAttribute(&pTemplate[i]);
+ }
+
+ if (is_token && !CKR_ERROR(rv))
+ {
+ t_attrib.type = CKA_CLASS;
+ t_attrib.pValue = &obj_class;
+ t_attrib.ulValueLen = sizeof(obj_class);
+
+ obj_class = CKO_CERTIFICATE;
+
+ if (object_MatchAttrib(&t_attrib, object))
+ {
+ /* Pull the serial from the cert because Netscape/Mozilla sets it incorrectly */
+ CK_BYTE buf[4096]; /* Fixme: don't hardcode this */
+ P11_Attrib *obj_attrib;
+ CK_ULONG len;
+
+ if (!CKR_ERROR(object_GetAttrib(CKA_VALUE, object, &obj_attrib)) &&
+ !CKR_ERROR(object_GetCertSerial((CK_BYTE *)obj_attrib->attrib.pValue,
+ obj_attrib->attrib.ulValueLen,
+ buf,
+ &len)))
+ {
+ log_Log(LOG_LOW, "Overwriting certificate serial number with infered value");
+ (void)CKR_ERROR(object_AddAttribute(object, CKA_SERIAL_NUMBER, FALSE, buf, len, 0));
+ }
+
+ /* Write the cert & attributes to the card */
+ log_Log(LOG_LOW, "Creating certificate");
+ rv = object_CreateCertificate(hSession, object);
+ }
+ else
+ {
+ obj_class = CKO_PUBLIC_KEY;
+ if (object_MatchAttrib(&t_attrib, object))
+ {
+ log_Log(LOG_LOW, "Creating public key");
+ rv = object_CreatePublicKey(hSession, object);
+ }
+ else
+ {
+ obj_class = CKO_PRIVATE_KEY;
+ if (object_MatchAttrib(&t_attrib, object))
+ {
+ log_Log(LOG_LOW, "Creating private key");
+ rv = object_CreatePrivateKey(hSession, object);
+
+ { P11_Object *object2;
+ // Fixme: hack to make sure the public key is on the token since some
+ // Fixme: cards require the public key. Missing error checking.
+ log_Log(LOG_LOW, "Creating public key (THIS MAY BE REMOVED IN THE FUTURE)");
+ rv = object_AddObject(session->session.slotID, (CK_OBJECT_HANDLE *)&object2);
+ (void)CKR_ERROR(rv);
+
+ obj_class = CKO_PUBLIC_KEY;
+ rv = object_AddAttribute(object2,
+ CKA_CLASS,
+ TRUE,
+ (CK_BYTE *)&obj_class,
+ sizeof(obj_class), 0);
+
+ rv = object_GetAttrib(CKA_ID, object, &attrib);
+ (void)CKR_ERROR(rv);
+ rv = object_AddAttribute(object2,
+ attrib->attrib.type,
+ TRUE,
+ (CK_BYTE *)attrib->attrib.pValue,
+ attrib->attrib.ulValueLen, 0);
+ (void)CKR_ERROR(rv);
+ rv = object_GetAttrib(CKA_MODULUS, object, &attrib);
+ (void)CKR_ERROR(rv);
+ rv = object_AddAttribute(object2,
+ attrib->attrib.type,
+ TRUE,
+ (CK_BYTE *)attrib->attrib.pValue,
+ attrib->attrib.ulValueLen, 0);
+ (void)CKR_ERROR(rv);
+ rv = object_GetAttrib(CKA_PUBLIC_EXPONENT, object, &attrib);
+ (void)CKR_ERROR(rv);
+ rv = object_AddAttribute(object2,
+ attrib->attrib.type,
+ TRUE,
+ (CK_BYTE *)attrib->attrib.pValue,
+ attrib->attrib.ulValueLen, 0);
+ (void)CKR_ERROR(rv);
+
+ rv = object_CreatePublicKey(hSession, object2);
+ (void)CKR_ERROR(rv); }
+ }
+ else
+ {
+ log_Log(LOG_LOW, "Creating object");
+ rv = object_CreateObject(hSession, object);
+ }
+ }
+ }
+ }
+
+ *phObject = (CK_OBJECT_HANDLE)object;
+ log_Log(LOG_LOW, "New object handle: %lX", *phObject);
+ }
+ }
+ else
+ rv = CKR_TEMPLATE_INCOMPLETE;
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_CreateObject");
+ return rv;
+}
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy. */
+CK_DEFINE_FUNCTION(CK_RV, C_CopyObject)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_CopyObject");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_CopyObject");
+
+ return rv;
+}
+
+
+/* C_DestroyObject destroys an object. */
+CK_DEFINE_FUNCTION(CK_RV, C_DestroyObject)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_DestroyObject");
+
+ thread_MutexLock(st.async_lock);
+
+ log_Log(LOG_LOW, "Object handle: %lX", hObject);
+ object_FreeObject(session->session.slotID, (P11_Object *)hObject);
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_DestroyObject");
+
+ return rv;
+}
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetObjectSize)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GetObjectSize");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetObjectSize");
+
+ return rv;
+}
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetAttributeValue)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
+ CK_ULONG ulCount /* attributes in template */
+)
+{
+ CK_RV rv = CKR_OK;
+ CK_RV perm_rv = CKR_OK;
+ P11_Object *object = (P11_Object *)hObject;
+ P11_Attrib *attrib;
+ CK_ULONG i;
+ CK_CHAR *obj_type;
+
+ P11_LOG_START("C_GetAttributeValue");
+
+ thread_MutexLock(st.async_lock);
+
+ log_Log(LOG_LOW, "Object handle: %lX", hObject);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pTemplate)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (INVALID_OBJECT)
+ rv = CKR_OBJECT_HANDLE_INVALID;
+ else
+ {
+ if (object->msc_key)
+ obj_type = (CK_CHAR *)"Key";
+ else if (object->msc_obj)
+ obj_type = (CK_CHAR *)"Object";
+ else
+ obj_type = (CK_CHAR *)"Non-token object";
+
+ log_Log(LOG_LOW, "Get attribute object handle: %X type: %s", hObject, obj_type);
+ for (i = 0; i < ulCount; i++)
+ {
+ log_Log(LOG_LOW, "Trying to get attribute: 0x%X", pTemplate[i].type);
+
+ if (!CKR_ERROR(rv = object_GetAttrib(pTemplate[i].type, object, &attrib)))
+ {
+ if (pTemplate[i].pValue == 0)
+ {
+ log_Log(LOG_LOW, "pValue is NULL returning length: %lu", attrib->attrib.ulValueLen);
+ pTemplate[i].ulValueLen = attrib->attrib.ulValueLen;
+ }
+ else if (pTemplate[i].ulValueLen < attrib->attrib.ulValueLen)
+ {
+ log_Log(LOG_LOW, "Output buffer too small: %lu < %lu",
+ pTemplate[i].ulValueLen, attrib->attrib.ulValueLen);
+ rv = CKR_BUFFER_TOO_SMALL;
+ pTemplate[i].ulValueLen = (CK_ULONG)-1;
+ }
+ else
+ {
+ log_Log(LOG_LOW, "Returning attribute");
+ object_LogAttribute(&attrib->attrib);
+
+ memcpy(pTemplate[i].pValue, attrib->attrib.pValue, attrib->attrib.ulValueLen);
+ pTemplate[i].ulValueLen = attrib->attrib.ulValueLen;
+
+ /* FIXME: hack for Mozilla 1.1b endian issue */
+ if (pTemplate[i].type == CKA_CLASS)
+ {
+ if (util_IsLittleEndian())
+ {
+ if ((((CK_BYTE *)pTemplate[i].pValue)[0] == 0x00) ||
+ (((CK_BYTE *)pTemplate[i].pValue)[0] == 0x80))
+ {
+ log_Log(LOG_LOW, "Reversing CKA_CLASS for little endian");
+ util_byterev(pTemplate[i].pValue, pTemplate[i].ulValueLen);
+ }
+ }
+ else
+ {
+ if ((((CK_BYTE *)pTemplate[i].pValue)[0] != 0x00) &&
+ (((CK_BYTE *)pTemplate[i].pValue)[0] != 0x80))
+ {
+ log_Log(LOG_LOW, "Reversing CKA_CLASS for big endian");
+ util_byterev(pTemplate[i].pValue, pTemplate[i].ulValueLen);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ pTemplate[i].ulValueLen = (CK_ULONG)-1;
+ perm_rv = rv;
+ rv = CKR_OK;
+ }
+ }
+
+ if ((rv == CKR_OK) && (perm_rv != CKR_OK))
+ rv = perm_rv;
+ }
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetAttributeValue");
+
+ return rv;
+}
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes */
+CK_DEFINE_FUNCTION(CK_RV, C_SetAttributeValue)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
+ CK_ULONG ulCount /* attributes in template */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *object = (P11_Object *)hObject;
+ ULONG i;
+
+ P11_LOG_START("C_SetAttributeValue");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pTemplate)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (INVALID_OBJECT)
+ rv = CKR_OBJECT_HANDLE_INVALID;
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else
+ {
+ for (i = 0; i < ulCount; i++)
+ {
+ log_Log(LOG_LOW, "SetAttributeValue:");
+ object_LogAttribute(&pTemplate[i]);
+
+ if (CKR_ERROR(rv = object_AddAttribute(object,
+ pTemplate[i].type,
+ TRUE, /* Fixme: Always a token attribute? */
+ (CK_BYTE *)pTemplate[i].pValue,
+ pTemplate[i].ulValueLen, 0)))
+ break;
+ }
+
+ (void)CKR_ERROR(rv = object_WriteAttributes(hSession, object));
+
+ (void)CKR_ERROR(rv = slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SetAttributeValue");
+
+ return rv;
+}
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template. */
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attrs in search template */
+)
+{
+ CK_RV rv = CKR_OK;
+ CK_RV msc_rv;
+ P11_Slot *slot;
+ P11_Session *session = (P11_Session *)hSession;
+ MSCKeyInfo keyInfo;
+ MSCObjectInfo objectInfo;
+
+ P11_LOG_START("C_FindObjectsInit");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (ulCount && !pTemplate)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else
+ {
+ slot = &st.slots[session->session.slotID - 1];
+ session->search_attrib_count = 0;
+
+ if (ulCount)
+ {
+ /* Fixme: Big problem? May need to malloc the pValue for the local search attributes. */
+ /* Otherwise it uses the memory pointer back into the calling application. */
+ session->search_attrib = (CK_ATTRIBUTE *)calloc(ulCount, sizeof(CK_ATTRIBUTE));
+ if (!session->search_attrib)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ memcpy(session->search_attrib, pTemplate, ulCount * sizeof(CK_ATTRIBUTE));
+ session->search_attrib_count = ulCount;
+ }
+ }
+
+ if (st.prefs.multi_app || !slot->objects)
+ {
+ if (!CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ {
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_RESET, &keyInfo);
+ while (!MSC_ERROR(msc_rv) && !CKR_ERROR(rv))
+ {
+ rv = object_UpdateKeyInfo(hSession, 0, &keyInfo);
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_NEXT, &keyInfo);
+ }
+
+ msc_rv = msc_ListObjects(&slot->conn, MSC_SEQUENCE_RESET, &objectInfo);
+ while (!MSC_ERROR(msc_rv) && !CKR_ERROR(rv))
+ {
+ if (!islower(objectInfo.objectID[0]))
+ rv = object_UpdateObjectInfo(hSession, 0, &objectInfo);
+
+ msc_rv = msc_ListObjects(&slot->conn, MSC_SEQUENCE_NEXT, &objectInfo);
+ }
+
+ /* Fixme: Need to delete objects that are no longer on the token */
+
+ if (!CKR_ERROR(rv))
+ (void)CKR_ERROR(rv = slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ else
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+ }
+
+ session->search_object = st.slots[session->session.slotID - 1].objects;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_FindObjectsInit");
+ return rv;
+}
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles. */
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjects)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
+ CK_ULONG ulMaxObjectCount, /* max handles to get */
+ CK_ULONG_PTR pulObjectCount /* actual # returned */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ CK_ULONG j, objnum;
+ CK_BYTE match;
+
+ P11_LOG_START("C_FindObjects");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!phObject || !ulMaxObjectCount || !pulObjectCount)
+ rv= CKR_ARGUMENTS_BAD;
+ else
+ {
+ objnum = 0;
+
+ log_Log(LOG_LOW, "Find max object count: %lu", ulMaxObjectCount);
+ while ((objnum < ulMaxObjectCount) && session->search_object)
+ {
+ if (!session->search_object->sensitive || (slot->pin_state > 0))
+ {
+ match = 1;
+
+ for (j = 0; j < session->search_attrib_count; j++)
+ {
+ if (!object_MatchAttrib(&session->search_attrib[j], session->search_object))
+ {
+ match = 0;
+ break;
+ }
+ }
+
+ if (match)
+ {
+ log_Log(LOG_LOW, "Object matched: %lX", session->search_object);
+ phObject[objnum] = (CK_OBJECT_HANDLE)session->search_object;
+ objnum++;
+ }
+ }
+
+ session->search_object = session->search_object->next;
+ }
+
+ log_Log(LOG_LOW, "Matched %lu objects", objnum);
+ *pulObjectCount = objnum;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_FindObjects");
+
+ return rv;
+}
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects. */
+CK_DEFINE_FUNCTION(CK_RV, C_FindObjectsFinal)
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_FindObjectsFinal");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else
+ {
+ session->search_object = 0x00;
+
+ if (session->search_attrib)
+ {
+ free(session->search_attrib);
+ session->search_attrib = 0x00;
+ }
+
+ session->search_attrib_count = 0x00;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_FindObjectsFinal");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_parallel.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_parallel.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_parallel.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,66 @@
+/******************************************************************************
+**
+** $Id: p11_parallel.c,v 1.2 2003/02/13 20:06:39 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Parallel function management (deprecated)
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetFunctionStatus)
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GetFunctionStatus");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_PARALLEL;
+ log_Log(LOG_MED, "Legacy function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetFunctionStatus");
+
+ return rv;
+}
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel. */
+CK_DEFINE_FUNCTION(CK_RV, C_CancelFunction)
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_CancelFunction");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_PARALLEL;
+ log_Log(LOG_MED, "Legacy function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_CancelFunction");
+
+ return rv;
+}
+
+
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_random.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_random.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_random.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,64 @@
+/******************************************************************************
+**
+** $Id: p11_random.c,v 1.2 2003/02/13 20:06:39 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Random number generation
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator. */
+CK_DEFINE_FUNCTION(CK_RV, C_SeedRandom)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* length of seed material */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SeedRandom");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SeedRandom");
+
+ return rv;
+}
+
+
+/* C_GenerateRandom generates random data. */
+CK_DEFINE_FUNCTION(CK_RV, C_GenerateRandom)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* # of bytes to generate */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GenerateRandom");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GenerateRandom");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_session.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_session.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_session.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,325 @@
+/******************************************************************************
+**
+** $Id: p11_session.c,v 1.2 2003/02/13 20:06:39 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Session management
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_OpenSession opens a session between an application and a
+ * token. */
+CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* from CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* passed to callback */
+ CK_NOTIFY Notify, /* callback function */
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session;
+ CK_ULONG pin_state;
+
+ P11_LOG_START("C_OpenSession");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (!phSession)
+ rv = CKR_ARGUMENTS_BAD;
+ else
+ {
+ if (!(flags & CKF_RW_SESSION) && slot_CheckRWSOsession(slotID))
+ rv = CKR_SESSION_READ_WRITE_SO_EXISTS;
+ else if (CKR_ERROR(rv = slot_EstablishConnection(slotID)))
+ /* Return error */;
+ else if (CKR_ERROR(rv = session_AddSession(phSession)))
+ /* Return error */;
+ else
+ {
+ log_Log(LOG_LOW, "New session handle: %X", *phSession);
+ session = (P11_Session *)*phSession;
+ session->session.slotID = slotID;
+
+ pin_state = st.slots[slotID - 1].pin_state;
+
+ if (flags & CKF_RW_SESSION)
+ {
+ if (pin_state == 1)
+ session->session.state = CKS_RW_USER_FUNCTIONS;
+ else if (pin_state == 2)
+ session->session.state = CKS_RW_SO_FUNCTIONS;
+ else
+ session->session.state = CKS_RW_PUBLIC_SESSION;
+ }
+ else
+ {
+ if (pin_state == 1)
+ session->session.state = CKS_RO_USER_FUNCTIONS;
+ else if (pin_state == 2)
+ session->session.state = CKS_RO_USER_FUNCTIONS;
+ else
+ session->session.state = CKS_RO_PUBLIC_SESSION;
+ }
+
+ session->session.flags = flags;
+ session->session.ulDeviceError = 0x1F; /* Fixme: what is this used for? */
+ session->application = pApplication;
+ session->notify = Notify;
+ }
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_OpenSession");
+
+ return rv;
+}
+
+
+/* C_CloseSession closes a session between an application and a
+ * token. */
+CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ CK_SLOT_ID slotID = session->session.slotID;
+
+ P11_LOG_START("C_CloseSession");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!CKR_ERROR(rv = session_FreeSession(hSession)))
+ rv = slot_ReleaseConnection(slotID);
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_CloseSession");
+
+ return rv;
+}
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)
+(
+ CK_SLOT_ID slotID /* the token's slot */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session_l;
+ P11_Session *session_l_temp;
+
+ P11_LOG_START("C_CloseAllSessions");
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else
+ {
+ session_l = st.sessions;
+
+ while (session_l)
+ {
+ session_l_temp = session_l->next;
+
+ if (session_l->session.slotID == slotID)
+ C_CloseSession((CK_SESSION_HANDLE)session_l); /* Fixme: ignore errors? */
+
+ session_l = session_l_temp;
+ }
+ }
+
+ P11_LOG_END("C_CloseAllSessions");
+
+ return rv;
+}
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session info */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_GetSessionInfo");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (!pInfo)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else
+ {
+ log_Log(LOG_LOW, "Session state: %lu", session->session.state);
+ memcpy(pInfo, &session->session, sizeof(CK_SESSION_INFO));
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetSessionInfo");
+
+ return rv;
+}
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetOperationState)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* gets state */
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GetOperationState");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetOperationState");
+
+ return rv;
+}
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session. */
+CK_DEFINE_FUNCTION(CK_RV, C_SetOperationState)
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* holds state */
+ CK_ULONG ulOperationStateLen, /* holds state length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SetOperationState");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SetOperationState");
+
+ return rv;
+}
+
+
+/* C_Login logs a user into a token. */
+CK_DEFINE_FUNCTION(CK_RV, C_Login)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_Login");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (!pPin || !ulPinLen)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ {
+ if (userType == CKU_SO)
+ log_Log(LOG_LOW, "Verifying SO PIN");
+ else if (userType == CKU_USER)
+ log_Log(LOG_LOW, "Verifying USER PIN");
+ else
+ log_Log(LOG_LOW, "Verifying Unknown user PIN: %lu", userType);
+
+ rv = slot_VerifyPIN(session->session.slotID, userType, pPin, ulPinLen);
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+
+ if (rv == CKR_OK)
+ slot_UserMode(session->session.slotID);
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Login");
+
+ return rv;
+}
+
+
+/* C_Logout logs a user out from a token. */
+CK_DEFINE_FUNCTION(CK_RV, C_Logout)
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_Logout");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ {
+ if (rv == CKR_OK)
+ slot_PublicMode(session->session.slotID);
+
+ memset(st.slots[session->session.slotID - 1].pins, 0x00, sizeof(st.slots[session->session.slotID - 1].pins));
+
+ if (MSC_ERROR(msc_LogoutAll(&st.slots[session->session.slotID - 1].conn)))
+ (void)CKR_ERROR(rv = slot_EndTransaction(session->session.slotID, MSC_RESET_TOKEN));
+ else
+ (void)CKR_ERROR(rv = slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Logout");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_sign.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_sign.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_sign.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,296 @@
+/******************************************************************************
+**
+** $Id: p11_sign.c,v 1.2 2003/02/13 20:06:39 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Signing and MACing
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+#include <openssl/rsa.h>
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ *signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_SignInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of signature key */
+)
+{
+ CK_RV rv = CKR_OK;
+ CK_OBJECT_HANDLE hObject = hKey; /* Needed for INVALID_OBJECT check */
+ P11_Session *session = (P11_Session *)hSession;
+
+ P11_LOG_START("C_SignInit");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pMechanism)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (INVALID_OBJECT)
+ rv = CKR_OBJECT_HANDLE_INVALID;
+ else if (!USER_MODE)
+ rv = CKR_USER_NOT_LOGGED_IN;
+ else
+ {
+ session->sign_mech = *pMechanism;
+ session->sign_key = hObject;
+
+ log_Log(LOG_LOW, "Sign object handle: 0x%lX", hObject);
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SignInit");
+
+ return rv;
+}
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_Sign)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+)
+{
+ CK_RV rv = CKR_OK;
+ MSCCryptInit cryptInit;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *key = (P11_Object *)session->sign_key;
+ CK_BYTE *to = 0;
+ CK_ULONG tlen;
+
+ P11_LOG_START("C_Sign");
+
+ thread_MutexLock(st.async_lock);
+
+ log_Log(LOG_LOW, "Output buffer len: %lu", *pulSignatureLen);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!pData || !pSignature)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (!key)
+ rv = CKR_OPERATION_NOT_INITIALIZED;
+ else if (!USER_MODE)
+ rv = CKR_USER_NOT_LOGGED_IN;
+ else if ((CK_ULONG)(key->msc_key->keySize / 8) > *pulSignatureLen)
+ {
+ *pulSignatureLen = key->msc_key->keySize / 8;
+ rv = CKR_BUFFER_TOO_SMALL;
+ }
+ else if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Intentionally blank */;
+ else if (session->sign_mech.mechanism == CKM_RSA_PKCS)
+ {
+ MSCULong32 ulValue, lenValue;
+
+ if (MSC_ERROR(msc_GetCapabilities(&st.slots[session->session.slotID - 1].conn,
+ MSC_TAG_CAPABLE_RSA,
+ (CK_BYTE_PTR) &ulValue,
+ &lenValue)))
+ rv = CKR_FUNCTION_FAILED;
+ else if (ulValue & MSC_CAPABLE_RSA_NOPAD)
+ {
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherMode = MSC_MODE_RSA_NOPAD;
+ cryptInit.cipherDirection = MSC_DIR_SIGN;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ tlen = key->msc_key->keySize / 8;
+ to = (CK_BYTE *)malloc(tlen);
+
+ log_Log(LOG_LOW, "Pad and Sign object keyNum: %lu tlen: %lu",
+ key->msc_key->keyNum, tlen);
+
+ if (!to)
+ rv = CKR_HOST_MEMORY;
+ else if (!RSA_padding_add_PKCS1_type_1(to, tlen, pData, ulDataLen))
+ rv = CKR_FUNCTION_FAILED;
+
+ else
+ {
+ MSCULong32 outputDataSize = *pulSignatureLen;
+ if (MSC_ERROR(msc_ComputeCrypt(
+ &st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ to,
+ tlen,
+ pSignature,
+ &outputDataSize)))
+ rv = CKR_FUNCTION_FAILED;
+ *pulSignatureLen = outputDataSize;
+ }
+ }
+ else if (ulValue & MSC_CAPABLE_RSA_PKCS1)
+ {
+ cryptInit.keyNum = key->msc_key->keyNum;
+ cryptInit.cipherMode = MSC_MODE_RSA_PAD_PKCS1;
+ cryptInit.cipherDirection = MSC_DIR_SIGN;
+ cryptInit.optParams = 0;
+ cryptInit.optParamsSize = 0;
+
+ log_Log(LOG_LOW, "Sign object keyNum: %lu DataLen: %lu",
+ key->msc_key->keyNum, ulDataLen);
+
+ MSCULong32 outputDataSize = *pulSignatureLen;
+ if (MSC_ERROR(msc_ComputeCrypt(
+ &st.slots[session->session.slotID - 1].conn,
+ &cryptInit,
+ pData,
+ ulDataLen,
+ pSignature,
+ &outputDataSize)))
+ rv = CKR_FUNCTION_FAILED;
+ *pulSignatureLen = outputDataSize;
+ }
+ else
+ rv = CKR_MECHANISM_PARAM_INVALID;
+
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ }
+ else
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ rv = CKR_MECHANISM_INVALID;
+ }
+
+ session->sign_key = 0;
+
+ if (to)
+ free(to);
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Sign");
+
+ return rv;
+}
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_SignUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data to sign */
+ CK_ULONG ulPartLen /* count of bytes to sign */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SignUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SignUpdate");
+
+ return rv;
+}
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_SignFinal)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SignFinal");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SignFinal");
+
+ return rv;
+}
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_SignRecoverInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SignRecoverInit");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SignRecoverInit");
+
+ return rv;
+}
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_SignRecover)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_SignRecover");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SignRecover");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_token.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_token.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_token.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,385 @@
+/******************************************************************************
+**
+** $Id: p11_token.c,v 1.2 2003/02/13 20:06:39 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Slot and token management
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)
+(
+ CK_BBOOL tokenPresent, /* only slots with tokens? */
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives number of slots */
+)
+{
+ CK_RV rv = CKR_OK;
+ CK_RV token_rv;
+ CK_ULONG i, count = 0;
+
+ P11_LOG_START("C_GetSlotList");
+
+ thread_MutexLock(st.async_lock);
+
+ (void)CKR_ERROR(slot_TokenChanged());
+
+ if (!pulCount)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (!st.slots)
+ {
+ *pulCount = 0;
+ log_Log(LOG_LOW, "No active slots");
+ }
+ else if (!pSlotList && !tokenPresent)
+ {
+ *pulCount = st.slot_count;
+ log_Log(LOG_LOW, "Returning slot count: %ld", *pulCount);
+ }
+ else if ((*pulCount < st.slot_count) && !tokenPresent)
+ rv = CKR_BUFFER_TOO_SMALL;
+ else if (!tokenPresent)
+ {
+ *pulCount = st.slot_count;
+
+ for (i = 0; i < *pulCount; i++)
+ {
+ pSlotList[i] = i + 1;
+ log_Log(LOG_MED, "Found reader at slot: %ld", pSlotList[i]);
+ }
+ }
+ else /* Look for readers with tokens present */
+ {
+ for (i = 1, count = 0; i <= st.slot_count; i++)
+ {
+ token_rv = slot_TokenPresent(i);
+ if ((token_rv == CKR_OK) || (token_rv == CKR_TOKEN_NOT_RECOGNIZED))
+ {
+ if (pSlotList)
+ pSlotList[count] = i;
+
+ log_Log(LOG_MED, "Found reader with token at slot: %ld", i);
+ count++;
+ }
+ }
+
+ *pulCount = count;
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetSlotList");
+ return rv;
+}
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetSlotInfo)
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GetSlotInfo");
+
+ thread_MutexLock(st.async_lock);
+ log_Log(LOG_LOW, "Checking slot: %ld", slotID);
+
+ (void)CKR_ERROR(slot_TokenChanged());
+
+ if (!pInfo)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ memcpy(pInfo, &st.slots[slotID - 1].slot_info, sizeof(CK_SLOT_INFO));
+ log_Log(LOG_LOW, "SlotInfo.flags: %lX", pInfo->flags);
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetSlotInfo");
+
+ return rv;
+}
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_GetTokenInfo");
+
+ thread_MutexLock(st.async_lock);
+ log_Log(LOG_LOW, "Checking slot: %ld", slotID);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (!pInfo)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ memcpy(pInfo, &st.slots[slotID - 1].token_info, sizeof(CK_TOKEN_INFO));
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetTokenInfo");
+
+ return rv;
+}
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)
+(
+ CK_SLOT_ID slotID, /* ID of token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
+ CK_ULONG_PTR pulCount /* gets # of mechs. */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Slot *slot = &st.slots[slotID - 1];
+ P11_MechInfo *mech;
+ CK_ULONG i;
+
+ P11_LOG_START("C_GetMechanismList");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (!pMechanismList)
+ {
+ log_Log(LOG_LOW, "Returning count only");
+ *pulCount = slot_MechanismCount(slot->mechanisms);
+ }
+ else if (*pulCount < slot_MechanismCount(slot->mechanisms))
+ rv = CKR_BUFFER_TOO_SMALL;
+ else
+ {
+ mech = slot->mechanisms;
+
+ for (i = 0; mech; i++)
+ {
+ pMechanismList[i] = mech->type;
+ mech = mech->next;
+ }
+
+ *pulCount = i;
+ }
+
+ log_Log(LOG_LOW, "Returning %lu mechanisms", *pulCount);
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetMechanismList");
+
+ return rv;
+}
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token. */
+CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismInfo)
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_MechInfo *mech;
+
+ P11_LOG_START("C_GetMechanismInfo");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (!pInfo)
+ rv = CKR_ARGUMENTS_BAD;
+ else
+ {
+ mech = st.slots[slotID - 1].mechanisms;
+
+ rv = CKR_MECHANISM_INVALID;
+
+ while (mech)
+ {
+ if (mech->type == type)
+ {
+ memcpy(pInfo, &mech->info, sizeof(CK_MECHANISM_INFO));
+ rv = CKR_OK;
+ break;
+ }
+
+ mech = mech->next;
+ }
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_GetMechanismInfo");
+
+ return rv;
+}
+
+
+/* C_InitToken initializes a token. */
+CK_DEFINE_FUNCTION(CK_RV, C_InitToken)
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_InitToken");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+ /* msc_WriteFramework() */
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_InitToken");
+
+ return rv;
+}
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_DEFINE_FUNCTION(CK_RV, C_InitPIN)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Slot *slot;
+ P11_Session *session;
+
+ P11_LOG_START("C_InitPIN");
+
+ thread_MutexLock(st.async_lock);
+
+// if (CKR_ERROR(rv = slot_TokenChanged()))
+// rv = CKR_DEVICE_REMOVED;
+// else
+ if (!pPin)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (READ_ONLY_SESSION)
+ rv = CKR_SESSION_READ_ONLY;
+ else
+ {
+ session = (P11_Session *)hSession;
+ slot = &st.slots[session->session.slotID - 1];
+
+ if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ /* Return error */;
+ else if (MSC_ERROR(msc_CreatePIN(&slot->conn,
+ (MSCUChar8)st.prefs.user_pin_num,
+ (MSCUChar8)st.prefs.max_pin_tries,
+ pPin,
+ ulPinLen,
+ (MSCUChar8 *)"PIN_UNBK", 8)))
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else
+ rv = slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN);
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_InitPIN");
+
+ return rv;
+}
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_DEFINE_FUNCTION(CK_RV, C_SetPIN)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+)
+{
+ CK_RV rv = CKR_OK;
+ P11_Slot *slot;
+ P11_Session *session;
+
+ P11_LOG_START("C_SetPIN");
+
+ thread_MutexLock(st.async_lock);
+
+ if (CKR_ERROR(rv = slot_TokenChanged()))
+ rv = CKR_DEVICE_REMOVED;
+ else if (!pOldPin || !pNewPin)
+ rv = CKR_ARGUMENTS_BAD;
+ else if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else if (READ_ONLY_SESSION)
+ rv = CKR_SESSION_READ_ONLY;
+ else
+ {
+ session = (P11_Session *)hSession;
+ slot = &st.slots[session->session.slotID - 1];
+
+ if (CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
+ rv = rv;
+ else if (MSC_ERROR(msc_ChangePIN(&slot->conn,
+ (MSCUChar8)st.prefs.user_pin_num,
+ pOldPin,
+ (CK_BYTE)ulOldLen,
+ pNewPin,
+ (CK_BYTE)ulNewLen)))
+ {
+ (void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else
+ rv = slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN);
+ }
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_SetPIN");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_verify.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_verify.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11_verify.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,176 @@
+/******************************************************************************
+**
+** $Id: p11_verify.c,v 1.2 2003/02/13 20:06:39 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Verifying signatures and MACs
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ * cannot be recovered from the signature (e.g. DSA). */
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_VerifyInit");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_VerifyInit");
+
+ return rv;
+}
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_Verify)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* signed data */
+ CK_ULONG ulDataLen, /* length of signed data */
+ CK_BYTE_PTR pSignature, /* signature */
+ CK_ULONG ulSignatureLen /* signature length*/
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_Verify");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_Verify");
+
+ return rv;
+}
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyUpdate)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* signed data */
+ CK_ULONG ulPartLen /* length of signed data */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_VerifyUpdate");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_VerifyUpdate");
+
+ return rv;
+}
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyFinal)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen /* signature length */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_VerifyFinal");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_VerifyFinal");
+
+ return rv;
+}
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecoverInit)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_VerifyRecoverInit");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_VerifyRecoverInit");
+
+ return rv;
+}
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature. */
+CK_DEFINE_FUNCTION(CK_RV, C_VerifyRecover)
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen, /* signature length */
+ CK_BYTE_PTR pData, /* gets signed data */
+ CK_ULONG_PTR pulDataLen /* gets signed data len */
+)
+{
+ CK_RV rv = CKR_OK;
+
+ P11_LOG_START("C_VerifyRecover");
+
+ thread_MutexLock(st.async_lock);
+
+ rv = CKR_FUNCTION_NOT_SUPPORTED;
+ log_Log(LOG_MED, "Function not supported");
+
+ thread_MutexUnlock(st.async_lock);
+
+ P11_LOG_END("C_VerifyRecover");
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_async.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_async.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_async.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,143 @@
+/******************************************************************************
+**
+** $Id: p11x_async.c,v 1.2 2003/02/13 20:06:40 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Asynchronous functions (UNIX version)
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+#include <time.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#endif
+
+/******************************************************************************
+** Function: async_StartSlotWatcher
+**
+** Starts a thread that watches all the slots in the system.
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV async_StartSlotWatcher()
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i;
+ MSCTokenInfo *tokenArray;
+
+ tokenArray = (MSCTokenInfo *)malloc(st.slot_count * sizeof(MSCTokenInfo));
+
+ if (!tokenArray)
+ return CKR_HOST_MEMORY;
+
+ for (i = 0; i < st.slot_count; i++)
+ {
+ memcpy(&tokenArray[i], &st.slots[i].conn.tokenInfo, sizeof(MSCTokenInfo));
+ tokenArray[i].tokenState = 0;
+ }
+
+ st.slot_status = (char *)malloc(st.slot_count);
+
+ if (!st.slot_status)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ memset(st.slot_status, 0x01, st.slot_count);
+
+ if (st.prefs.threaded && st.create_threads)
+ {
+ if (MSC_ERROR(msc_CallbackForTokenEvent(tokenArray,
+ st.slot_count,
+ async_TokenEventCallback,
+ 0)))
+ {
+ free(st.slot_status);
+ st.slot_status = 0;
+ rv = CKR_FUNCTION_FAILED;
+ }
+ }
+ }
+
+ if (tokenArray)
+ free(tokenArray);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: async_StopSlotWatcher
+**
+** Stops the slot watching thread.
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV async_StopSlotWatcher()
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.threaded && st.create_threads)
+ msc_CallbackCancelEvent();
+
+ if (st.slot_status)
+ {
+ free(st.slot_status);
+ st.slot_status = 0;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: async_TokenEventCallback
+**
+** Called for asynchronous token events. Depending on the thread mode this
+** will either set a flag that will be picked up later by any call into the
+** P11 module, or if in fully threaded mode this will update all information
+** about the token in the callback thread.
+**
+** Parameters:
+** tokenArray - Token status information
+** arrayLen - Number of items in tokenArray
+** data - Pointer to "data" that was set with MSCCallbackForTokenEvent
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+MSCULong32 async_TokenEventCallback(MSCTokenInfo *tokenArray, MSCULong32 arrayLen, void *data)
+{
+ CK_ULONG i;
+
+ for (i = 0; i < arrayLen; i++)
+ {
+ if (tokenArray[i].tokenState & MSC_STATE_CHANGED)
+ {
+ log_Log(LOG_LOW, "Async event on slot %ld: 0x%lX", i + 1, tokenArray[i].tokenState);
+ st.slot_status[i] = 0x01;
+ }
+ }
+
+ if (st.prefs.slot_watch_scheme == P11_SLOT_WATCH_THREAD_FULL)
+ {
+ thread_MutexLock(st.async_lock);
+ slot_TokenChanged();
+ thread_MutexUnlock(st.async_lock);
+ }
+
+ return MSC_SUCCESS;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_bio.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_bio.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_bio.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,11 @@
+/******************************************************************************
+**
+** $Id: p11x_bio.c,v 1.2 2003/02/13 20:06:40 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Chris Osgood
+** Purpose: Biometric support functions to be used instead of a normal PIN.
+**
+******************************************************************************/
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_error.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_error.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_error.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,403 @@
+/******************************************************************************
+**
+** $Id: p11x_error.c,v 1.2 2003/02/13 20:06:40 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Error handling
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/******************************************************************************
+** Function: error_LogCmd
+**
+** If there is an error then this logs it to the logfile as a stringified
+** text message.
+**
+** Parameters:
+** err - CKR Error code
+** cond - Test condition that says whether or not this is an error
+** file - Filename where the error occured (__FILE__)
+** line - Line number of the error (__LINE__)
+** stringifyFn - Function used to stringify the error code (err)
+**
+** Returns:
+** The error code that was passed in
+*******************************************************************************/
+CK_RV error_LogCmd(CK_RV err, CK_RV cond, CK_CHAR *file, CK_LONG line, char *(*stringifyFn)(CK_RV))
+{
+ if (err != cond)
+ log_Log(LOG_MED, "(%s %ld): error: 0x%lX \"%s\"", file, line, err, stringifyFn(err));
+
+ return err;
+}
+
+/******************************************************************************
+** Function: error_Stringify
+**
+** Convert a CKR_XXX error code to text.
+**
+** Parameters:
+** rv - Error code to convert
+**
+** Returns:
+** A static string error message (make this const?)
+*******************************************************************************/
+char *error_Stringify(CK_RV rv)
+{
+ char *error;
+
+ switch(rv)
+ {
+ case CKR_OK:
+ error = "CKR_OK";
+ break;
+
+ case CKR_CANCEL:
+ error = "CKR_CANCEL";
+ break;
+
+ case CKR_HOST_MEMORY:
+ error = "CKR_HOST_MEMORY";
+ break;
+
+ case CKR_SLOT_ID_INVALID:
+ error = "CKR_SLOT_ID_INVALID";
+ break;
+
+ case CKR_GENERAL_ERROR:
+ error = "CKR_GENERAL_ERROR";
+ break;
+
+ case CKR_FUNCTION_FAILED:
+ error = "CKR_FUNCTION_FAILED";
+ break;
+
+ case CKR_ARGUMENTS_BAD:
+ error = "CKR_ARGUMENTS_BAD";
+ break;
+
+ case CKR_NO_EVENT:
+ error = "CKR_NO_EVENT";
+ break;
+
+ case CKR_NEED_TO_CREATE_THREADS:
+ error = "CKR_NEED_TO_CREATE_THREADS";
+ break;
+
+ case CKR_CANT_LOCK:
+ error = "CKR_CANT_LOCK";
+ break;
+
+ case CKR_ATTRIBUTE_READ_ONLY:
+ error = "CKR_ATTRIBUTE_READ_ONLY";
+ break;
+
+ case CKR_ATTRIBUTE_SENSITIVE:
+ error = "CKR_ATTRIBUTE_SENSITIVE";
+ break;
+
+ case CKR_ATTRIBUTE_TYPE_INVALID:
+ error = "CKR_ATTRIBUTE_TYPE_INVALID";
+ break;
+
+ case CKR_ATTRIBUTE_VALUE_INVALID:
+ error = "CKR_ATTRIBUTE_VALUE_INVALID";
+ break;
+
+ case CKR_DATA_INVALID:
+ error = "CKR_DATA_INVALID";
+ break;
+
+ case CKR_DATA_LEN_RANGE:
+ error = "CKR_DATA_LEN_RANGE";
+ break;
+
+ case CKR_DEVICE_ERROR:
+ error = "CKR_DEVICE_ERROR";
+ break;
+
+ case CKR_DEVICE_MEMORY:
+ error = "CKR_DEVICE_MEMORY";
+ break;
+
+ case CKR_DEVICE_REMOVED:
+ error = "CKR_DEVICE_REMOVED";
+ break;
+
+ case CKR_ENCRYPTED_DATA_INVALID:
+ error = "CKR_ENCRYPTED_DATA_INVALID";
+ break;
+
+ case CKR_ENCRYPTED_DATA_LEN_RANGE:
+ error = "CKR_ENCRYPTED_DATA_LEN_RANGE";
+ break;
+
+ case CKR_FUNCTION_CANCELED:
+ error = "CKR_FUNCTION_CANCELED";
+ break;
+
+ case CKR_FUNCTION_NOT_PARALLEL:
+ error = "CKR_FUNCTION_NOT_PARALLEL";
+ break;
+
+ case CKR_FUNCTION_NOT_SUPPORTED:
+ error = "CKR_FUNCTION_NOT_SUPPORTED";
+ break;
+
+ case CKR_KEY_HANDLE_INVALID:
+ error = "CKR_KEY_HANDLE_INVALID";
+ break;
+
+ case CKR_KEY_SIZE_RANGE:
+ error = "CKR_KEY_SIZE_RANGE";
+ break;
+
+ case CKR_KEY_TYPE_INCONSISTENT:
+ error = "CKR_KEY_TYPE_INCONSISTENT";
+ break;
+
+ case CKR_KEY_NOT_NEEDED:
+ error = "CKR_KEY_NOT_NEEDED";
+ break;
+
+ case CKR_KEY_CHANGED:
+ error = "CKR_KEY_CHANGED";
+ break;
+
+ case CKR_KEY_NEEDED:
+ error = "CKR_KEY_NEEDED";
+ break;
+
+ case CKR_KEY_INDIGESTIBLE:
+ error = "CKR_KEY_INDIGESTIBLE";
+ break;
+
+ case CKR_KEY_FUNCTION_NOT_PERMITTED:
+ error = "CKR_KEY_FUNCTION_NOT_PERMITTED";
+ break;
+
+ case CKR_KEY_NOT_WRAPPABLE:
+ error = "CKR_KEY_NOT_WRAPPABLE";
+ break;
+
+ case CKR_KEY_UNEXTRACTABLE:
+ error = "CKR_KEY_UNEXTRACTABLE";
+ break;
+
+ case CKR_MECHANISM_INVALID:
+ error = "CKR_MECHANISM_INVALID";
+ break;
+
+ case CKR_MECHANISM_PARAM_INVALID:
+ error = "CKR_MECHANISM_PARAM_INVALID";
+ break;
+
+ case CKR_OBJECT_HANDLE_INVALID:
+ error = "CKR_OBJECT_HANDLE_INVALID";
+ break;
+
+ case CKR_OPERATION_ACTIVE:
+ error = "CKR_OPERATION_ACTIVE";
+ break;
+
+ case CKR_OPERATION_NOT_INITIALIZED:
+ error = "CKR_OPERATION_NOT_INITIALIZED";
+ break;
+
+ case CKR_PIN_INCORRECT:
+ error = "CKR_PIN_INCORRECT";
+ break;
+
+ case CKR_PIN_INVALID:
+ error = "CKR_PIN_INVALID";
+ break;
+
+ case CKR_PIN_LEN_RANGE:
+ error = "CKR_PIN_LEN_RANGE";
+ break;
+
+ case CKR_PIN_EXPIRED:
+ error = "CKR_PIN_EXPIRED";
+ break;
+
+ case CKR_PIN_LOCKED:
+ error = "CKR_PIN_LOCKED";
+ break;
+
+ case CKR_SESSION_CLOSED:
+ error = "CKR_SESSION_CLOSED";
+ break;
+
+ case CKR_SESSION_COUNT:
+ error = "CKR_SESSION_COUNT";
+ break;
+
+ case CKR_SESSION_HANDLE_INVALID:
+ error = "CKR_SESSION_HANDLE_INVALID";
+ break;
+
+ case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
+ error = "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
+ break;
+
+ case CKR_SESSION_READ_ONLY:
+ error = "CKR_SESSION_READ_ONLY";
+ break;
+
+ case CKR_SESSION_EXISTS:
+ error = "CKR_SESSION_EXISTS";
+ break;
+
+ case CKR_SESSION_READ_ONLY_EXISTS:
+ error = "CKR_SESSION_READ_ONLY_EXISTS";
+ break;
+
+ case CKR_SESSION_READ_WRITE_SO_EXISTS:
+ error = "CKR_SESSION_READ_WRITE_SO_EXISTS";
+ break;
+
+ case CKR_SIGNATURE_INVALID:
+ error = "CKR_SIGNATURE_INVALID";
+ break;
+
+ case CKR_SIGNATURE_LEN_RANGE:
+ error = "CKR_SIGNATURE_LEN_RANGE";
+ break;
+
+ case CKR_TEMPLATE_INCOMPLETE:
+ error = "CKR_TEMPLATE_INCOMPLETE";
+ break;
+
+ case CKR_TEMPLATE_INCONSISTENT:
+ error = "CKR_TEMPLATE_INCONSISTENT";
+ break;
+
+ case CKR_TOKEN_NOT_PRESENT:
+ error = "CKR_TOKEN_NOT_PRESENT";
+ break;
+
+ case CKR_TOKEN_NOT_RECOGNIZED:
+ error = "CKR_TOKEN_NOT_RECOGNIZED";
+ break;
+
+ case CKR_TOKEN_WRITE_PROTECTED:
+ error = "CKR_TOKEN_WRITE_PROTECTED";
+ break;
+
+ case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
+ error = "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
+ break;
+
+ case CKR_UNWRAPPING_KEY_SIZE_RANGE:
+ error = "CKR_UNWRAPPING_KEY_SIZE_RANGE";
+ break;
+
+ case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
+ error = "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
+ break;
+
+ case CKR_USER_ALREADY_LOGGED_IN:
+ error = "CKR_USER_ALREADY_LOGGED_IN";
+ break;
+
+ case CKR_USER_NOT_LOGGED_IN:
+ error = "CKR_USER_NOT_LOGGED_IN";
+ break;
+
+ case CKR_USER_PIN_NOT_INITIALIZED:
+ error = "CKR_USER_PIN_NOT_INITIALIZED";
+ break;
+
+ case CKR_USER_TYPE_INVALID:
+ error = "CKR_USER_TYPE_INVALID";
+ break;
+
+ case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
+ error = "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
+ break;
+
+ case CKR_USER_TOO_MANY_TYPES:
+ error = "CKR_USER_TOO_MANY_TYPES";
+ break;
+
+ case CKR_WRAPPED_KEY_INVALID:
+ error = "CKR_WRAPPED_KEY_INVALID";
+ break;
+
+ case CKR_WRAPPED_KEY_LEN_RANGE:
+ error = "CKR_WRAPPED_KEY_LEN_RANGE";
+ break;
+
+ case CKR_WRAPPING_KEY_HANDLE_INVALID:
+ error = "CKR_WRAPPING_KEY_HANDLE_INVALID";
+ break;
+
+ case CKR_WRAPPING_KEY_SIZE_RANGE:
+ error = "CKR_WRAPPING_KEY_SIZE_RANGE";
+ break;
+
+ case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
+ error = "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
+ break;
+
+ case CKR_RANDOM_SEED_NOT_SUPPORTED:
+ error = "CKR_RANDOM_SEED_NOT_SUPPORTED";
+ break;
+
+ case CKR_RANDOM_NO_RNG:
+ error = "CKR_RANDOM_NO_RNG";
+ break;
+
+ case CKR_DOMAIN_PARAMS_INVALID:
+ error = "CKR_DOMAIN_PARAMS_INVALID";
+ break;
+
+ case CKR_BUFFER_TOO_SMALL:
+ error = "CKR_BUFFER_TOO_SMALL";
+ break;
+
+ case CKR_SAVED_STATE_INVALID:
+ error = "CKR_SAVED_STATE_INVALID";
+ break;
+
+ case CKR_INFORMATION_SENSITIVE:
+ error = "CKR_INFORMATION_SENSITIVE";
+ break;
+
+ case CKR_STATE_UNSAVEABLE:
+ error = "CKR_STATE_UNSAVEABLE";
+ break;
+
+ case CKR_CRYPTOKI_NOT_INITIALIZED:
+ error = "CKR_CRYPTOKI_NOT_INITIALIZED";
+ break;
+
+ case CKR_CRYPTOKI_ALREADY_INITIALIZED:
+ error = "CKR_CRYPTOKI_ALREADY_INITIALIZED";
+ break;
+
+ case CKR_MUTEX_BAD:
+ error = "CKR_MUTEX_BAD";
+ break;
+
+ case CKR_MUTEX_NOT_LOCKED:
+ error = "CKR_MUTEX_NOT_LOCKED";
+ break;
+
+ case CKR_VENDOR_DEFINED:
+ error = "CKR_VENDOR_DEFINED";
+ break;
+
+ default:
+ error = "Unknown CKR error";
+ break;
+ }
+
+ return error;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_log.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_log.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_log.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,144 @@
+/******************************************************************************
+**
+** $Id: p11x_log.c,v 1.2 2003/02/13 20:06:40 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Logging functions
+**
+******************************************************************************/
+
+#include <stdio.h>
+#include <assert.h>
+#include <time.h>
+#include <stdarg.h>
+#include "cryptoki.h"
+
+#ifdef SYS_LOG
+#include <syslog.h>
+#endif
+
+/******************************************************************************
+** Function: log_Start
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+void log_Start(char *func)
+{
+ log_Log(LOG_LOW, "+%s : start", func);
+}
+
+/******************************************************************************
+** Function: log_End
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+void log_End(char *func, CK_RV rv)
+{
+ if (CKR_ERROR(rv));
+ log_Log(LOG_LOW, " -%s : end RV(0x%lX)", func, rv);
+}
+
+/******************************************************************************
+** Function: log_Err
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+void log_Err(char *msg, char *file, CK_LONG line)
+{
+ log_Log(LOG_MED, "Error (%s %ld): %s", file, line, msg);
+}
+
+/******************************************************************************
+** Function: log_Log
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+void log_Log(CK_ULONG level, char *msg, ...)
+{
+ va_list args;
+
+#ifdef SYS_LOG
+ thread_MutexLock(st.log_lock);
+
+ if (st.prefs.log_level > level)
+ return;
+
+ va_start(args, msg);
+ vsyslog(0, msg, args);
+ va_end(args);
+#else // SYS_LOG
+ FILE *fp;
+ time_t t;
+ struct tm *time_s;
+ char format[256];
+
+ if (st.prefs.log_level > level)
+ return;
+
+ thread_MutexLock(st.log_lock);
+
+ fp = fopen((char *)st.prefs.log_filename, "ab");
+
+ if (!fp)
+ {
+ fp = stderr;
+ fprintf(fp, "Error, could not open: %s\n", st.prefs.log_filename);
+ }
+
+ time(&t);
+ time_s = localtime(&t);
+
+ sprintf(format, "%.2d/%.2d %.2d:%.2d:%.2d %s",
+ time_s->tm_mday,
+ time_s->tm_mon+1,
+ time_s->tm_hour,
+ time_s->tm_min,
+ time_s->tm_sec,
+ msg);
+
+ va_start(args, msg);
+ vfprintf(fp, format, args);
+ va_end(args);
+
+#ifdef WIN32
+ fputs("\r\n", fp);
+#else
+ fputs("\n", fp);
+#endif // WIN32
+
+ fflush(fp); /* Fixme: more accurate, but slows logging */
+
+ if (fp != stderr)
+ fclose(fp);
+
+#endif // SYS_LOG
+
+ thread_MutexUnlock(st.log_lock);
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,715 @@
+/******************************************************************************
+**
+** $Id: p11x_msc.c,v 1.2 2003/02/13 20:06:40 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: MSC wrappers. This whole module does practically nothing other
+** than proxy calls to the MSC libraries. This is mostly just to
+** provide a layer of protection in case the MSC API changes.
+** msc_ComputeCrypt does handle some cached PIN stuff.
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+MSC_RV msc_ListTokens(
+ MSCULong32 listScope, /* defines the scope to return */
+ MSCLPTokenInfo tokenArray, /* token struct array */
+ MSCPULong32 arrayLength /* Length of array */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCListTokens(
+ listScope,
+ tokenArray,
+ arrayLength
+ );
+
+ return rv;
+}
+
+ /* Establishes a connection to the specified token */
+MSC_RV msc_EstablishConnection(
+ MSCLPTokenInfo tokenStruct, /* The struct of token */
+ MSCULong32 sharingMode, /* Mode of sharing */
+ MSCPUChar8 applicationName, /* The applet ID/Name */
+ MSCULong32 nameSize, /* The ID/Name Size */
+ MSCLPTokenConnection pConnection /* Returned connection */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCEstablishConnection(
+ tokenStruct,
+ sharingMode,
+ applicationName,
+ nameSize,
+ pConnection
+ );
+
+ return rv;
+}
+
+ /* Releases a connection to the specified token */
+MSC_RV msc_ReleaseConnection(
+ MSCLPTokenConnection pConnection, /* Connection handle */
+ MSCULong32 endAction /* Action to perform */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCReleaseConnection(
+ pConnection,
+ endAction
+ );
+
+ return rv;
+}
+
+ /* Blocks for an event to occur on a token */
+MSC_RV msc_WaitForTokenEvent(
+ MSCLPTokenInfo tokenArray, /* Array of token structs */
+ MSCULong32 arraySize, /* Size of the array */
+ MSCULong32 timeoutValue /* Timeout */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCWaitForTokenEvent(
+ tokenArray,
+ arraySize,
+ timeoutValue
+ );
+
+ return rv;
+}
+
+ /* Cancels a pending MSCWaitForTokenEvent */
+MSC_RV msc_CancelEventWait(
+ void /* No parameters */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCCancelEventWait();
+
+ return rv;
+}
+
+ /* Registers a callback function for event change */
+MSC_RV msc_CallbackForTokenEvent(
+ MSCLPTokenInfo tokenArray, /* Array of token structs */
+ MSCULong32 arraySize, /* Size of the array */
+ MSCCallBack callBack, /* Callback function */
+ MSCPVoid32 appData /* Application data */
+)
+{
+ MSC_RV rv = SCARD_E_UNSUPPORTED_FEATURE;
+#if 0
+ rv = MSCCallbackForTokenEvent(
+ tokenArray,
+ arraySize,
+ callBack,
+ appData
+ );
+#endif
+ return rv;
+}
+
+ /* Cancels all callback registrations */
+MSC_RV msc_CallbackCancelEvent()
+{
+ MSC_RV rv = SCARD_E_UNSUPPORTED_FEATURE;
+#if 0
+ rv = MSCCallbackCancelEvent();
+#endif
+ return rv;
+}
+
+ /* Locks a transaction to the token */
+MSC_RV msc_BeginTransaction(
+ MSCLPTokenConnection pConnection /* Connection handle */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCBeginTransaction(
+ pConnection
+ );
+
+ return rv;
+}
+
+ /* Releases a locked transaction to the token */
+MSC_RV msc_EndTransaction(
+ MSCLPTokenConnection pConnection, /* Connection handle */
+ MSCULong32 endAction /* Action to perform on token */
+)
+{
+ MSC_RV rv;
+
+ rv = MSCEndTransaction(
+ pConnection,
+ endAction
+ );
+
+ return rv;
+}
+
+ /* Pre-personalization function */
+MSC_RV msc_WriteFramework(
+ MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams
+)
+{
+ MSC_RV rv;
+
+ rv = MSCWriteFramework(
+ pConnection,
+ pInitParams
+ );
+
+ return rv;
+}
+
+MSC_RV msc_GetStatus(
+ MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo
+)
+{
+ MSC_RV rv;
+
+ rv = MSCGetStatus(
+ pConnection,
+ pStatusInfo
+ );
+
+ return rv;
+}
+
+MSC_RV msc_GetCapabilities(
+ MSCLPTokenConnection pConnection,
+ MSCULong32 Tag,
+ MSCPUChar8 Value,
+ MSCPULong32 Length
+)
+{
+ MSC_RV rv;
+
+ rv = MSCGetCapabilities(
+ pConnection,
+ Tag,
+ Value,
+ Length
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ExtendedFeature(
+ MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature,
+ MSCPUChar8 outData,
+ MSCULong32 outLength,
+ MSCPUChar8 inData,
+ MSCPULong32 inLength
+)
+{
+ MSC_RV rv;
+
+ rv = MSCExtendedFeature(
+ pConnection,
+ extFeature,
+ outData,
+ outLength,
+ inData,
+ inLength
+ );
+
+ return rv;
+}
+
+MSC_RV msc_GenerateKeys(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum,
+ MSCUChar8 pubKeyNum,
+ MSCLPGenKeyParams pParams
+)
+{
+ MSC_RV rv;
+
+ rv = MSCGenerateKeys(
+ pConnection,
+ prvKeyNum,
+ pubKeyNum,
+ pParams
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ImportKey(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL,
+ MSCPUChar8 pKeyBlob,
+ MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCImportKey(
+ pConnection,
+ keyNum,
+ pKeyACL,
+ pKeyBlob,
+ keyBlobSize,
+ keyPolicy,
+ pAddParams,
+ addParamsSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ExportKey(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob,
+ MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCExportKey(
+ pConnection,
+ keyNum,
+ pKeyBlob,
+ keyBlobSize,
+ pAddParams,
+ addParamsSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ComputeCrypt(
+ MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit,
+ MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize,
+ MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize
+)
+{
+ MSC_RV rv = MSC_SUCCESS;
+ CK_ULONG i;
+
+ /* Handles cached PIN's */
+ for (i = 0; i < 2; i++)
+ {
+ rv = MSCComputeCrypt(
+ pConnection,
+ cryptInit,
+ pInputData,
+ inputDataSize,
+ pOutputData,
+ outputDataSize
+ );
+
+ if (rv != MSC_SUCCESS)
+ {
+ if (CKR_ERROR(slot_ReverifyPins()))
+ break;
+ }
+ else
+ break;
+ }
+
+ return rv;
+}
+
+MSC_RV msc_ExtAuthenticate(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData,
+ MSCULong32 dataSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCExtAuthenticate(
+ pConnection,
+ keyNum,
+ cipherMode,
+ cipherDirection,
+ pData,
+ dataSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ListKeys(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo
+)
+{
+ MSC_RV rv;
+
+ rv = MSCListKeys(
+ pConnection,
+ seqOption,
+ pKeyInfo
+ );
+
+ return rv;
+}
+
+MSC_RV msc_CreatePIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize,
+ MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCCreatePIN(
+ pConnection,
+ pinNum,
+ pinAttempts,
+ pPinCode,
+ pinCodeSize,
+ pUnblockCode,
+ unblockCodeSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_VerifyPIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCVerifyPIN(
+ pConnection,
+ pinNum,
+ pPinCode,
+ pinCodeSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ChangePIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode,
+ MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode,
+ MSCUChar8 newPinCodeSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCChangePIN(
+ pConnection,
+ pinNum,
+ pOldPinCode,
+ oldPinCodeSize,
+ pNewPinCode,
+ newPinCodeSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_UnblockPIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode,
+ MSCULong32 unblockCodeSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCUnblockPIN(
+ pConnection,
+ pinNum,
+ pUnblockCode,
+ unblockCodeSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ListPINs(
+ MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask
+)
+{
+ MSC_RV rv;
+
+ rv = MSCListPINs(
+ pConnection,
+ pPinBitMask
+ );
+
+ return rv;
+}
+
+MSC_RV msc_CreateObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 objectSize,
+ MSCLPObjectACL pObjectACL
+)
+{
+ MSC_RV rv;
+
+ rv = MSCCreateObject(
+ pConnection,
+ objectID,
+ objectSize,
+ pObjectACL
+ );
+
+ return rv;
+}
+
+MSC_RV msc_DeleteObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCUChar8 zeroFlag
+)
+{
+ MSC_RV rv;
+
+ rv = MSCDeleteObject(
+ pConnection,
+ objectID,
+ zeroFlag
+ );
+
+ return rv;
+}
+
+MSC_RV msc_WriteObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset,
+ MSCPUChar8 pInputData,
+ MSCULong32 dataSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCWriteObject(
+ pConnection,
+ objectID,
+ offset,
+ pInputData,
+ dataSize,
+ 0, /* Fixme: rwCallback */
+ 0 /* Fixme: addParams */
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ReadObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset,
+ MSCPUChar8 pOutputData,
+ MSCULong32 dataSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCReadObject(
+ pConnection,
+ objectID,
+ offset,
+ pOutputData,
+ dataSize,
+ 0, /* Fixme: rwCallback */
+ 0 /* Fixme: addParams */
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ListObjects(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo
+)
+{
+ MSC_RV rv;
+
+ rv = MSCListObjects(
+ pConnection,
+ seqOption,
+ pObjectInfo
+ );
+
+ return rv;
+}
+
+MSC_RV msc_LogoutAll(
+ MSCLPTokenConnection pConnection
+)
+{
+ MSC_RV rv;
+
+ rv = MSCLogoutAll(
+ pConnection
+ );
+
+ return rv;
+}
+
+MSC_RV msc_GetChallenge(
+ MSCLPTokenConnection pConnection,
+ MSCPUChar8 pSeed,
+ MSCUShort16 seedSize,
+ MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCGetChallenge(
+ pConnection,
+ pSeed,
+ seedSize,
+ pRandomData,
+ randomDataSize
+ );
+
+ return rv;
+}
+
+MSC_RV msc_GetKeyAttributes(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNumber,
+ MSCLPKeyInfo pKeyInfo
+)
+{
+ MSC_RV rv;
+
+ rv = MSCGetKeyAttributes(
+ pConnection,
+ keyNumber,
+ pKeyInfo
+ );
+
+ return rv;
+}
+
+MSC_RV msc_GetObjectAttributes(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCLPObjectInfo pObjectInfo
+)
+{
+ MSC_RV rv;
+
+ rv = MSCGetObjectAttributes(
+ pConnection,
+ objectID,
+ pObjectInfo
+ );
+
+ return rv;
+}
+
+MSC_RV msc_ReadAllocateObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCPUChar8* pOutputData,
+ MSCPULong32 dataSize
+)
+{
+ MSC_RV rv;
+
+ rv = MSCReadAllocateObject(
+ pConnection,
+ objectID,
+ pOutputData,
+ dataSize,
+ 0, /* Fixme: rwCallback */
+ 0 /* Fixme: addParams */
+ );
+
+ return rv;
+}
+
+
+MSCUChar8 msc_IsTokenReset(MSCLPTokenConnection pConnection)
+{
+ MSCUChar8 rv;
+
+ rv = MSCIsTokenReset(pConnection);
+
+ return rv;
+}
+
+MSCUChar8 msc_ClearReset(MSCLPTokenConnection pConnection)
+{
+ MSCUChar8 rv;
+
+ rv = MSCClearReset(pConnection);
+
+ return rv;
+}
+
+MSCUChar8 msc_IsTokenMoved(MSCLPTokenConnection pConnection)
+{
+ MSCUChar8 rv;
+
+ rv = MSCIsTokenMoved(pConnection);
+
+ return rv;
+}
+
+MSCUChar8 msc_IsTokenChanged(MSCLPTokenConnection pConnection)
+{
+ MSCUChar8 rv;
+
+ rv = MSCIsTokenChanged(pConnection);
+
+ return rv;
+}
+
+MSCUChar8 msc_IsTokenKnown(MSCLPTokenConnection pConnection)
+{
+ MSCUChar8 rv;
+
+ rv = MSCIsTokenKnown(pConnection);
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_msc.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,262 @@
+/******************************************************************************
+**
+** $Id: p11x_msc.h,v 1.2 2003/02/13 20:06:41 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: MSC wrappers
+**
+******************************************************************************/
+
+
+MSC_RV msc_ListTokens(
+ MSCULong32 listScope, /* defines the scope to return */
+ MSCLPTokenInfo tokenArray, /* token struct array */
+ MSCPULong32 arrayLength /* Length of array */
+);
+
+MSC_RV msc_EstablishConnection(
+ MSCLPTokenInfo tokenStruct, /* The struct of token */
+ MSCULong32 sharingMode, /* Mode of sharing */
+ MSCPUChar8 applicationName, /* The applet ID/Name */
+ MSCULong32 nameSize, /* The ID/Name Size */
+ MSCLPTokenConnection pConnection /* Returned connection */
+);
+
+MSC_RV msc_ReleaseConnection(
+ MSCLPTokenConnection pConnection, /* Connection handle */
+ MSCULong32 endAction /* Action to perform */
+);
+
+MSC_RV msc_WaitForTokenEvent(
+ MSCLPTokenInfo tokenArray, /* Array of token structs */
+ MSCULong32 arraySize, /* Size of the array */
+ MSCULong32 timeoutValue /* Timeout */
+);
+
+MSC_RV msc_CancelEventWait(
+ void /* No parameters */
+);
+
+MSC_RV msc_CallbackForTokenEvent(
+ MSCLPTokenInfo tokenArray, /* Array of token structs */
+ MSCULong32 arraySize, /* Size of the array */
+ MSCCallBack callBack, /* Callback function */
+ MSCPVoid32 appData /* Application data */
+);
+
+MSC_RV msc_CallbackCancelEvent();
+
+MSC_RV msc_BeginTransaction(
+ MSCLPTokenConnection pConnection /* Connection handle */
+);
+
+MSC_RV msc_EndTransaction(
+ MSCLPTokenConnection pConnection, /* Connection handle */
+ MSCULong32 endAction /* Action to perform on token */
+);
+
+MSC_RV msc_WriteFramework(
+ MSCLPTokenConnection pConnection,
+ MSCLPInitTokenParams pInitParams
+);
+
+MSC_RV msc_GetStatus(
+ MSCLPTokenConnection pConnection,
+ MSCLPStatusInfo pStatusInfo
+);
+
+MSC_RV msc_GetCapabilities(
+ MSCLPTokenConnection pConnection,
+ MSCULong32 Tag,
+ MSCPUChar8 Value,
+ MSCPULong32 Length
+);
+
+MSC_RV msc_ExtendedFeature(
+ MSCLPTokenConnection pConnection,
+ MSCULong32 extFeature,
+ MSCPUChar8 outData,
+ MSCULong32 outLength,
+ MSCPUChar8 inData,
+ MSCPULong32 inLength
+);
+
+MSC_RV msc_GenerateKeys(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 prvKeyNum,
+ MSCUChar8 pubKeyNum,
+ MSCLPGenKeyParams pParams
+);
+
+MSC_RV msc_ImportKey(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCLPKeyACL pKeyACL,
+ MSCPUChar8 pKeyBlob,
+ MSCULong32 keyBlobSize,
+ MSCLPKeyPolicy keyPolicy,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize
+);
+
+MSC_RV msc_ExportKey(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCPUChar8 pKeyBlob,
+ MSCPULong32 keyBlobSize,
+ MSCPVoid32 pAddParams,
+ MSCUChar8 addParamsSize
+);
+
+MSC_RV msc_ComputeCrypt(
+ MSCLPTokenConnection pConnection,
+ MSCLPCryptInit cryptInit,
+ MSCPUChar8 pInputData,
+ MSCULong32 inputDataSize,
+ MSCPUChar8 pOutputData,
+ MSCPULong32 outputDataSize
+);
+
+
+MSC_RV msc_ExtAuthenticate(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNum,
+ MSCUChar8 cipherMode,
+ MSCUChar8 cipherDirection,
+ MSCPUChar8 pData,
+ MSCULong32 dataSize
+);
+
+
+MSC_RV msc_ListKeys(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPKeyInfo pKeyInfo
+);
+
+MSC_RV msc_CreatePIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCUChar8 pinAttempts,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize,
+ MSCPUChar8 pUnblockCode,
+ MSCUChar8 unblockCodeSize
+);
+
+
+MSC_RV msc_VerifyPIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pPinCode,
+ MSCULong32 pinCodeSize
+);
+
+
+MSC_RV msc_ChangePIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pOldPinCode,
+ MSCUChar8 oldPinCodeSize,
+ MSCPUChar8 pNewPinCode,
+ MSCUChar8 newPinCodeSize
+);
+
+
+MSC_RV msc_UnblockPIN(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 pinNum,
+ MSCPUChar8 pUnblockCode,
+ MSCULong32 unblockCodeSize
+);
+
+
+MSC_RV msc_ListPINs(
+ MSCLPTokenConnection pConnection,
+ MSCPUShort16 pPinBitMask
+);
+
+
+MSC_RV msc_CreateObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 objectSize,
+ MSCLPObjectACL pObjectACL
+);
+
+
+MSC_RV msc_DeleteObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCUChar8 zeroFlag
+);
+
+
+MSC_RV msc_WriteObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset,
+ MSCPUChar8 pInputData,
+ MSCULong32 dataSize
+);
+
+
+MSC_RV msc_ReadObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCULong32 offset,
+ MSCPUChar8 pOutputData,
+ MSCULong32 dataSize
+);
+
+
+MSC_RV msc_ListObjects(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 seqOption,
+ MSCLPObjectInfo pObjectInfo
+);
+
+
+MSC_RV msc_LogoutAll(
+ MSCLPTokenConnection pConnection
+);
+
+
+MSC_RV msc_GetChallenge(
+ MSCLPTokenConnection pConnection,
+ MSCPUChar8 pSeed,
+ MSCUShort16 seedSize,
+ MSCPUChar8 pRandomData,
+ MSCUShort16 randomDataSize
+);
+
+
+MSC_RV msc_GetKeyAttributes(
+ MSCLPTokenConnection pConnection,
+ MSCUChar8 keyNumber,
+ MSCLPKeyInfo pKeyInfo
+);
+
+
+MSC_RV msc_GetObjectAttributes(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCLPObjectInfo pObjectInfo
+);
+
+
+MSC_RV msc_ReadAllocateObject(
+ MSCLPTokenConnection pConnection,
+ MSCString objectID,
+ MSCPUChar8* pOutputData,
+ MSCPULong32 dataSize
+);
+
+MSCUChar8 msc_IsTokenReset(MSCLPTokenConnection pConnection);
+MSCUChar8 msc_ClearReset(MSCLPTokenConnection pConnection);
+MSCUChar8 msc_IsTokenMoved(MSCLPTokenConnection pConnection);
+MSCUChar8 msc_IsTokenChanged(MSCLPTokenConnection pConnection);
+MSCUChar8 msc_IsTokenKnown(MSCLPTokenConnection pConnection);
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_object.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_object.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_object.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,2336 @@
+/******************************************************************************
+**
+** $Id: p11x_object.c,v 1.3 2004/10/14 20:33:36 mb Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Session & object management functions
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+#include <openssl/x509.h>
+
+/******************************************************************************
+** Function: object_FreeAllObjects
+**
+** Recursively releases all objects from the given slot.
+**
+** Parameters:
+** slotID - Slot number to release
+** list - Object to free (used for recursion)
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_FreeAllObjects(CK_SLOT_ID slotID, P11_Object *list)
+{
+ if (list)
+ {
+ if (list->next)
+ object_FreeAllObjects(slotID, list->next);
+
+ object_FreeObject(slotID, list);
+ }
+}
+
+/******************************************************************************
+** Function: object_FreeObject
+**
+** Deletes/frees a specific object from a specific slot. The slot ID is needed
+** because it contains the list of all objects.
+**
+** Parameters:
+** slotID - Slot number that object relates to
+** object - Pointer to object to free
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_FreeObject(CK_SLOT_ID slotID, P11_Object *object)
+{
+ slotID--;
+
+ if (object)
+ {
+ log_Log(LOG_LOW, "Removing object: %lX", object);
+
+ if (object->prev)
+ {
+ object->prev->next = object->next;
+
+ if (st.slots[slotID].objects == object)
+ st.slots[slotID].objects = object->prev;
+ }
+
+ if (object->next)
+ {
+ object->next->prev = object->prev;
+
+ if (st.slots[slotID].objects == object)
+ st.slots[slotID].objects = object->next;
+ }
+
+ if (!object->prev && !object->next)
+ st.slots[slotID].objects = 0x00;
+
+ if (object->msc_obj)
+ free(object->msc_obj);
+
+ if (object->msc_key)
+ free(object->msc_key);
+
+ object_FreeAllAttributes(object->attrib);
+
+ memset(object, 0x00, sizeof(P11_Object));
+
+ free(object);
+ }
+}
+
+/******************************************************************************
+** Function: object_FreeAllAttributes
+**
+** Deletes/frees all attributes relating to a specific object
+**
+** Parameters:
+** list - attribute to free (used for recursion)
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_FreeAllAttributes(P11_Attrib *list)
+{
+ if (list)
+ {
+ log_Log(LOG_LOW, "Removing attribute: %lX", list);
+
+ if (list->next)
+ object_FreeAllAttributes(list->next);
+
+ if (list->attrib.pValue)
+ free(list->attrib.pValue);
+
+ memset(list, 0x00, sizeof(P11_Attrib));
+
+ free(list);
+ }
+}
+
+/******************************************************************************
+** Function: object_AddObject
+**
+** Adds an object to specified slot
+**
+** Parameters:
+** slotID - Slot number to add object to
+** phObject - Return handle new object
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** CKR_OK
+*******************************************************************************/
+CK_RV object_AddObject(CK_SLOT_ID slotID, CK_OBJECT_HANDLE *phObject)
+{
+ CK_RV rv = CKR_OK;
+
+ *phObject = 0;
+ slotID--;
+
+ if (st.slots[slotID].objects)
+ {
+ if (st.prefs.obj_sort_order == P11_OBJ_SORT_NEWEST_LAST)
+ {
+ P11_Object *object_l;
+
+ object_l = st.slots[slotID].objects;
+ while(object_l->next)
+ object_l = object_l->next;
+
+ object_l->next = (P11_Object *)calloc(1, sizeof(P11_Object));
+
+ if (!object_l->next)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ object_l->next->prev = object_l;
+ object_l->next->check = object_l->next;
+ *phObject = (CK_OBJECT_HANDLE)object_l->next;
+ }
+ }
+ else
+ {
+ st.slots[slotID].objects->prev = (P11_Object *)calloc(1, sizeof(P11_Object));
+ if (!st.slots[slotID].objects->prev)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ st.slots[slotID].objects->prev->next = st.slots[slotID].objects;
+ st.slots[slotID].objects = st.slots[slotID].objects->prev;
+ st.slots[slotID].objects->check = st.slots[slotID].objects;
+ *phObject = (CK_OBJECT_HANDLE)st.slots[slotID].objects;
+ }
+ }
+ }
+ else
+ {
+ st.slots[slotID].objects = (P11_Object *)calloc(1, sizeof(P11_Object));
+ if (!st.slots[slotID].objects)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ st.slots[slotID].objects->check = st.slots[slotID].objects;
+ *phObject = (CK_OBJECT_HANDLE)st.slots[slotID].objects;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_UpdateKeyInfo
+**
+** Add a new token keyinfo to this session's object list. Creates a new
+** object if neccessary, otherwise updates the existing object.
+**
+** Parameters:
+** hSession - Session handle
+** hObject - Returns new or existing object handle
+** pKeyInfo - Sets the object's msc_key property to this
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** CKR_OK
+*******************************************************************************/
+CK_RV object_UpdateKeyInfo(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE *hObject, MSCKeyInfo *pKeyInfo)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *object_l, *new_obj;
+
+ if (!pKeyInfo)
+ {
+ new_obj = (P11_Object *)*hObject;
+ pKeyInfo = new_obj->msc_key;
+ }
+ else
+ {
+ object_l = st.slots[session->session.slotID - 1].objects;
+ while (object_l)
+ {
+ if (object_l->msc_key && (object_l->msc_key->keyNum == pKeyInfo->keyNum))
+ {
+ log_Log(LOG_LOW, "Found existing key num: %lu", pKeyInfo->keyNum);
+ memcpy(object_l->msc_key, pKeyInfo, sizeof(MSCKeyInfo));
+ if (hObject) *hObject = (CK_OBJECT_HANDLE)object_l;
+ return rv;
+ }
+
+ object_l = object_l->next;
+ }
+
+ if (!CKR_ERROR(rv = object_AddObject(session->session.slotID, (CK_OBJECT_HANDLE *)&new_obj)))
+ {
+ log_Log(LOG_LOW, "New key handle: %X", new_obj);
+ new_obj->msc_key = (MSCKeyInfo *)calloc(1, sizeof(MSCKeyInfo));
+ if (!new_obj->msc_key)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ memcpy(new_obj->msc_key, pKeyInfo, sizeof(MSCKeyInfo));
+ if (hObject) *hObject = (CK_OBJECT_HANDLE)new_obj;
+ }
+ }
+ }
+
+ if (!CKR_ERROR(rv))
+ {
+ CK_BYTE key_obj_id[3] = "k ";
+
+ key_obj_id[1] = pKeyInfo->keyNum > 9 ? 65 + pKeyInfo->keyNum : 48 + pKeyInfo->keyNum; /* Vinnie 1749 A-F (55-65) */
+
+ object_FreeAllAttributes(new_obj->attrib);
+ new_obj->attrib = 0;
+
+ (void)CKR_ERROR(rv = object_ReadAttributes(hSession, key_obj_id, new_obj));
+ }
+
+ P11_ERR("Done UpdateKeyInfo");
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_UpdateObjectInfo
+**
+** Add a new token objectinfo to this session's object list. Creates a new
+** object if neccessary, otherwise updates the existing object.
+**
+** If the object is a certificate then this function does some extra work
+** to make sure the public/private match up and have all the attributes they
+** need.
+**
+** Parameters:
+** hSession - Session handle
+** pObjectInfo - Returns new or existing object handle
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** CKR_FUNCTION_FAILED on general error (could be failed MSC call)
+** CKR_OK
+*******************************************************************************/
+CK_RV object_UpdateObjectInfo(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE *hObject, MSCObjectInfo *pObjectInfo)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ P11_Object *object_l, *new_obj;
+ P11_Attrib *attrib, *modulus, *cka_id, *pub_exp;
+ CK_ATTRIBUTE ck_attrib;
+ CK_OBJECT_CLASS obj_class;
+ CK_BYTE t_obj_id[MSC_MAXSIZE_OBJID];
+ CK_BYTE *data;
+
+ if (!pObjectInfo)
+ {
+ new_obj = (P11_Object *)*hObject;
+ pObjectInfo = new_obj->msc_obj;
+ }
+ else
+ {
+ object_l = slot->objects;
+ while (object_l)
+ {
+ /* Fixme: object ID's are always strings?! */
+ if (object_l->msc_obj && (!strncmp(object_l->msc_obj->objectID, pObjectInfo->objectID, MSC_MAXSIZE_OBJID)))
+ {
+ log_Log(LOG_LOW, "Found existing object ID: %.*s", MSC_MAXSIZE_OBJID, pObjectInfo->objectID);
+ memcpy(object_l->msc_obj, pObjectInfo, sizeof(MSCObjectInfo));
+ if (hObject) *hObject = (CK_OBJECT_HANDLE)object_l;
+ return rv;
+ }
+
+ object_l = object_l->next;
+ }
+
+ if (!CKR_ERROR(rv = object_AddObject(session->session.slotID, (CK_OBJECT_HANDLE *)&new_obj)))
+ {
+ log_Log(LOG_LOW, "New object handle: %X", new_obj);
+ new_obj->msc_obj = (MSCObjectInfo *)calloc(1, sizeof(MSCObjectInfo));
+ if (!new_obj->msc_obj)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ memcpy(new_obj->msc_obj, pObjectInfo, sizeof(MSCObjectInfo));
+ if (hObject) *hObject = (CK_OBJECT_HANDLE)new_obj;
+ }
+ }
+ }
+
+ if (!CKR_ERROR(rv))
+ {
+ object_FreeAllAttributes(new_obj->attrib);
+ new_obj->attrib = 0;
+
+ data = (CK_BYTE *)malloc(pObjectInfo->objectSize);
+
+ if (!data)
+ rv = CKR_HOST_MEMORY;
+ else if (MSC_ERROR(msc_ReadObject(&slot->conn,
+ pObjectInfo->objectID,
+ 0,
+ data,
+ pObjectInfo->objectSize)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ (void)CKR_ERROR(rv = object_AddAttribute(new_obj, CKA_VALUE, FALSE, data, pObjectInfo->objectSize, &attrib));
+
+ if (data)
+ free(data);
+
+ strncpy((char *)t_obj_id, pObjectInfo->objectID, sizeof(t_obj_id));
+ t_obj_id[0] = tolower(t_obj_id[0]);
+
+ if (!CKR_ERROR(rv = object_ReadAttributes(hSession, t_obj_id, new_obj)))
+ {
+ rv = object_InferClassAttributes(hSession, new_obj);
+ }
+
+ obj_class = CKO_CERTIFICATE;
+ ck_attrib.type = CKA_CLASS;
+ ck_attrib.pValue = &obj_class;
+ ck_attrib.ulValueLen = 4;
+
+ if (object_MatchAttrib(&ck_attrib, new_obj))
+ {
+ if (!CKR_ERROR_NOLOG(object_GetAttrib(CKA_MODULUS, new_obj, &modulus)) &&
+ !CKR_ERROR_NOLOG(object_GetAttrib(CKA_PUBLIC_EXPONENT, new_obj, &pub_exp)) &&
+ !CKR_ERROR_NOLOG(object_GetAttrib(CKA_ID, new_obj, &cka_id)))
+ {
+ obj_class = CKO_PUBLIC_KEY;
+
+ object_l = slot->objects;
+ while (object_l)
+ {
+ if (object_MatchAttrib(&cka_id->attrib, object_l) &&
+ object_MatchAttrib(&ck_attrib, object_l))
+ {
+ log_Log(LOG_LOW, "Found existing public key key match.");
+ break;
+ }
+
+ object_l = object_l->next;
+ }
+
+ /* object_l will be null if we didn't find an existing public key */
+ if (!object_l &&
+ !CKR_ERROR(rv = object_AddObject(session->session.slotID, (CK_OBJECT_HANDLE *)&object_l)))
+ {
+ log_Log(LOG_LOW, "Added non-token public key object");
+
+ obj_class = CKO_PUBLIC_KEY;
+ (void)CKR_ERROR(object_AddAttribute(object_l,
+ CKA_CLASS,
+ FALSE,
+ (CK_BYTE *)ck_attrib.pValue,
+ ck_attrib.ulValueLen, 0));
+
+ (void)CKR_ERROR(object_AddAttribute(object_l,
+ CKA_MODULUS,
+ FALSE,
+ (CK_BYTE *)modulus->attrib.pValue,
+ modulus->attrib.ulValueLen, 0));
+
+ (void)CKR_ERROR(object_AddAttribute(object_l,
+ CKA_PUBLIC_EXPONENT,
+ FALSE,
+ (CK_BYTE *)pub_exp->attrib.pValue,
+ pub_exp->attrib.ulValueLen, 0));
+
+ (void)CKR_ERROR(object_AddAttribute(object_l,
+ CKA_ID,
+ FALSE,
+ (CK_BYTE *)cka_id->attrib.pValue,
+ cka_id->attrib.ulValueLen, 0));
+ }
+ }
+ }
+
+ /* Fixme: move this up into the previous if's code block? */
+ obj_class = CKO_CERTIFICATE;
+ ck_attrib.type = CKA_CLASS;
+ ck_attrib.pValue = &obj_class;
+ ck_attrib.ulValueLen = 4;
+
+ if (object_MatchAttrib(&ck_attrib, new_obj))
+ {
+ if (!CKR_ERROR_NOLOG(object_GetAttrib(CKA_MODULUS, new_obj, &modulus)))
+ {
+ if (!CKR_ERROR_NOLOG(object_GetAttrib(CKA_ID, new_obj, &cka_id)))
+ {
+ obj_class = CKO_PRIVATE_KEY;
+
+ object_l = slot->objects;
+ while (object_l)
+ {
+ if (object_MatchAttrib(&cka_id->attrib, object_l) &&
+ object_MatchAttrib(&ck_attrib, object_l))
+ {
+ log_Log(LOG_LOW, "Found private key match. Added modulus to key.");
+ (void)CKR_ERROR(object_AddAttribute(object_l,
+ CKA_MODULUS,
+ FALSE,
+ (CK_BYTE *)modulus->attrib.pValue,
+ modulus->attrib.ulValueLen, 0));
+ break;
+ }
+
+ object_l = object_l->next;
+ }
+ }
+ }
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_FreeTokenObjects
+**
+** This only deletes/frees objects that are token objects (objects stored on
+** the token).
+**
+** Fixme: This function is not used?
+**
+** Parameters:
+** slotID - Slot number to free objects on
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_FreeTokenObjects(CK_SLOT_ID slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Object *object_l;
+
+ object_l = st.slots[slotID - 1].objects;
+
+ while (object_l)
+ {
+ if (object_l->msc_obj || object_l->msc_key)
+ object_FreeObject(slotID, object_l);
+
+ object_l = st.slots[slotID - 1].objects;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_GetAttrib
+**
+** Gets an attribute from an object
+**
+** Parameters:
+** type - Attribute type to get (like CKA_ID)
+** object - Object to search for attribute
+** attrib - Returns the found attribute
+**
+** Returns:
+** CKR_ATTRIBUTE_TYPE_INVALID if attribute was not found
+** CKR_OK if attribute was found
+*******************************************************************************/
+CK_RV object_GetAttrib(CK_ATTRIBUTE_TYPE type, P11_Object *object, P11_Attrib **attrib)
+{
+ CK_RV rv = CKR_ATTRIBUTE_TYPE_INVALID;
+ P11_Attrib *attrib_l;
+
+ attrib_l = object->attrib;
+ while (attrib_l)
+ {
+ if (type == attrib_l->attrib.type)
+ {
+ rv = CKR_OK;
+ if (attrib)
+ *attrib = attrib_l;
+ break;
+ }
+
+ attrib_l = attrib_l->next;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_SetAttrib
+**
+** Set an attribute on an object (or adds a new one if it doesn't exist).
+** This function is the same as object_AddAttribute.
+**
+** Fixme: this function is not used?
+**
+** Parameters:
+** object - Object to add attribute to
+** attrib - Attribute to add
+**
+** Returns:
+** Error from object_AddAttribute
+** CKR_OK
+*******************************************************************************/
+CK_RV object_SetAttrib(P11_Object *object, CK_ATTRIBUTE *attrib)
+{
+ CK_RV rv = CKR_OK;
+ P11_Attrib *attrib_new;
+
+ (void)CKR_ERROR(rv = object_AddAttribute(object,
+ attrib->type,
+ TRUE,
+ (CK_BYTE *)attrib->pValue,
+ attrib->ulValueLen,
+ &attrib_new));
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_AddAttribute
+**
+** Adds a new attribute to an object or replaces an existing attribute if it
+** already exists.
+**
+** Parameters:
+** object - Object to add attribute to
+** type - Attribute type (CKA_ID, etc.)
+** token - TRUE/FALSE stating whether this attribute will be stored on the
+** token
+** value - Value of attribute (pValue)
+** value_len - Length of value (ulValueLen)
+** attrib - Pointer to new attribute object
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV object_AddAttribute(P11_Object *object, CK_ATTRIBUTE_TYPE type, CK_BBOOL token, CK_BYTE *value, CK_ULONG value_len, P11_Attrib **attrib)
+{
+ CK_RV rv = CKR_OK;
+ P11_Attrib *t_attrib = 0;
+
+ if (object->attrib)
+ {
+ if (object_GetAttrib(type, object, &t_attrib) != CKR_OK)
+ {
+ t_attrib = (P11_Attrib *)calloc(1, sizeof(P11_Attrib));
+
+ if (!t_attrib)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ object->attrib->prev = t_attrib;
+ t_attrib->next = object->attrib;
+ object->attrib = t_attrib;
+ }
+ }
+ }
+ else
+ {
+ t_attrib = (P11_Attrib *)calloc(1, sizeof(P11_Attrib));
+
+ if (!t_attrib)
+ rv = CKR_HOST_MEMORY;
+ else
+ object->attrib = t_attrib;
+ }
+
+ if (t_attrib)
+ {
+ if (t_attrib->attrib.pValue)
+ free(t_attrib->attrib.pValue);
+
+ t_attrib->token = token;
+ t_attrib->attrib.type = type;
+ t_attrib->attrib.ulValueLen = value_len;
+
+ if (value_len)
+ t_attrib->attrib.pValue = calloc(1, value_len);
+ else
+ t_attrib->attrib.pValue = 0;
+
+ if (value_len && !t_attrib->attrib.pValue)
+ rv = CKR_HOST_MEMORY; // Fixme: returns error, but has already added the attribute
+ else if (value)
+ memcpy(t_attrib->attrib.pValue, value, value_len);
+ }
+
+ if (attrib)
+ *attrib = t_attrib;
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_AddBoolAttribute
+**
+** Shortcut to add a simple true/false bool attribute to an object.
+**
+** Fixme: do the parameters need to be fixed? "object" should come first
+**
+** Parameters:
+** type - Attribute type (CKA_ID, etc.)
+** value - True or false
+** object - Object to add attribute to
+**
+** Returns:
+** Error from object_AddAttribute
+** CKR_OK;
+*******************************************************************************/
+CK_RV object_AddBoolAttribute(CK_ATTRIBUTE_TYPE type, CK_BBOOL value, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ P11_Attrib *attrib;
+
+ /* Fixme: all bool attributes are stored on the token? */
+ (void)CKR_ERROR(rv = object_AddAttribute(object, type, TRUE, (CK_BYTE *)&value, sizeof(CK_BBOOL), &attrib));
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_MatchAttrib
+**
+** Finds an attribute (by value) of an object
+**
+** Parameters:
+** attrib - Attrib to match
+** object - Object to use
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** True/False if attribute matched or not
+*******************************************************************************/
+CK_RV object_MatchAttrib(CK_ATTRIBUTE *attrib, P11_Object *object)
+{
+ CK_RV rv;
+ P11_Attrib *obj_attrib;
+ CK_BYTE *reverse, *forward, temp;
+ CK_ULONG i;
+
+ object_LogAttribute(attrib);
+
+ reverse = (CK_BYTE *)malloc(attrib->ulValueLen);
+
+ if (!reverse)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ forward = (CK_BYTE *)attrib->pValue;
+
+ memcpy(reverse, forward, attrib->ulValueLen);
+
+ for (i = 0; i < (CK_ULONG)(attrib->ulValueLen / 2); i++)
+ {
+ temp = reverse[i];
+ reverse[i] = reverse[attrib->ulValueLen - i - 1];
+ reverse[attrib->ulValueLen - i - 1] = temp;
+ }
+
+ log_Log(LOG_LOW, "Match attribute type: 0x%lX", attrib->type);
+
+ if (!CKR_ERROR(rv = object_GetAttrib(attrib->type, object, &obj_attrib)) &&
+ (!memcmp(forward, obj_attrib->attrib.pValue, attrib->ulValueLen) ||
+ !memcmp(reverse, obj_attrib->attrib.pValue, attrib->ulValueLen)))
+ {
+ rv = 1;
+ }
+ else
+ {
+ { CK_BYTE buf[4096];
+ object_BinToHex((CK_BYTE *)forward, attrib->ulValueLen, buf);
+ log_Log(LOG_LOW, "Orig:%s", buf);
+ object_BinToHex((CK_BYTE *)reverse, attrib->ulValueLen, buf);
+ log_Log(LOG_LOW, " Rev:%s", buf);
+
+ if (rv == CKR_OK)
+ { object_BinToHex((CK_BYTE *)obj_attrib->attrib.pValue, obj_attrib->attrib.ulValueLen, buf);
+ log_Log(LOG_LOW, " Obj:%s", buf); } }
+
+ rv = 0;
+ }
+
+ free(reverse);
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_TemplateGetAttrib
+**
+** Finds an attribute inside a template attribute list. This works with
+** CK_ATTRIBUTE instead of a P11_Attrib and does not match by value, only
+** attribute type.
+**
+** Parameters:
+** type - Attribute type (CKA_ID, etc.)
+** attrib - Attribute list
+** attrib_count - Number of elements in attribute list
+** attrib_out - Returns matched attribute
+**
+** Returns:
+** CKR_ATTRIBUTE_TYPE_INVALID if attribute was not found
+** CKR_OK
+*******************************************************************************/
+CK_RV object_TemplateGetAttrib(CK_ATTRIBUTE_TYPE type,
+ CK_ATTRIBUTE *attrib,
+ CK_ULONG attrib_count,
+ CK_ATTRIBUTE **attrib_out)
+{
+ CK_RV rv = CKR_ATTRIBUTE_TYPE_INVALID;
+ CK_ULONG i;
+
+ for (i = 0; i < attrib_count; i++)
+ {
+ if (attrib[i].type == type)
+ {
+ if (attrib_out)
+ *attrib_out = &attrib[i];
+
+ rv = CKR_OK;
+ break;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_RSAGenKeyPair
+**
+** Generates an RSA key pair on the token
+**
+** Parameters:
+** hSession - Session handle
+** pPublicKeyTemplate - Public key template
+** ulPublicKeyAttributeCount - Public key template attribute count
+** pPrivateKeyTemplate - Private key template
+** ulPrivateKeyAttributeCount - Private key template attribute count
+** phPublicKey - Pointer to new public key object
+** phPrivateKey - Pointer to new private key object
+**
+** Returns:
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV object_RSAGenKeyPair(CK_SESSION_HANDLE hSession,
+ CK_ATTRIBUTE *pPublicKeyTemplate,
+ CK_ULONG ulPublicKeyAttributeCount,
+ CK_ATTRIBUTE *pPrivateKeyTemplate,
+ CK_ULONG ulPrivateKeyAttributeCount,
+ CK_OBJECT_HANDLE *phPublicKey,
+ CK_OBJECT_HANDLE *phPrivateKey)
+{
+ CK_RV rv = CKR_OK;
+ MSC_RV msc_rv;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ P11_Object *objectPub;
+ P11_Object *objectPrv;
+ CK_ATTRIBUTE *attrib;
+ P11_Attrib *p11_attrib;
+ MSCKeyInfo keyInfo;
+ MSCKeyInfo keyInfoPub;
+ MSCKeyInfo keyInfoPrv;
+ CK_BYTE keyNum = 0;
+ CK_ULONG keySize = 0;
+ MSCGenKeyParams params;
+
+ (void)CKR_ERROR(object_TemplateGetAttrib(CKA_MODULUS_BITS,
+ pPublicKeyTemplate,
+ ulPublicKeyAttributeCount,
+ &attrib));
+ memcpy(&keySize, attrib->pValue, attrib->ulValueLen);
+
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_RESET, &keyInfo);
+ if (!MSC_ERROR(msc_rv))
+ keyNum = keyInfo.keyNum + 1;
+ while (!MSC_ERROR(msc_rv) && !CKR_ERROR(rv))
+ {
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_NEXT, &keyInfo);
+
+ if (!MSC_ERROR(msc_rv))
+ keyNum = keyInfo.keyNum + 1;
+ }
+
+ log_Log(LOG_LOW, "KeySize: %lu", keySize);
+ log_Log(LOG_LOW, "KeyNum: %lu", keyNum);
+
+ /* Fixme: check capabilities for CRT */
+
+ params.algoType = MSC_GEN_ALG_RSA_CRT;
+ params.keySize = (MSCUShort16)keySize;
+ params.privateKeyACL.readPermission = MSC_AUT_NONE;
+ params.privateKeyACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ params.privateKeyACL.usePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ params.publicKeyACL.readPermission = MSC_AUT_ALL;
+ params.publicKeyACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ params.publicKeyACL.usePermission = MSC_AUT_ALL;
+ params.privateKeyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_SIGN | MSC_KEYPOLICY_DIR_DECRYPT;
+ params.privateKeyPolicy.cipherMode = MSC_KEYPOLICY_MODE_RSA_NOPAD;
+ params.publicKeyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_VERIFY | MSC_KEYPOLICY_DIR_ENCRYPT;
+ params.publicKeyPolicy.cipherMode = MSC_KEYPOLICY_MODE_RSA_NOPAD;
+ params.keyGenOptions = MSC_OPT_DEFAULT;
+ params.pOptParams = 0;
+ params.optParamsSize = 0;
+
+ if (MSC_ERROR(msc_GenerateKeys(&slot->conn, keyNum, (MSCUChar8)(keyNum + 1), ¶ms)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ {
+
+ (void)MSC_ERROR(msc_GetKeyAttributes(&slot->conn, (MSCUChar8)(keyNum + 1), &keyInfoPub));
+ (void)MSC_ERROR(msc_GetKeyAttributes(&slot->conn, keyNum, &keyInfoPrv));
+
+ log_Log(LOG_LOW, "keyNums: %lu and %lu", keyNum, keyNum + 1);
+
+ (void)CKR_ERROR(object_UpdateKeyInfo(hSession, (CK_OBJECT_HANDLE *)&objectPub, &keyInfoPub));
+ (void)CKR_ERROR(object_UpdateKeyInfo(hSession, (CK_OBJECT_HANDLE *)&objectPrv, &keyInfoPrv));
+
+ *phPublicKey = (CK_OBJECT_HANDLE)objectPub;
+ *phPrivateKey = (CK_OBJECT_HANDLE)objectPrv;
+
+ (void)CKR_ERROR(object_GetAttrib(CKA_MODULUS, objectPub, &p11_attrib));
+ (void)CKR_ERROR(object_AddAttribute(objectPrv,
+ p11_attrib->attrib.type,
+ TRUE, /* Fixme: Always a token attribute? */
+ (CK_BYTE *)p11_attrib->attrib.pValue,
+ p11_attrib->attrib.ulValueLen, 0));
+
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_LogObjects
+**
+** Logs all objects and attributes for specified slot
+**
+** Parameters:
+** slotID - Slot number
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_LogObjects(CK_SLOT_ID slotID)
+{
+ P11_Object *list;
+
+ list = st.slots[slotID - 1].objects;
+
+ while(list)
+ {
+
+ object_LogObject(list);
+
+ list = list->next;
+ }
+}
+
+/******************************************************************************
+** Function: object_LogObject
+**
+** Logs a single object and its attributes
+**
+** Parameters:
+** object - Object to log
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_LogObject(P11_Object *object)
+{
+ P11_Attrib *attrib;
+
+ log_Log(LOG_LOW, "=== Object handle: %X", object);
+
+ if (object->msc_obj)
+ log_Log(LOG_LOW, "--- Object Object: %s Size: %lu",
+ object->msc_obj->objectID, object->msc_obj->objectSize);
+ else if (object->msc_key)
+ log_Log(LOG_LOW, "--- Key Object: %lu Size: %lu",
+ object->msc_key->keyNum, object->msc_key->keySize);
+
+ attrib = object->attrib;
+
+ while(attrib)
+ {
+ object_LogAttribute(&attrib->attrib);
+ attrib = attrib->next;
+ }
+}
+
+/******************************************************************************
+** Function: object_LogAttribute
+**
+** Write out a single attribute to the log file
+**
+** Parameters:
+** attrib - Attribute to log
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_LogAttribute(CK_ATTRIBUTE *attrib)
+{
+ CK_ULONG ulValue = 0;
+ CK_BYTE bValue = 0;
+ CK_BYTE *buf;
+
+ buf = (CK_BYTE *)malloc((attrib->ulValueLen * 3) + 1);
+ if (!buf)
+ {
+ log_Log(LOG_HIGH, "Memory alloc failed");
+ return;
+ }
+
+ if (attrib->pValue)
+ {
+ memcpy(&ulValue, attrib->pValue, 4);
+ memcpy(&bValue, attrib->pValue, 1);
+ object_BinToHex((CK_BYTE *)attrib->pValue, attrib->ulValueLen, buf);
+
+ switch (attrib->type)
+ {
+ case CKA_ID:
+ log_Log(LOG_LOW, "CKA_ID:%s", buf);
+ break;
+ case CKA_SERIAL_NUMBER:
+ log_Log(LOG_LOW, "CKA_SERIAL_NUMBER:%s", buf);
+ break;
+ case CKA_SUBJECT:
+ log_Log(LOG_LOW, "CKA_SUBJECT:%s", buf);
+ break;
+ case CKA_ISSUER:
+ log_Log(LOG_LOW, "CKA_ISSUER:%s", buf);
+ break;
+ case CKA_MODULUS:
+ log_Log(LOG_LOW, "CKA_MODULUS:%s", buf);
+ break;
+ case CKA_CLASS:
+ log_Log(LOG_LOW, "CKA_CLASS: %lu 0x%X", ulValue, ulValue);
+ break;
+ case CKA_KEY_TYPE:
+ log_Log(LOG_LOW, "CKA_KEY_TYPE: %lu 0x%X", ulValue, ulValue);
+ break;
+ case CKA_TOKEN:
+ log_Log(LOG_LOW, "CKA_TOKEN: %lu 0x%X", bValue, bValue);
+ break;
+ case CKA_LABEL:
+ log_Log(LOG_LOW, "CKA_LABEL:%s", buf);
+ log_Log(LOG_LOW, "CKA_LABEL (string): %.*s", attrib->ulValueLen, attrib->pValue);
+ break;
+ case CKA_VALUE:
+ log_Log(LOG_LOW, "CKA_VALUE:%s", buf);
+ break;
+ case CKA_PUBLIC_EXPONENT:
+ log_Log(LOG_LOW, "CKA_PUBLIC_EXPONENT:%s", buf);
+ break;
+ case CKA_CERTIFICATE_TYPE:
+ log_Log(LOG_LOW, "CKA_CERTIFICATE_TYPE:%s", buf);
+ break;
+ case CKA_EXTRACTABLE:
+ log_Log(LOG_LOW, "CKA_EXTRACTABLE:%s", buf);
+ break;
+ case CKA_SIGN_RECOVER:
+ log_Log(LOG_LOW, "CKA_SIGN_RECOVER:%s", buf);
+ break;
+ case CKA_DERIVE:
+ log_Log(LOG_LOW, "CKA_DERIVE:%s", buf);
+ break;
+ case CKA_MODIFIABLE:
+ log_Log(LOG_LOW, "CKA_MODIFIABLE:%s", buf);
+ break;
+ case CKA_UNWRAP:
+ log_Log(LOG_LOW, "CKA_UNWRAP:%s", buf);
+ break;
+ case CKA_DECRYPT:
+ log_Log(LOG_LOW, "CKA_DECRYPT:%s", buf);
+ break;
+ case CKA_PRIVATE:
+ log_Log(LOG_LOW, "CKA_PRIVATE:%s", buf);
+ break;
+ case CKA_SIGN:
+ log_Log(LOG_LOW, "CKA_SIGN:%s", buf);
+ break;
+ case CKA_NEVER_EXTRACTABLE:
+ log_Log(LOG_LOW, "CKA_NEVER_EXTRACTABLE:%s", buf);
+ break;
+ case CKA_ALWAYS_SENSITIVE:
+ log_Log(LOG_LOW, "CKA_CKA_ALWAYS_SENSITIVE:%s", buf);
+ break;
+ case CKA_SENSITIVE:
+ log_Log(LOG_LOW, "CKA_SENSITIVE:%s", buf);
+ break;
+ default:
+ log_Log(LOG_LOW, "CKA_UNKNOWN (0x%lX):%s", attrib->type, buf);
+ break;
+ }
+ }
+
+ free(buf);
+}
+
+/******************************************************************************
+** Function: object_BinToHex
+**
+** Converts a binary array to hex text
+**
+** Parameters:
+** data - Input data
+** data_len - Input data len
+** out - Output text data
+**
+** Returns:
+** none
+*******************************************************************************/
+void object_BinToHex(CK_BYTE *data, CK_ULONG data_len, CK_BYTE *out)
+{
+ CK_ULONG i;
+
+ for (i = 0; i < data_len; i++)
+ sprintf((char *)&out[i * 3], " %.2X", data[i]);
+
+ out[data_len * 3] = 0;
+}
+
+/******************************************************************************
+** Function: object_AddAttributes
+**
+** Used by object_ReadAttributes when reading an object's attribute file.
+** Handles endian conversion of types.
+**
+** Parameters:
+** object - Object to add attributes to
+** data - Raw data to be processed
+** len - Length of raw data
+**
+** Returns:
+** Result of object_AddAttribute
+** CKR_OK
+*******************************************************************************/
+CK_RV object_AddAttributes(P11_Object *object, CK_BYTE *data, CK_ULONG len)
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i;
+ P11_Attrib *attrib;
+ CK_ATTRIBUTE_TYPE type;
+ CK_ULONG data_len;
+
+ for (i = 0; (i < len) && !CKR_ERROR(rv);)
+ {
+ type = (data[i] * 0x1000000) +
+ (data[i+1] * 0x10000) +
+ (data[i+2] * 0x100) +
+ data[i+3];
+
+ data_len = (data[i+4] * 0x100) + data[i+5];
+
+ (void)CKR_ERROR(rv = object_AddAttribute(object, type, TRUE, &data[i + 6], data_len, &attrib));
+
+ log_Log(LOG_LOW, "object_AddAttributes:");
+ object_LogAttribute(&attrib->attrib);
+
+ i += 6 + attrib->attrib.ulValueLen;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_ReadAttributes
+**
+** Reads the attributes (from attribute file) of an object
+**
+** Parameters:
+** hSession - Session handle
+** obj_id - Object ID of attribute file (string)
+** object - Object to add attributes to
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** Error from object_AddAttributes
+** CKR_OK
+*******************************************************************************/
+CK_RV object_ReadAttributes(CK_SESSION_HANDLE hSession, CK_BYTE *obj_id, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ CK_RV msc_rv;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ CK_ULONG data_len;
+ CK_BYTE *data;
+ CK_BYTE data_hdr[7];
+
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_TOKEN, 1, object));
+
+ msc_rv = msc_ReadObject(&slot->conn, (char *)obj_id, 0, data_hdr, sizeof(data_hdr));
+
+ if (MSC_ERROR(msc_rv) && (msc_rv != MSC_UNAUTHORIZED))
+ {
+InferAttributes:
+ if (CKR_ERROR(object_InferAttributes(hSession, object)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ (void)CKR_ERROR(object_WriteAttributes(hSession, object));
+ }
+ else if (msc_rv == MSC_UNAUTHORIZED)
+ {
+ object->sensitive = 1;
+ }
+ else
+ {
+ { CK_BYTE buf[(sizeof(data_hdr) * 3) + 1];
+ object_BinToHex(data_hdr, sizeof(data_hdr), buf);
+ log_Log(LOG_LOW, "Raw attribute header (file %s): %s", obj_id, buf); }
+
+ data_len = (data_hdr[5] * 0x100) + data_hdr[6];
+ data = (CK_BYTE *)malloc(data_len);
+
+ log_Log(LOG_LOW, "Going to read %lu (0x%lX) bytes of data at offset %lX", data_len, data_len, sizeof(data_hdr));
+
+ if (!data)
+ rv = CKR_HOST_MEMORY;
+ else if (MSC_ERROR(msc_ReadObject(&slot->conn,
+ (char *)obj_id,
+ sizeof(data_hdr),
+ data,
+ data_len)))
+ {
+ P11_ERR("Reading of attribute object failed");
+ goto InferAttributes; /* Fixme: may want to remove the goto; this is fairly clean, if hard to follow */
+ }
+ else
+ {
+ { CK_BYTE *buf;
+ buf = (CK_BYTE *)malloc((data_len * 3) + 1);
+ object_BinToHex(data, data_len, buf);
+ log_Log(LOG_LOW, "Raw attribute file: %s", buf);
+ free(buf); }
+
+ (void)CKR_ERROR(rv = object_AddAttributes(object, data, data_len));
+ }
+
+ if (data)
+ free(data);
+ }
+
+ object_LogObject(object);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_InferAttributes
+**
+** Depending on the type of object this adds some default values of attributes
+** or pulls out values that it can and adds them as attributes.
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to infer attributes on
+**
+** Returns:
+** CKR_FUNCTION_FAILED if a non-token object is specified
+** CKR_OK
+*******************************************************************************/
+CK_RV object_InferAttributes(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+
+ if (object->msc_key)
+ object_InferKeyAttributes(hSession, object);
+ else if (object->msc_obj)
+ object_InferObjAttributes(hSession, object);
+ else
+ {
+ P11_ERR("Invalid non-token object");
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_InferKeyAttributes
+**
+** Adds some default values of attributes or pulls out values that it can and
+** adds them as attributes for this key.
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to infer attributes on
+**
+** Returns:
+** Error from object_AddAttribute
+** CKR_OK
+*******************************************************************************/
+CK_RV object_InferKeyAttributes(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ P11_Attrib *attrib, *modulus;
+ CK_OBJECT_CLASS obj_class;
+ CK_KEY_TYPE key_type;
+
+ switch (object->msc_key->keyType)
+ {
+ case MSC_KEY_RSA_PUBLIC:
+ case MSC_KEY_DSA_PUBLIC:
+ obj_class = CKO_PUBLIC_KEY;
+ break;
+ case MSC_KEY_RSA_PRIVATE:
+ case MSC_KEY_RSA_PRIVATE_CRT:
+ case MSC_KEY_DSA_PRIVATE:
+ obj_class = CKO_PRIVATE_KEY;
+ break;
+ case MSC_KEY_DES:
+ case MSC_KEY_3DES:
+ case MSC_KEY_3DES3:
+ obj_class = CKO_SECRET_KEY; /* Fixme: Secret key??? */
+ break;
+ default:
+ obj_class = CKO_DATA;
+ break;
+ }
+
+ switch (object->msc_key->keyType)
+ {
+ case MSC_KEY_DSA_PUBLIC:
+ case MSC_KEY_DSA_PRIVATE:
+ key_type = CKK_DSA;
+ break;
+ case MSC_KEY_RSA_PUBLIC:
+ case MSC_KEY_RSA_PRIVATE:
+ case MSC_KEY_RSA_PRIVATE_CRT:
+ key_type = CKK_RSA;
+ break;
+ case MSC_KEY_DES:
+ key_type = CKK_DES;
+ break;
+ case MSC_KEY_3DES:
+ key_type = CKK_DES2;
+ break;
+ case MSC_KEY_3DES3:
+ key_type = CKK_DES3;
+ break;
+ default:
+ key_type = CKK_VENDOR_DEFINED;
+ break;
+ }
+
+ /* Fixme: some of these are ULONG values? Need to convert to big-endian? */
+ (void)CKR_ERROR(rv = object_AddAttribute(object, CKA_CLASS, TRUE, (CK_BYTE *)&obj_class, sizeof(CK_OBJECT_CLASS), &attrib));
+ (void)CKR_ERROR(rv = object_AddAttribute(object, CKA_KEY_TYPE, TRUE, (CK_BYTE *)&key_type, sizeof(CK_KEY_TYPE), &attrib));
+
+ if ((object->msc_key->keyType == MSC_KEY_RSA_PRIVATE) ||
+ (object->msc_key->keyType == MSC_KEY_RSA_PRIVATE_CRT) ||
+ (object->msc_key->keyType == MSC_KEY_DSA_PRIVATE))
+ {
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_SENSITIVE, 1, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_ALWAYS_SENSITIVE, 1, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_NEVER_EXTRACTABLE, 1, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_SIGN, 1, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_PRIVATE, 1, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_DECRYPT, 1, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_UNWRAP, 1, object));
+
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_MODIFIABLE, 0, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_DERIVE, 0, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_SIGN_RECOVER, 0, object));
+ (void)CKR_ERROR(rv = object_AddBoolAttribute(CKA_EXTRACTABLE, 0, object));
+ }
+
+ if ((object->msc_key->keyType == MSC_KEY_RSA_PUBLIC) ||
+ (object->msc_key->keyType == MSC_KEY_DSA_PUBLIC))
+ {
+ MSCUChar8 keyBlob[4096]; // Fixme: don't hardcode this
+ MSCULong32 keyBlobSize = sizeof(keyBlob);
+ CK_RV msc_rv;
+
+ if (!MSC_ERROR(msc_rv = msc_ExportKey(&slot->conn,
+ object->msc_key->keyNum,
+ keyBlob,
+ &keyBlobSize,
+ 0, 0)))
+ {
+ (void)CKR_ERROR(rv = object_AddAttribute(object,
+ CKA_MODULUS,
+ TRUE,
+ &keyBlob[6],
+ (keyBlob[4] * 0x100) + keyBlob[5], &modulus));
+
+ (void)CKR_ERROR(rv = object_AddAttribute(object,
+ CKA_PUBLIC_EXPONENT,
+ TRUE,
+ &keyBlob[modulus->attrib.ulValueLen + 8],
+ (keyBlob[modulus->attrib.ulValueLen + 6] * 255) + keyBlob[modulus->attrib.ulValueLen + 7],
+ &attrib));
+ }
+ }
+
+ if (!CKR_ERROR(rv = object_AddAttribute(object, CKA_ID, TRUE, 0, 20, &attrib)))
+ {
+ char t_id[21];
+
+ sprintf(t_id, "KEY%.17u", object->msc_key->keyNum);
+ memcpy(attrib->attrib.pValue, t_id, 20);
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_InferObjAttributes
+**
+** Adds some default values of attributes or pulls out values that it can and
+** adds them as attributes for this object.
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to infer attributes on
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_InferObjAttributes(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_WriteAttributes
+**
+** Writes attributes of object out to attribute file. This function is big
+** because it handles keys, certs, and other objects along with creating them
+** if necessary. This could be split into smaller pieces.
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to get attributes from
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc erro
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV object_WriteAttributes(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ MSC_RV msc_rv;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ P11_Attrib *attrib;
+ char obj_id[MSC_MAXSIZE_OBJID];
+ MSCObjectACL objACL;
+ CK_ULONG obj_size;
+ CK_BYTE data_hdr[7];
+ CK_BYTE *data;
+ CK_ULONG data_pos;
+ CK_ATTRIBUTE ck_attrib;
+ CK_BBOOL priv;
+ CK_OBJECT_CLASS obj_class;
+
+ memset(obj_id, 0x00, sizeof(obj_id));
+ memset(data_hdr, 0x00, sizeof(data_hdr));
+
+ attrib = object->attrib;
+ obj_size = 0;
+
+ while (attrib)
+ {
+ if (attrib->token)
+ obj_size += attrib->attrib.ulValueLen + 6; // Fixme: what if the obj_id is more than 2 bytes??
+
+ log_Log(LOG_LOW, "%lX Objsize: %lu Len: %lu", attrib->attrib.type, obj_size, attrib->attrib.ulValueLen);
+
+ attrib = attrib->next;
+ }
+
+ if (object->msc_key)
+ {
+ obj_id[0] = 'k';
+ obj_id[1] = object->msc_key->keyNum + 1 > 9 ? 65 + object->msc_key->keyNum : 48 + object->msc_key->keyNum;
+
+ data_hdr[0] = 0; // Fixme: Key object type
+
+ priv = 0x01;
+ ck_attrib.type = CKA_PRIVATE;
+ ck_attrib.pValue = &priv;
+ ck_attrib.ulValueLen = sizeof(priv);
+
+/*
+ if (object_MatchAttrib(&ck_attrib, object))
+ objACL.readPermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ else
+*/
+ objACL.readPermission = MSC_AUT_ALL;
+
+ objACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ objACL.deletePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+
+ obj_class = CKO_PRIVATE_KEY;
+ ck_attrib.type = CKA_CLASS;
+ ck_attrib.pValue = &obj_class;
+ ck_attrib.ulValueLen = sizeof(obj_class);
+
+ if (object_MatchAttrib(&ck_attrib, object))
+ msc_rv = msc_CreateObject(&slot->conn, (char *)obj_id, st.prefs.prvkey_attrib_size, &objACL);
+ else
+ msc_rv = msc_CreateObject(&slot->conn, (char *)obj_id, st.prefs.pubkey_attrib_size, &objACL);
+
+ if (MSC_ERROR(msc_rv) && (msc_rv != MSC_OBJECT_EXISTS))
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else if (object->msc_obj)
+ {
+ data_hdr[0] = 0; // Fixme: object type
+
+ strncpy((char *)obj_id, object->msc_obj->objectID, sizeof(obj_id));
+ objACL.readPermission = object->msc_obj->objectACL.readPermission;
+ objACL.writePermission = object->msc_obj->objectACL.writePermission;
+ objACL.deletePermission = object->msc_obj->objectACL.deletePermission;
+
+ log_Log(LOG_LOW, "Object ID is: %s", obj_id);
+
+ if (!isupper(obj_id[0]))
+ {
+ P11_ERR("Can't create object; first character in OID is not upper-case");
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else if (CKR_ERROR(object_GetAttrib(CKA_VALUE, object, &attrib)))
+ {
+ P11_ERR("Can't create object; no CKA_VALUE attribute");
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else
+ {
+ msc_rv = msc_CreateObject(&slot->conn, (char *)obj_id, attrib->attrib.ulValueLen, &objACL);
+
+ if (msc_rv == MSC_OBJECT_EXISTS)
+ {
+ if (MSC_ERROR(msc_DeleteObject(&slot->conn, obj_id, 0)))
+ rv = CKR_FUNCTION_FAILED;
+ else if (MSC_ERROR(msc_CreateObject(&slot->conn, (char *)obj_id, attrib->attrib.ulValueLen, &objACL)))
+ rv = CKR_FUNCTION_FAILED;
+ else if (MSC_ERROR(msc_WriteObject(&slot->conn, (char *)obj_id, 0,
+ (CK_BYTE *)attrib->attrib.pValue, attrib->attrib.ulValueLen)))
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else if (MSC_ERROR(msc_rv))
+ rv = CKR_FUNCTION_FAILED;
+ else if (MSC_ERROR(msc_WriteObject(&slot->conn, (char *)obj_id, 0,
+ (CK_BYTE *)attrib->attrib.pValue, attrib->attrib.ulValueLen)))
+ rv = CKR_FUNCTION_FAILED;
+
+ obj_id[0] = tolower(obj_id[0]);
+
+ priv = 0x01;
+ ck_attrib.type = CKA_PRIVATE;
+ ck_attrib.pValue = &priv;
+ ck_attrib.ulValueLen = sizeof(priv);
+
+ if (object_MatchAttrib(&ck_attrib, object))
+ objACL.readPermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ else
+ objACL.readPermission = MSC_AUT_ALL;
+
+ objACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ objACL.deletePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+
+ obj_class = CKO_CERTIFICATE;
+ ck_attrib.type = CKA_CLASS;
+ ck_attrib.pValue = &obj_class;
+ ck_attrib.ulValueLen = sizeof(obj_class);
+
+ if (object_MatchAttrib(&ck_attrib, object))
+ msc_rv = msc_CreateObject(&slot->conn, (char *)obj_id, st.prefs.cert_attrib_size, &objACL);
+ else
+ msc_rv = msc_CreateObject(&slot->conn, (char *)obj_id, st.prefs.data_attrib_size, &objACL);
+
+ if (MSC_ERROR(msc_rv) && (msc_rv != MSC_OBJECT_EXISTS))
+ rv = CKR_FUNCTION_FAILED;
+ }
+ }
+ else
+ {
+ P11_ERR("Invalid non-token object");
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ if (!CKR_ERROR(rv))
+ {
+ data = (CK_BYTE *)malloc(obj_size + sizeof(data_hdr));
+
+ if (!data)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ log_Log(LOG_LOW, "Obj size is: %lu (0x%lX)", obj_size, obj_size);
+
+ data_hdr[1] = obj_id[0];
+ data_hdr[2] = obj_id[1];
+ data_hdr[5] = (CK_BYTE)((obj_size & 0xFF00) >> 8);
+ data_hdr[6] = (CK_BYTE)(obj_size & 0xFF);
+ memcpy(data, data_hdr, sizeof(data_hdr));
+
+ attrib = object->attrib;
+ data_pos = sizeof(data_hdr);
+
+ while (attrib)
+ {
+ if (!attrib->token)
+ {
+ log_Log(LOG_LOW, "Skipping attribute:");
+ object_LogAttribute(&attrib->attrib);
+ }
+ else
+ {
+ log_Log(LOG_LOW, "Writing attribute:");
+ object_LogAttribute(&attrib->attrib);
+
+ data[data_pos] = (CK_BYTE)((attrib->attrib.type & 0xFF000000) >> 24);
+ data[data_pos + 1] = (CK_BYTE)((attrib->attrib.type & 0xFF0000) >> 16);
+ data[data_pos + 2] = (CK_BYTE)((attrib->attrib.type & 0xFF00) >> 8);
+ data[data_pos + 3] = (CK_BYTE)(attrib->attrib.type & 0xFF);
+ data[data_pos + 4] = (CK_BYTE)((attrib->attrib.ulValueLen & 0xFF00) >> 8);
+ data[data_pos + 5] = (CK_BYTE)(attrib->attrib.ulValueLen & 0xFF);
+ memcpy(&data[data_pos + 6], attrib->attrib.pValue, attrib->attrib.ulValueLen);
+
+ data_pos += attrib->attrib.ulValueLen + 6; // Fixme: 2 byte obj_id??
+ }
+
+ attrib = attrib->next;
+ }
+
+ log_Log(LOG_LOW, "ID: %s SIZE: %lu", obj_id, obj_size);
+
+ { CK_BYTE buf[4096];
+ object_BinToHex(data, obj_size + sizeof(data_hdr), buf);
+ log_Log(LOG_LOW, "Data:%s", buf); }
+
+ if (MSC_ERROR(msc_WriteObject(&slot->conn, obj_id, 0, data, obj_size + sizeof(data_hdr))))
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ if (data)
+ free(data);
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_InferClassAttributes
+**
+** Infer attribute about a specific class of object (a certificate for example)
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to infer attributes
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV object_InferClassAttributes(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ CK_ATTRIBUTE attrib;
+ P11_Attrib *obj_attrib, *t_attrib;
+ CK_OBJECT_CLASS obj_class;
+ CK_BYTE buf[4096]; /* Fixme: don't hardcode this */
+ CK_ULONG len;
+
+ log_Log(LOG_LOW, "object_InferClassAttributes");
+
+ if (!CKR_ERROR(object_GetAttrib(CKA_VALUE, object, &obj_attrib)))
+ {
+ obj_class = CKO_CERTIFICATE;
+ attrib.type = CKA_CLASS;
+ attrib.pValue = &obj_class; // Fixme: endian issue
+ attrib.ulValueLen = 4;
+
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKA_VALUE");
+
+ if (object_MatchAttrib(&attrib, object))
+ {
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKO_CERTIFICATE");
+
+ if (CKR_ERROR_NOLOG(object_GetAttrib(CKA_MODULUS, object, &t_attrib)) &&
+ !CKR_ERROR(object_GetCertModulus((CK_BYTE *)obj_attrib->attrib.pValue,
+ obj_attrib->attrib.ulValueLen,
+ buf,
+ &len)))
+ {
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKA_MODULUS");
+ (void)CKR_ERROR(object_AddAttribute(object, CKA_MODULUS, FALSE, buf, len, &t_attrib));
+ }
+
+ if (CKR_ERROR_NOLOG(object_GetAttrib(CKA_PUBLIC_EXPONENT, object, &t_attrib)) &&
+ !CKR_ERROR(object_GetCertPubExponent((CK_BYTE *)obj_attrib->attrib.pValue,
+ obj_attrib->attrib.ulValueLen,
+ buf,
+ &len)))
+ {
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKA_PUBLIC_EXPONENT");
+ (void)CKR_ERROR(object_AddAttribute(object, CKA_PUBLIC_EXPONENT, FALSE, buf, len, &t_attrib));
+ }
+
+ if (CKR_ERROR_NOLOG(object_GetAttrib(CKA_SUBJECT, object, &t_attrib)) &&
+ !CKR_ERROR(object_GetCertSubject((CK_BYTE *)obj_attrib->attrib.pValue,
+ obj_attrib->attrib.ulValueLen,
+ buf,
+ &len)))
+ {
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKA_SUBJECT");
+ (void)CKR_ERROR(object_AddAttribute(object, CKA_SUBJECT, FALSE, buf, len, &t_attrib));
+ }
+
+ if (CKR_ERROR_NOLOG(object_GetAttrib(CKA_ISSUER, object, &t_attrib)) &&
+ !CKR_ERROR(object_GetCertIssuer((CK_BYTE *)obj_attrib->attrib.pValue,
+ obj_attrib->attrib.ulValueLen,
+ buf,
+ &len)))
+ {
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKA_ISSUER");
+ (void)CKR_ERROR(object_AddAttribute(object, CKA_ISSUER, FALSE, buf, len, &t_attrib));
+ }
+
+ if (CKR_ERROR_NOLOG(object_GetAttrib(CKA_SERIAL_NUMBER, object, &t_attrib)) &&
+ !CKR_ERROR(object_GetCertSerial((CK_BYTE *)obj_attrib->attrib.pValue,
+ obj_attrib->attrib.ulValueLen,
+ buf,
+ &len)))
+ {
+ log_Log(LOG_LOW, "object_InferClassAttributes: got CKA_SERIAL_NUMBER");
+ (void)CKR_ERROR(object_AddAttribute(object, CKA_SERIAL_NUMBER, FALSE, buf, len, &t_attrib));
+ }
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_GetCertSerial
+**
+** Pulls the serial number from raw certificate data using OpenSSL.
+**
+** Fixme: add error checking for OpenSSL functions?
+**
+** Parameters:
+** cert - Input certificate
+** cert_size - Size of input data
+** out - Output data (serial number)
+** out_len - Length of output data
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_GetCertSerial(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len)
+{
+ CK_RV rv = CKR_OK;
+ BIO *inObject=NULL;
+ X509 *certObject=NULL;
+ ASN1_INTEGER *serial;
+ BUF_MEM *bptr;
+
+ inObject = BIO_new_mem_buf(cert, cert_size);
+ certObject = d2i_X509_bio(inObject, NULL);
+
+ serial = X509_get_serialNumber(certObject);
+
+ *out_len = serial->length;
+
+ if (out)
+ memcpy(out, serial->data, serial->length);
+
+ { CK_BYTE *buf;
+ buf = (CK_BYTE *)malloc(((*out_len) * 3) + 1);
+ object_BinToHex(out, *out_len, buf);
+ log_Log(LOG_LOW, "GetCertSerial:%s", buf);
+ free(buf); }
+
+ ASN1_INTEGER_free(serial);
+ //Fixme: X509_free(certObject);
+ BIO_get_mem_ptr(inObject, &bptr);
+ BIO_set_close(inObject, BIO_NOCLOSE);
+ BIO_free(inObject);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_GetCertSubject
+**
+** Pulls the subject from raw certificate data using OpenSSL.
+**
+** Fixme: add error checking for OpenSSL functions?
+**
+** Parameters:
+** cert - Input certificate
+** cert_size - Size of input data
+** out - Output data (subject)
+** out_len - Length of output data
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_GetCertSubject(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len)
+{
+ CK_RV rv = CKR_OK;
+ BIO *inObject=NULL;
+ X509 *certObject=NULL;
+ X509_NAME *name;
+ BUF_MEM *bptr;
+
+ inObject = BIO_new_mem_buf(cert, cert_size);
+ certObject = d2i_X509_bio(inObject, NULL);
+
+ name = X509_get_subject_name(certObject);
+
+ if (!out)
+ *out_len = i2d_X509_NAME(name, 0);
+ else
+ *out_len = i2d_X509_NAME(name, &out);
+
+ X509_NAME_free(name);
+ //Fixme: X509_free(certObject);
+ BIO_get_mem_ptr(inObject, &bptr);
+ BIO_set_close(inObject, BIO_NOCLOSE);
+ BIO_free(inObject);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_GetCertIssuer
+**
+** Pulls the issuer from raw certificate data using OpenSSL.
+**
+** Fixme: add error checking for OpenSSL functions?
+**
+** Parameters:
+** cert - Input certificate
+** cert_size - Size of input data
+** out - Output data (issuer)
+** out_len - Length of output data
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_GetCertIssuer(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len)
+{
+ CK_RV rv = CKR_OK;
+ BIO *inObject=NULL;
+ X509 *certObject=NULL;
+ X509_NAME *name;
+ BUF_MEM *bptr;
+
+ inObject = BIO_new_mem_buf(cert, cert_size);
+ certObject = d2i_X509_bio(inObject, NULL);
+
+ name = X509_get_issuer_name(certObject);
+
+ if (!out)
+ *out_len = i2d_X509_NAME(name, 0);
+ else
+ *out_len = i2d_X509_NAME(name, &out);
+
+ X509_NAME_free(name);
+ //Fixme: X509_free(certObject);
+ BIO_get_mem_ptr(inObject, &bptr);
+ BIO_set_close(inObject, BIO_NOCLOSE);
+ BIO_free(inObject);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_GetCertModulus
+**
+** Pulls the modulus from raw certificate data using OpenSSL.
+**
+** Fixme: add error checking for OpenSSL functions?
+**
+** Parameters:
+** cert - Input certificate
+** cert_size - Size of input data
+** out - Output data (modulus)
+** out_len - Length of output data
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_GetCertModulus(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len)
+{
+ CK_RV rv = CKR_OK;
+ BIO *inObject=NULL;
+ X509 *certObject=NULL;
+ EVP_PKEY *pkey;
+ BUF_MEM *bptr;
+
+ inObject = BIO_new_mem_buf(cert, cert_size);
+
+ certObject = d2i_X509_bio(inObject, NULL);
+
+ pkey = X509_get_pubkey(certObject);
+
+ if (!out)
+ *out_len = BN_num_bytes(pkey->pkey.rsa->n);
+ else
+ {
+ *out_len = BN_num_bytes(pkey->pkey.rsa->n);
+ BN_bn2bin(pkey->pkey.rsa->n, out);
+ }
+
+ //Fixme: X509_free(certObject);
+ BIO_get_mem_ptr(inObject, &bptr);
+ BIO_set_close(inObject, BIO_NOCLOSE);
+ BIO_free(inObject);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_GetCertPubExponent
+**
+** Pulls the public exponent from raw certificate data using OpenSSL.
+**
+** Fixme: add error checking for OpenSSL functions?
+**
+** Parameters:
+** cert - Input certificate
+** cert_size - Size of input data
+** out - Output data (public exponent)
+** out_len - Length of output data
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_GetCertPubExponent(CK_BYTE *cert, CK_ULONG cert_size, CK_BYTE *out, CK_ULONG *out_len)
+{
+ CK_RV rv = CKR_OK;
+ BIO *inObject=NULL;
+ X509 *certObject=NULL;
+ EVP_PKEY *pkey;
+ BUF_MEM *bptr;
+
+ inObject = BIO_new_mem_buf(cert, cert_size);
+
+ certObject = d2i_X509_bio(inObject, NULL);
+
+ pkey = X509_get_pubkey(certObject);
+
+ if (!out)
+ *out_len = BN_num_bytes(pkey->pkey.rsa->e);
+ else
+ {
+ *out_len = BN_num_bytes(pkey->pkey.rsa->e);
+ BN_bn2bin(pkey->pkey.rsa->e, out);
+ }
+
+ //Fixme: X509_free(certObject);
+ BIO_get_mem_ptr(inObject, &bptr);
+ BIO_set_close(inObject, BIO_NOCLOSE);
+ BIO_free(inObject);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_CreateCertificate
+**
+** Creates a new certificate object on the token
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to add to token
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_CreateCertificate(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ P11_Object *object_l;
+ P11_Attrib *attrib;
+ CK_BYTE tag, last;
+
+ if (!(object->msc_obj = (MSCObjectInfo *)calloc(1, sizeof(MSCObjectInfo))))
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ object_l = slot->objects;
+ tag = 'C';
+ last = 47;
+
+ while (object_l)
+ {
+ if ((object_l != object) &&
+ object_l->msc_obj &&
+ !CKR_ERROR(object_GetAttrib(CKA_CLASS, object_l, &attrib)))
+ {
+ if (*((CK_ULONG *)attrib->attrib.pValue) == CKO_CERTIFICATE)
+ {
+ tag = object_l->msc_obj->objectID[0];
+ last = object_l->msc_obj->objectID[1];
+ }
+ }
+
+ object_l = object_l->next;
+ }
+
+ object->msc_obj->objectID[0] = tag;
+ object->msc_obj->objectID[1] = last + 1;
+ object->msc_obj->objectID[2] = 0;
+
+ object->msc_obj->objectSize = 0; /* WriteAttributes will figure out the size */
+ object->msc_obj->objectACL.readPermission = MSC_AUT_ALL;
+ object->msc_obj->objectACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ object->msc_obj->objectACL.deletePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+
+ rv = object_WriteAttributes(hSession, object);
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_CreatePublicKey
+**
+** Creates a new public key object on the token (imports RSA key)
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to add to token
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_CreatePublicKey(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ MSC_RV msc_rv;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ CK_BYTE keyNum = 0;
+ MSCKeyInfo keyInfo;
+ P11_Attrib *modulus;
+ P11_Attrib *public_exponent;
+ CK_ULONG keySize = 1024;
+ CK_BYTE *keyBlob;
+ CK_ULONG keyBlobSize;
+
+ if (!(object->msc_key = (MSCKeyInfo *)calloc(1, sizeof(MSCKeyInfo))))
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_RESET, &keyInfo);
+ if (!MSC_ERROR(msc_rv))
+ keyNum = keyInfo.keyNum + 1;
+ while (!MSC_ERROR(msc_rv) && !CKR_ERROR(rv))
+ {
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_NEXT, &keyInfo);
+
+ if (!MSC_ERROR(msc_rv))
+ keyNum = keyInfo.keyNum + 1;
+ }
+
+ if (!CKR_ERROR(object_GetAttrib(CKA_MODULUS, object, &modulus)))
+ keySize = modulus->attrib.ulValueLen * 8;
+ else
+ return CKR_FUNCTION_FAILED;
+
+ (void)CKR_ERROR(object_GetAttrib(CKA_PUBLIC_EXPONENT, object, &public_exponent));
+
+ keyBlobSize = modulus->attrib.ulValueLen +
+ public_exponent->attrib.ulValueLen;
+
+ keyBlob = (CK_BYTE *)malloc(keyBlobSize + 14);
+
+ if (!keyBlob)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ object->msc_key->keyNum = keyNum;
+ object->msc_key->keyType = MSC_KEY_RSA_PUBLIC;
+ object->msc_key->keySize = (MSCUShort16)keySize;
+ object->msc_key->keyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_VERIFY | MSC_KEYPOLICY_DIR_ENCRYPT;
+ object->msc_key->keyPolicy.cipherMode = MSC_KEYPOLICY_MODE_RSA_NOPAD;
+ object->msc_key->keyACL.readPermission = MSC_AUT_ALL;
+ object->msc_key->keyACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ object->msc_key->keyACL.usePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+
+ keyBlobSize = 0;
+ keyBlob[keyBlobSize++] = MSC_BLOB_ENC_PLAIN;
+ keyBlob[keyBlobSize++] = object->msc_key->keyType;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(object->msc_key->keySize >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)object->msc_key->keySize;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(modulus->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)modulus->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], modulus->attrib.pValue, modulus->attrib.ulValueLen);
+ keyBlobSize += modulus->attrib.ulValueLen;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(public_exponent->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)public_exponent->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], public_exponent->attrib.pValue, public_exponent->attrib.ulValueLen);
+ keyBlobSize += public_exponent->attrib.ulValueLen;
+
+ { CK_BYTE *buf;
+ buf = (CK_BYTE *)malloc((keyBlobSize * 3) + 1);
+ object_BinToHex(keyBlob, keyBlobSize, buf);
+ log_Log(LOG_LOW, "Raw keyBlob: %s", buf);
+ free(buf); }
+
+ if (MSC_ERROR(msc_ImportKey(&slot->conn,
+ object->msc_key->keyNum,
+ &object->msc_key->keyACL,
+ keyBlob,
+ keyBlobSize,
+ &object->msc_key->keyPolicy, 0, 0)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ rv = object_WriteAttributes(hSession, object);
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_CreatePrivateKey
+**
+** Creates a new private key object on the token (imports RSA key)
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to add to token
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_CreatePrivateKey(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ MSC_RV msc_rv;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ CK_BYTE keyNum = 0;
+ MSCKeyInfo keyInfo;
+ P11_Attrib *modulus;
+ P11_Attrib *private_exponent;
+ P11_Attrib *public_exponent;
+ P11_Attrib *prime_1;
+ P11_Attrib *prime_2;
+ P11_Attrib *exponent_1;
+ P11_Attrib *exponent_2;
+ P11_Attrib *coefficient;
+ CK_ULONG keySize = 1024;
+ CK_BYTE *keyBlob;
+ CK_ULONG keyBlobSize;
+
+ if (!(object->msc_key = (MSCKeyInfo *)calloc(1, sizeof(MSCKeyInfo))))
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_RESET, &keyInfo);
+ if (!MSC_ERROR(msc_rv))
+ keyNum = keyInfo.keyNum + 1;
+ while (!MSC_ERROR(msc_rv) && !CKR_ERROR(rv))
+ {
+ msc_rv = msc_ListKeys(&slot->conn, MSC_SEQUENCE_NEXT, &keyInfo);
+
+ if (!MSC_ERROR(msc_rv))
+ keyNum = keyInfo.keyNum + 1;
+ }
+
+ if (!CKR_ERROR(object_GetAttrib(CKA_MODULUS, object, &modulus)))
+ keySize = modulus->attrib.ulValueLen * 8;
+
+ (void)CKR_ERROR(object_GetAttrib(CKA_PRIVATE_EXPONENT, object, &private_exponent));
+ (void)CKR_ERROR(object_GetAttrib(CKA_PUBLIC_EXPONENT, object, &public_exponent));
+ (void)CKR_ERROR(object_GetAttrib(CKA_PRIME_1, object, &prime_1));
+ (void)CKR_ERROR(object_GetAttrib(CKA_PRIME_2, object, &prime_2));
+ (void)CKR_ERROR(object_GetAttrib(CKA_EXPONENT_1, object, &exponent_1));
+ (void)CKR_ERROR(object_GetAttrib(CKA_EXPONENT_2, object, &exponent_2));
+ (void)CKR_ERROR(object_GetAttrib(CKA_COEFFICIENT, object, &coefficient));
+
+ keyBlobSize = prime_1->attrib.ulValueLen +
+ prime_2->attrib.ulValueLen +
+ coefficient->attrib.ulValueLen +
+ exponent_1->attrib.ulValueLen +
+ exponent_2->attrib.ulValueLen;
+
+ keyBlob = (CK_BYTE *)malloc(keyBlobSize + 14);
+
+ if (!keyBlob)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ object->msc_key->keyNum = keyNum;
+ object->msc_key->keyType = MSC_KEY_RSA_PRIVATE_CRT;
+ object->msc_key->keySize = (MSCUShort16)keySize;
+ object->msc_key->keyPolicy.cipherDirection = MSC_KEYPOLICY_DIR_SIGN | MSC_KEYPOLICY_DIR_DECRYPT;
+ object->msc_key->keyPolicy.cipherMode = MSC_KEYPOLICY_MODE_RSA_NOPAD;
+ object->msc_key->keyACL.readPermission = MSC_AUT_NONE;
+ object->msc_key->keyACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ object->msc_key->keyACL.usePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+
+ keyBlobSize = 0;
+ keyBlob[keyBlobSize++] = MSC_BLOB_ENC_PLAIN;
+ keyBlob[keyBlobSize++] = object->msc_key->keyType;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(object->msc_key->keySize >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)object->msc_key->keySize;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(prime_1->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)prime_1->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], prime_1->attrib.pValue, prime_1->attrib.ulValueLen);
+ keyBlobSize += prime_1->attrib.ulValueLen;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(prime_2->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)prime_2->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], prime_2->attrib.pValue, prime_2->attrib.ulValueLen);
+ keyBlobSize += prime_2->attrib.ulValueLen;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(coefficient->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)coefficient->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], coefficient->attrib.pValue, coefficient->attrib.ulValueLen);
+ keyBlobSize += coefficient->attrib.ulValueLen;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(exponent_1->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)exponent_1->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], exponent_1->attrib.pValue, exponent_1->attrib.ulValueLen);
+ keyBlobSize += exponent_1->attrib.ulValueLen;
+ keyBlob[keyBlobSize++] = (CK_BYTE)(exponent_2->attrib.ulValueLen >> 8);
+ keyBlob[keyBlobSize++] = (CK_BYTE)exponent_2->attrib.ulValueLen;
+ memcpy(&keyBlob[keyBlobSize], exponent_2->attrib.pValue, exponent_2->attrib.ulValueLen);
+ keyBlobSize += exponent_2->attrib.ulValueLen;
+
+ { CK_BYTE *buf;
+ buf = (CK_BYTE *)malloc((keyBlobSize * 3) + 1);
+ object_BinToHex(keyBlob, keyBlobSize, buf);
+ log_Log(LOG_LOW, "Raw keyBlob: %s", buf);
+ free(buf); }
+
+ if (MSC_ERROR(msc_ImportKey(&slot->conn,
+ object->msc_key->keyNum,
+ &object->msc_key->keyACL,
+ keyBlob,
+ keyBlobSize,
+ &object->msc_key->keyPolicy, 0, 0)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ rv = object_WriteAttributes(hSession, object);
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_CreateObject
+**
+** Creates a new data object on the token
+**
+** Parameters:
+** hSession - Session handle
+** object - Object to add to token
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV object_CreateObject(CK_SESSION_HANDLE hSession, P11_Object *object)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Slot *slot = &st.slots[session->session.slotID - 1];
+ P11_Object *object_l;
+ P11_Attrib *attrib;
+ CK_BYTE tag, last;
+
+ if (!(object->msc_obj = (MSCObjectInfo *)calloc(1, sizeof(MSCObjectInfo))))
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ object_l = slot->objects;
+ tag = 'O';
+ last = 47;
+
+ while (object_l)
+ {
+ if ((object_l != object) &&
+ object_l->msc_obj &&
+ !CKR_ERROR(object_GetAttrib(CKA_CLASS, object_l, &attrib)))
+ {
+ if (*((CK_ULONG *)attrib->attrib.pValue) == CKO_CERTIFICATE)
+ {
+ tag = object_l->msc_obj->objectID[0];
+ last = object_l->msc_obj->objectID[1];
+ }
+ }
+
+ object_l = object_l->next;
+ }
+
+ object->msc_obj->objectID[0] = tag;
+ object->msc_obj->objectID[1] = last + 1;
+ object->msc_obj->objectID[2] = 0;
+
+ object->msc_obj->objectSize = 0; /* WriteAttributes will figure out the size */
+
+ /* Data objects don't have any attributes that specify permissions so we just */
+ /* default to these. */
+ object->msc_obj->objectACL.readPermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ object->msc_obj->objectACL.writePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+ object->msc_obj->objectACL.deletePermission = (MSCUShort16)object_MapPIN(st.prefs.user_pin_num);
+
+ rv = object_WriteAttributes(hSession, object);
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_MapPIN
+**
+** Maps a PIN number to a Musclecard Framework AUT PIN
+**
+** Parameters:
+** pinNum - P11 PIN number
+**
+** Returns:
+** MSC_AUT_XXX
+*******************************************************************************/
+CK_ULONG object_MapPIN(CK_ULONG pinNum)
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.disable_security)
+ return MSC_AUT_ALL;
+ else if (pinNum == 0)
+ return MSC_AUT_PIN_0;
+ else if (pinNum == 1)
+ return MSC_AUT_PIN_1;
+ else if (pinNum == 2)
+ return MSC_AUT_PIN_2;
+ else if (pinNum == 3)
+ return MSC_AUT_PIN_3;
+ else if (pinNum == 4)
+ return MSC_AUT_PIN_4;
+ else
+ return P11_MAX_ULONG;
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: object_UserMode
+**
+** Tries to update the information on "sensitive" objects
+**
+** Parameters:
+** hSession - session handle
+**
+** Returns:
+** CKR_XXX
+*******************************************************************************/
+CK_ULONG object_UserMode(CK_SESSION_HANDLE hSession)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+ P11_Object *object_l;
+
+ if (!session)
+ rv = CKR_FUNCTION_FAILED;
+ else
+ {
+ object_l = st.slots[session->session.slotID - 1].objects;
+ while(object_l && object_l->next)
+ {
+ if (object_l->sensitive)
+ {
+ if (object_l->msc_key)
+ rv = CKR_ERROR(object_UpdateKeyInfo(hSession, (CK_OBJECT_HANDLE *)&object_l, 0));
+ else if (object_l->msc_obj)
+ rv = CKR_ERROR(object_UpdateObjectInfo(hSession, (CK_OBJECT_HANDLE *)&object_l, 0));
+ }
+
+ object_l = object_l->next;
+ }
+ }
+
+ return rv;
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_prefs.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_prefs.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_prefs.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,318 @@
+/******************************************************************************
+**
+** $Id: p11x_prefs.c,v 1.2 2003/02/13 20:06:41 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: PKCS #11 preference handling functions
+**
+******************************************************************************/
+
+#include <stdio.h>
+#include "cryptoki.h"
+
+#ifndef HAVE_STRTOKR
+#undef strtok_r
+#define strtok_r(x,y,z) strtok(x,y)
+#endif
+
+#ifdef WIN32
+#define strcasecmp stricmp
+#endif
+
+/******************************************************************************
+** Function: util_ParsePreference
+**
+** Parse a preference item from a line of text. The text should be null
+** terminated and buf_size keeps overruns from happening.
+**
+** If a preference item is successfully parsed then it is stored in the
+** st.prefs settings.
+**
+** This whole function is fairly verbose and could be broken into smaller
+** pieces to handle things like "get true/false pref" but at least this is
+** very straightforward.
+**
+** Fixme: put this in p11x_prefs.c
+**
+** Parameters:
+** buf - Null terminated text buffer
+** buf_size - Size of buffer
+**
+** Returns:
+** none
+*******************************************************************************/
+void util_ParsePreference(char *buf, CK_ULONG buf_size)
+{
+ char sep[] = "=\t\r\n ";
+ char *token;
+#ifdef HAVE_STRTOKR
+ char *strtok_ptr;
+#endif
+
+ /* We will be using many unsafe string functions so force a NULL at the */
+ /* end of the buffer to protect ourselves */
+ buf[buf_size - 1] = 0;
+ token = strchr(buf, '#');
+
+ if (token)
+ *token = 0;
+
+ token = strtok_r(buf, sep, &strtok_ptr);
+
+ if (token)
+ {
+ if (!strcasecmp("DebugLevel", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"DebugLevel\" failed");
+ else
+ {
+ if (!strcasecmp("LOW", token))
+ st.prefs.log_level = LOG_LOW;
+ else if (!strcasecmp("MED", token))
+ st.prefs.log_level = LOG_MED;
+ else
+ st.prefs.log_level = LOG_HIGH;
+ }
+ }
+ else if (!strcasecmp("LogFilename", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"LogFilename\" failed");
+ else
+ strncpy((char *)st.prefs.log_filename, token, sizeof(st.prefs.log_filename));
+ }
+ else if (!strcasecmp("MultiApp", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"MultiApp\" failed");
+ else
+ {
+ if (!strcasecmp("True", token) || !strcasecmp("Yes", token))
+ st.prefs.multi_app = 1;
+ else if (!strcasecmp("False", token) || !strcasecmp("No", token))
+ st.prefs.multi_app = 0;
+ else
+ log_Log(LOG_HIGH, "Invalid MultiApp preference specified: %s", token);
+ }
+ }
+ else if (!strcasecmp("Threaded", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"Threaded\" failed");
+ else
+ {
+ if (!strcasecmp("True", token) || !strcasecmp("Yes", token))
+ st.prefs.threaded = 1;
+ else if (!strcasecmp("False", token) || !strcasecmp("No", token))
+ st.prefs.threaded = 0;
+ else
+ log_Log(LOG_HIGH, "Invalid Threaded preference specified: %s", token);
+ }
+ }
+ else if (!strcasecmp("SlotStatusThreadScheme", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"SlotStatusThreadScheme\" failed");
+ else
+ {
+ if (!strcasecmp("Full", token))
+ st.prefs.slot_watch_scheme = P11_SLOT_WATCH_THREAD_FULL;
+ else if (!strcasecmp("Partial", token))
+ st.prefs.slot_watch_scheme = P11_SLOT_WATCH_THREAD_PARTIAL;
+ else
+ log_Log(LOG_HIGH, "Invalid SlotStatusThreadScheme specified: %s", token);
+ }
+ }
+ else if (!strcasecmp("ObjectSortOrder", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"ObjectSortOrder\" failed");
+ else
+ {
+ if (!strcasecmp("NewestFirst", token))
+ st.prefs.obj_sort_order = P11_OBJ_SORT_NEWEST_FIRST;
+ else if (!strcasecmp("NewestLast", token))
+ st.prefs.obj_sort_order = P11_OBJ_SORT_NEWEST_LAST;
+ else
+ log_Log(LOG_HIGH, "Invalid ObjectSortOrder specified: %s", token);
+ }
+ }
+ else if (!strcasecmp("CachePIN", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"CachePIN\" failed");
+ else
+ {
+ if (!strcasecmp("True", token) || !strcasecmp("Yes", token))
+ st.prefs.cache_pin = 1;
+ else if (!strcasecmp("False", token) || !strcasecmp("No", token))
+ st.prefs.cache_pin = 0;
+ else
+ log_Log(LOG_HIGH, "Invalid cache_pin preference specified: %s", token);
+ }
+ }
+ else if (!strcasecmp("Version", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"Version\" failed");
+ else
+ {
+ char *pos;
+
+ pos = strchr(token, '.');
+ if (!pos)
+ P11_ERR("Config option \"Version\" failed");
+ else
+ {
+ *pos = 0;
+ st.prefs.version_major = atol(token);
+ st.prefs.version_minor = atol(pos + 1);
+ }
+ }
+ }
+ else if (!strcasecmp("MaxPinTries", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"MaxPinTries\" failed");
+ else
+ st.prefs.max_pin_tries = atol(token);
+ }
+ else if (!strcasecmp("SOUserPinNum", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"SOUserPinNum\" failed");
+ else
+ st.prefs.so_user_pin_num = atol(token);
+ }
+ else if (!strcasecmp("UserPinNum", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"UserPinNum\" failed");
+ else
+ st.prefs.user_pin_num = atol(token);
+ }
+ else if (!strcasecmp("CertAttribSize", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"CertAttribSize\" failed");
+ else
+ st.prefs.cert_attrib_size = atol(token);
+ }
+ else if (!strcasecmp("PubKeyAttribSize", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"PubKeyAttribSize\" failed");
+ else
+ st.prefs.pubkey_attrib_size = atol(token);
+ }
+ else if (!strcasecmp("PrvKeyAttribSize", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"PrvKeyAttribSize\" failed");
+ else
+ st.prefs.prvkey_attrib_size = atol(token);
+ }
+ else if (!strcasecmp("DataAttribSize", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"DataAttribSize\" failed");
+ else
+ st.prefs.data_attrib_size = atol(token);
+ }
+ else if (!strcasecmp("DisableSecurity", token))
+ {
+ token = strtok_r(0, sep, &strtok_ptr);
+ if (!token)
+ P11_ERR("Config option \"DisableSecurity\" failed");
+ else
+ {
+ if (!strcasecmp("True", token) || !strcasecmp("Yes", token))
+ st.prefs.disable_security = 1;
+ else if (!strcasecmp("False", token) || !strcasecmp("No", token))
+ st.prefs.disable_security = 0;
+ else
+ log_Log(LOG_HIGH, "Invalid DisableSecurity preference specified: %s", token);
+ }
+ }
+ }
+}
+
+/******************************************************************************
+** Function: util_ReadPreferences
+**
+** Gets preferences, if available. On UNIX, looks for .pkcs11rc
+** in the $HOME directory, or root directory if $HOME is not
+** defined. Having a preferences file is optional and it is assumed
+** that most of the time users will not have one unless debug/logging
+** or other special settings are required.
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+#ifndef WIN32
+CK_RV util_ReadPreferences()
+{
+ CK_RV rv = CKR_OK;
+ FILE *fp;
+ char rcfilepath[256];
+ char rcfilename[] = "/.pkcs11rc";
+ char buf[1024];
+
+ strncpy(rcfilepath, getenv("HOME"), sizeof(rcfilepath) - sizeof(rcfilename) - 1);
+ strcat(rcfilepath, rcfilename);
+
+ fp = fopen(rcfilepath, "rb");
+ if (fp)
+ {
+ while (fgets(buf, sizeof(buf), fp))
+ util_ParsePreference(buf, sizeof(buf));
+
+ fclose(fp);
+ }
+
+ return rv;
+}
+#else
+CK_RV util_ReadPreferences()
+{
+ CK_RV rv = CKR_OK;
+ FILE *fp;
+ char rcfilepath[] = "C:\\Program Files\\Muscle\\pkcs11rc";
+ char buf[1024];
+
+ fp = fopen(rcfilepath, "rb");
+ if (fp)
+ {
+ while (fgets(buf, sizeof(buf), fp))
+ util_ParsePreference(buf, sizeof(buf));
+
+ fclose(fp);
+ }
+
+ return rv;
+
+}
+#endif
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_session.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_session.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_session.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,114 @@
+/******************************************************************************
+**
+** $Id: p11x_session.c,v 1.2 2003/02/13 20:06:41 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Session & object management functions
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/******************************************************************************
+** Function: session_AddSession
+**
+** Adds a new session
+**
+** Parameters:
+** phSession - Returns a pointer to the new session
+**
+** Returns:
+** CKR_HOST_MEMORY if memory alloc failed
+** CKR_OK
+*******************************************************************************/
+CK_RV session_AddSession(CK_SESSION_HANDLE *phSession)
+{
+ CK_RV rv = CKR_OK;
+
+ *phSession = 0;
+
+ if (st.sessions)
+ {
+ st.sessions->prev = (P11_Session *)calloc(1, sizeof(P11_Session));
+ if (!st.sessions->prev)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ st.sessions->prev->next = st.sessions;
+ st.sessions = st.sessions->prev;
+ st.sessions->check = st.sessions;
+ *phSession = (CK_SESSION_HANDLE)st.sessions;
+ }
+ }
+ else
+ {
+ st.sessions = (P11_Session *)calloc(1, sizeof(P11_Session));
+ if (!st.sessions)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ st.sessions->check = st.sessions;
+ *phSession = (CK_SESSION_HANDLE)st.sessions;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: session_FreeSession
+**
+** Deletes/removes a session
+**
+** Parameters:
+** hSession - Handle of session to remove
+**
+** Returns:
+** CKR_SESSION_HANDLE_INVALID if session handle is invalid
+** CKR_OK
+*******************************************************************************/
+CK_RV session_FreeSession(CK_SESSION_HANDLE hSession)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session = (P11_Session *)hSession;
+
+ if (INVALID_SESSION)
+ rv = CKR_SESSION_HANDLE_INVALID;
+ else
+ {
+ log_Log(LOG_LOW, "Removing session: %lX", hSession);
+
+ if (session->prev) /* Fixme: check for head of list? st.sessions */
+ {
+ session->prev->next = session->next;
+
+ if (session == st.sessions) /* Fixme: Is this needed? */
+ st.sessions = session->prev;
+ }
+
+ if (session->next)
+ {
+ session->next->prev = session->prev;
+
+ if (session == st.sessions)
+ st.sessions = session->next;
+ }
+
+ if (!session->prev && !session->next)
+ st.sessions = 0x00;
+
+ if (session->search_attrib)
+ free(session->search_attrib);
+
+ /* Clear memory, just to be safe */
+ memset(session, 0x00, sizeof(P11_Session));
+
+ free(session);
+ }
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_slot.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_slot.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_slot.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1203 @@
+/******************************************************************************
+**
+** $Id: p11x_slot.c,v 1.2 2003/02/13 20:06:41 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Slot management functions
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/******************************************************************************
+** Function: slot_BeginTransaction
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV slot_BeginTransaction(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ MSC_RV msc_rv;
+
+ log_Log(LOG_LOW, "Begin transaction: %lu", slotID);
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (CKR_ERROR(rv = slot_EstablishConnection(slotID)))
+ rv = rv;
+ else if (MSC_ERROR(msc_rv = msc_BeginTransaction(&st.slots[slotID - 1].conn)))
+ {
+ slot_ReleaseConnection(slotID);
+
+ if ((msc_rv == MSC_TOKEN_RESET) || (msc_rv == MSC_TOKEN_REMOVED))
+ rv = CKR_DEVICE_REMOVED;
+ else
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_EndTransaction
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV slot_EndTransaction(CK_ULONG slotID, CK_ULONG action)
+{
+ CK_RV rv = CKR_OK;
+
+ log_Log(LOG_LOW, "End transaction: %lu", slotID);
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (MSC_ERROR(msc_EndTransaction(&st.slots[slotID - 1].conn, action)))
+ rv = CKR_FUNCTION_FAILED;
+ else if (st.prefs.threaded)
+ (void)CKR_ERROR(rv = slot_ReleaseConnection(slotID));
+
+ return rv;
+}
+
+/*
+** Checks for an open RW SO session
+*/
+/******************************************************************************
+** Function: slot_CheckRWSOsession
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_BBOOL slot_CheckRWSOsession(CK_ULONG slotID)
+{
+ CK_BBOOL rv = FALSE;
+ P11_Session *session_l;
+
+ session_l = st.sessions;
+ while (session_l)
+ {
+ if ((session_l->session.slotID == slotID) &&
+ (session_l->session.state == CKS_RW_SO_FUNCTIONS))
+ {
+ rv = TRUE;
+ break;
+ }
+
+ session_l = session_l->next;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_EstablishConnection
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV slot_EstablishConnection(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ MSC_RV msc_rv;
+ MSCTokenInfo token_info;
+ P11_Slot *slot;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (CKR_ERROR(rv = slot_TokenPresent(slotID)))
+ /* Return error */;
+ else
+ {
+ slot = &st.slots[slotID - 1];
+
+ log_Log(LOG_LOW, "Attempting establish");
+
+ if (!slot->conn.hCard)
+ {
+ log_Log(LOG_LOW, "Establish connection");
+
+ memcpy(&token_info, &slot->conn.tokenInfo, sizeof(MSCTokenInfo));
+ if (MSC_ERROR(msc_rv = msc_EstablishConnection(&token_info,
+ MSC_SHARE_SHARED,
+ NULL, 0,
+ &slot->conn)))
+ {
+ /* memset(&slot->conn, 0x00, sizeof(slot->conn)); */
+ /* memcpy(&slot->conn.tokenInfo, &token_info, sizeof(MSCTokenInfo)); */
+ st.slot_status[slotID - 1] = 0x01;
+ log_Log(LOG_MED, "MSCEstablishConnection failed");
+
+ if ((msc_rv == MSC_TOKEN_RESET) || (msc_rv == MSC_TOKEN_REMOVED))
+ rv = CKR_DEVICE_REMOVED;
+ else
+ rv = CKR_FUNCTION_FAILED;
+ }
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_ReleaseConnection
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV slot_ReleaseConnection(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session_l;
+ P11_Slot *slot;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ slot = &st.slots[slotID - 1];
+ /* Don't close the connection if a session is using it */
+ /* Fixme: this could be sped up by using reference counting instead */
+ log_Log(LOG_LOW, "Attempting release");
+ session_l = st.sessions;
+
+ while (session_l)
+ {
+ if (session_l->session.slotID == slotID)
+ return rv;
+ session_l = session_l->next;
+ }
+
+ if (slot->conn.hCard)
+ {
+ log_Log(LOG_LOW, "Releasing connection (slot_ReleaseConnection)");
+ (void)MSC_ERROR(msc_ReleaseConnection(&slot->conn, MSC_LEAVE_TOKEN));
+ log_Log(LOG_LOW, "Done releasing (slot_ReleaseConnection)");
+ }
+
+ slot->conn.hCard = 0;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_UpdateSlot
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV slot_UpdateSlot(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Slot *slot;
+ MSCTokenInfo *token_info;
+ CK_SLOT_INFO *slot_info;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ slot = &st.slots[slotID - 1];
+ token_info = &slot->conn.tokenInfo;
+ slot_info = &slot->slot_info;
+
+ token_info->tokenState = MSC_STATE_UNAWARE;
+
+ if (MSC_ERROR(msc_WaitForTokenEvent(token_info, 1, 10000)))
+ rv = CKR_FUNCTION_FAILED;
+ else
+ {
+ util_PadStrSet(slot_info->slotDescription, (CK_CHAR *)token_info->slotName, sizeof(slot_info->slotDescription));
+ util_PadStrSet(slot_info->manufacturerID, (CK_CHAR *)"Unknown MFR", sizeof(slot_info->manufacturerID));
+ /* Fixme: If Netscape does not see a token present, it may mark the slot as bad and never use it */
+ slot_info->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT |
+ (CKR_ERROR(slot_TokenPresent(slotID)) ? 0x00 : CKF_TOKEN_PRESENT);
+ slot_info->hardwareVersion.major = 0x01; /* Fixme: unsupported */
+ slot_info->hardwareVersion.minor = 0x00; /* Fixme: unsupported */
+ slot_info->firmwareVersion.major = 0x01; /* Fixme: unsupported */
+ slot_info->firmwareVersion.minor = 0x00; /* Fixme: unsupported */
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_VerifyPIN
+**
+** Description
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV slot_VerifyPIN(CK_SLOT_ID slotID, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
+{
+ CK_RV rv = CKR_OK;
+ CK_RV msc_rv = MSC_SUCCESS;
+ P11_Slot *slot;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ slot = &st.slots[slotID - 1];
+
+ if (userType == CKU_SO)
+ (void)MSC_ERROR(msc_rv = msc_VerifyPIN(&slot->conn, (MSCUChar8)st.prefs.so_user_pin_num, pPin, ulPinLen));
+ else if (userType == CKU_USER)
+ (void)MSC_ERROR(msc_rv = msc_VerifyPIN(&slot->conn, (MSCUChar8)st.prefs.user_pin_num, pPin, ulPinLen));
+ else
+ rv = CKR_USER_TYPE_INVALID;
+
+ if (msc_rv == MSC_AUTH_FAILED)
+ {
+ P11_ERR("PIN INCORRECT");
+ rv = CKR_PIN_INCORRECT;
+ }
+ else if (msc_rv == MSC_IDENTITY_BLOCKED)
+ rv = CKR_PIN_LOCKED;
+ else if (msc_rv != MSC_SUCCESS)
+ rv = CKR_FUNCTION_FAILED;
+ else if (st.prefs.cache_pin && (userType == CKU_SO))
+ {
+ // Fixme: do padding // encryption is disabled
+ // des_ecb3_encrypt(pPin, slot->pins[CKU_SO].pin, st.pin_key[0], st.pin_key[1], st.pin_key[2], 1);
+ memcpy(slot->pins[CKU_SO].pin, pPin, ulPinLen);
+ slot->pins[0].pin_size = ulPinLen;
+ }
+ else if (st.prefs.cache_pin && (userType == CKU_USER))
+ {
+ // Fixme: do padding // encryption is disabled
+ // des_ecb3_encrypt(pPin, slot->pins[CKU_USER].pin, st.pin_key[0], st.pin_key[1], st.pin_key[2], 1);
+ memcpy(slot->pins[CKU_USER].pin, pPin, ulPinLen);
+ slot->pins[1].pin_size = ulPinLen;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_MinRSAKeySize
+**
+** Returns minimum RSA key size
+**
+** Fixme: does Netscape use # bits or # bytes for RSA mechanisms??
+**
+** Parameters:
+** cap - MSC capabilities
+**
+** Returns:
+** Length
+*******************************************************************************/
+CK_ULONG slot_MinRSAKeySize(MSCULong32 cap)
+{
+ CK_ULONG rv = 0;
+
+ if (cap & MSC_CAPABLE_RSA_512)
+ rv = 64;
+ else if (cap & MSC_CAPABLE_RSA_768)
+ rv = 96;
+ else if (cap & MSC_CAPABLE_RSA_1024)
+ rv = 128;
+ else if (cap & MSC_CAPABLE_RSA_2048)
+ rv = 256;
+ else if (cap & MSC_CAPABLE_RSA_4096)
+ rv = 512;
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_MaxRSAKeySize
+**
+** Returns maximum RSA key size
+**
+** Fixme: does Netscape use # bits or # bytes for RSA mechanisms??
+**
+** Parameters:
+** cap - MSC capabilities
+**
+** Returns:
+** Length
+*******************************************************************************/
+CK_ULONG slot_MaxRSAKeySize(MSCULong32 cap)
+{
+ CK_ULONG rv = 0;
+
+ if (cap & MSC_CAPABLE_RSA_4096)
+ rv = 512;
+ else if (cap & MSC_CAPABLE_RSA_2048)
+ rv = 256;
+ else if (cap & MSC_CAPABLE_RSA_1024)
+ rv = 128;
+ else if (cap & MSC_CAPABLE_RSA_768)
+ rv = 96;
+ else if (cap & MSC_CAPABLE_RSA_512)
+ rv = 64;
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_UpdateMechanisms
+**
+** Updates information about the token in a specific slot. Many of the symmetric
+** algorithms are commented out because they are too slow to use on smartcards
+**
+** Parameters:
+** slotID - Slot number to update
+**
+** Returns:
+** CKR_SLOT_ID_INVALID if the slot number is invalid
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_UpdateMechanisms(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Slot *slot;
+ MSCULong32 len = 0;
+ MSCULong32 crypto_alg = 0;
+ MSCULong32 temp_cap = 0;
+ P11_MechInfo *mech;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ slot = &st.slots[slotID - 1];
+
+ slot_FreeAllMechanisms(slot->mechanisms);
+ slot->mechanisms = 0;
+
+ if (MSC_ERROR(msc_GetCapabilities(&slot->conn,
+ MSC_TAG_SUPPORT_CRYPTOALG,
+ (MSCUChar8 *)&crypto_alg,
+ &len)))
+ P11_ERR("MSCGetCapabilities failed");
+
+ if (crypto_alg & MSC_SUPPORT_RSA)
+ {
+ log_Log(LOG_LOW, "Card supports RSA");
+
+ slot_AddMechanism(slot, CKM_SHA1_RSA_PKCS, &mech);
+ mech->info.ulMinKeySize = slot_MinRSAKeySize(temp_cap);
+ mech->info.ulMaxKeySize = slot_MaxRSAKeySize(temp_cap);
+ /* Fixme: these flags may be wrong */
+ mech->info.flags = CKF_ENCRYPT |
+ CKF_DECRYPT |
+ CKF_SIGN |
+ CKF_SIGN_RECOVER |
+ CKF_VERIFY |
+ CKF_VERIFY_RECOVER |
+ CKF_GENERATE |
+ CKF_GENERATE_KEY_PAIR |
+ CKF_WRAP |
+ CKF_UNWRAP;
+
+ if (!MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_CAPABLE_RSA,
+ (MSCUChar8 *)&temp_cap, &len)))
+ {
+ if (temp_cap & MSC_CAPABLE_RSA_KEYGEN)
+ {
+ log_Log(LOG_LOW, "Card supports RSA key gen");
+ slot_AddMechanism(slot, CKM_RSA_PKCS_KEY_PAIR_GEN, &mech);
+
+ mech->info.ulMinKeySize = slot_MinRSAKeySize(temp_cap);
+ mech->info.ulMaxKeySize = slot_MaxRSAKeySize(temp_cap);
+ /* Fixme: these flags may be wrong */
+ mech->info.flags = CKF_GENERATE |
+ CKF_GENERATE_KEY_PAIR;
+ }
+
+ if (temp_cap & (MSC_CAPABLE_RSA_PKCS1 | MSC_CAPABLE_RSA_NOPAD))
+ {
+ if (temp_cap & MSC_CAPABLE_RSA_NOPAD)
+ log_Log(LOG_LOW, "Card supports RSA NOPAD");
+
+ if (temp_cap & MSC_CAPABLE_RSA_PKCS1)
+ log_Log(LOG_LOW, "Card supports RSA PKCS#1");
+
+ slot_AddMechanism(slot, CKM_RSA_PKCS, &mech);
+
+ mech->info.ulMinKeySize = slot_MinRSAKeySize(temp_cap);
+ mech->info.ulMaxKeySize = slot_MaxRSAKeySize(temp_cap);
+ /* Fixme: these flags may be wrong */
+ mech->info.flags = CKF_ENCRYPT |
+ CKF_DECRYPT |
+ CKF_SIGN |
+ CKF_SIGN_RECOVER |
+ CKF_VERIFY |
+ CKF_VERIFY_RECOVER;
+
+ if (temp_cap & MSC_CAPABLE_RSA_NOPAD)
+ mech->info.flags = CKF_WRAP | CKF_UNWRAP;
+ }
+ }
+ }
+
+ if (crypto_alg & MSC_SUPPORT_DSA)
+ {
+ log_Log(LOG_LOW, "Card supports DSA");
+ slot_AddMechanism(slot, CKM_DSA, &mech);
+
+ if (!MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_CAPABLE_DSA, (MSCUChar8 *)&temp_cap, &len)))
+ {
+ if (temp_cap & MSC_CAPABLE_DSA_KEYGEN)
+ slot_AddMechanism(slot, CKM_DSA_KEY_PAIR_GEN, &mech);
+ }
+ }
+
+ if (crypto_alg & MSC_SUPPORT_ELGAMAL)
+ {
+ log_Log(LOG_LOW, "Card supports ElGamal");
+ /* Fixme: unsupported */
+ }
+
+ if (crypto_alg & MSC_SUPPORT_DES)
+ {
+ log_Log(LOG_LOW, "Card supports DES but not returning mechanism");
+
+ /*
+ ** if (!MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_CAPABLE_DES, (MSCUChar8 *)&des_cap, &len)))
+ ** {
+ ** if (des_cap & MSC_CAPABLE_DES_KEYGEN)
+ ** slot_AddMechanism(slot, CKM_DES_KEY_GEN, &mech);
+ ** if (des_cap & MSC_CAPABLE_DES_CBC)
+ ** slot_AddMechanism(slot, CKM_DES_CBC, &mech);
+ ** if (des_cap & MSC_CAPABLE_DES_ECB)
+ ** slot_AddMechanism(slot, CKM_DES_ECB, &mech);
+ ** }
+ */
+ }
+
+ if (crypto_alg & MSC_SUPPORT_3DES)
+ {
+ log_Log(LOG_LOW, "Card supports 3DES but not returning mechanism");
+
+ /*
+ ** if (!MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_CAPABLE_3DES, (MSCUChar8 *)&temp_cap, &len)))
+ ** {
+ ** if (temp_cap & MSC_CAPABLE_3DES_KEYGEN)
+ ** slot_AddMechanism(slot, CKM_DES_KEY_GEN, &mech);
+ ** if (des_cap & MSC_CAPABLE_DES_CBC)
+ ** slot_AddMechanism(slot, CKM_DES3_CBC, &mech);
+ ** if (des_cap & MSC_CAPABLE_DES_ECB)
+ ** slot_AddMechanism(slot, CKM_DES3_ECB, &mech);
+ ** }
+ */
+ }
+
+ if (crypto_alg & MSC_SUPPORT_IDEA)
+ {
+ log_Log(LOG_LOW, "Card supports IDEA");
+ /* Fixme: unsupported */
+ }
+
+ if (crypto_alg & MSC_SUPPORT_AES)
+ {
+ log_Log(LOG_LOW, "Card supports AES");
+ /* Fixme: unsupported */
+ }
+
+ if (crypto_alg & MSC_SUPPORT_BLOWFISH)
+ {
+ log_Log(LOG_LOW, "Card supports BLOWFISH");
+ /* Fixme: unsupported */
+ }
+
+ if (crypto_alg & MSC_SUPPORT_TWOFISH)
+ {
+ log_Log(LOG_LOW, "Card supports TWOFISH");
+ /* Fixme: unsupported */
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_MechanismCount
+**
+** Counts the number of mechanisms in the provided linked list
+**
+** Parameters:
+** mech - Mechanism list
+**
+** Returns:
+** Count
+*******************************************************************************/
+CK_ULONG slot_MechanismCount(P11_MechInfo *mech)
+{
+ CK_ULONG count = 0;
+
+ while (mech)
+ {
+ count++;
+ mech = mech->next;
+ }
+
+ return count;
+}
+
+/******************************************************************************
+** Function: slot_FreeAllMechanisms
+**
+** Recursively frees/deletes all mechanisms in list
+**
+** Parameters:
+** list - List of mechanisms to free
+**
+** Returns:
+** none
+*******************************************************************************/
+void slot_FreeAllMechanisms(P11_MechInfo *list)
+{
+ if (list)
+ {
+ if (list->next)
+ slot_FreeAllMechanisms(list->next);
+
+ free(list);
+ }
+}
+
+/******************************************************************************
+** Function: slot_AddMechanism
+**
+** Adds a mechanism to a specific slot
+**
+** Parameters:
+** slot - Slot to add mechanism to
+** type - Mechanism type
+** mech_info - Returns new mechanism info
+**
+** Returns:
+** CKR_HOST_MEMORY if memory alloc fails
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_AddMechanism(P11_Slot *slot, CK_MECHANISM_TYPE type, P11_MechInfo **mech_info)
+{
+ CK_RV rv = CKR_OK;
+
+ if (slot->mechanisms)
+ {
+ slot->mechanisms->prev = (P11_MechInfo *)calloc(1, sizeof(P11_MechInfo));
+ if (!slot->mechanisms->prev)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ slot->mechanisms->prev->next = slot->mechanisms;
+ slot->mechanisms = slot->mechanisms->prev;
+ slot->mechanisms->type = type;
+
+ if (mech_info)
+ *mech_info = slot->mechanisms;
+ }
+ }
+ else
+ {
+ slot->mechanisms = (P11_MechInfo *)calloc(1, sizeof(P11_MechInfo));
+ if (!slot->mechanisms)
+ rv = CKR_HOST_MEMORY;
+ else
+ {
+ slot->mechanisms->type = type;
+
+ if (mech_info)
+ *mech_info = slot->mechanisms;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_UpdateToken
+**
+** Updates all information about a token in a slot.
+**
+** Parameters:
+** slotID - Slot number to update
+**
+** Returns:
+** CKR_SLOT_ID_INVALID if slotID is invalid
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_UpdateToken(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Slot *slot;
+ P11_Session *session_l;
+ CK_ULONG sess_count, rw_sess_count;
+ MSCUShort16 pin_bit_mask = 0;
+ MSCULong32 support_func = 0;
+ MSCUChar8 cap_pin_maxsize = 0;
+ MSCUChar8 cap_pin_minsize = 0;
+ MSCULong32 len = 0;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (CKR_ERROR((rv = slot_TokenPresent(slotID))))
+ (void)CKR_ERROR(slot_DisconnectSlot(slotID, MSC_RESET_TOKEN));
+ else
+ {
+ slot = &st.slots[slotID - 1];
+
+ if (!MSC_ERROR(msc_GetStatus(&slot->conn, &slot->status_info)) &&
+ !MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_SUPPORT_FUNCTIONS, (MSCUChar8 *)&support_func, &len)) &&
+ !MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_CAPABLE_PIN_MAXSIZE, &cap_pin_maxsize, &len)) &&
+ !MSC_ERROR(msc_GetCapabilities(&slot->conn, MSC_TAG_CAPABLE_PIN_MINSIZE, &cap_pin_minsize, &len)) &&
+ !MSC_ERROR(msc_ListPINs(&slot->conn, &pin_bit_mask))
+ )
+ {
+ session_l = st.sessions;
+ sess_count = rw_sess_count = 0;
+
+ while (session_l)
+ {
+ if (session_l->session.slotID == slotID)
+ {
+ sess_count++;
+ if (session_l->session.flags & CKF_RW_SESSION)
+ rw_sess_count++;
+ }
+
+ session_l = session_l->next;
+ }
+
+ util_PadStrSet(slot->token_info.label, (CK_CHAR *)slot->conn.tokenInfo.tokenName, sizeof(slot->token_info.label));
+ util_PadStrSet(slot->token_info.manufacturerID, (CK_CHAR *)"Unknown MFR", sizeof(slot->token_info.manufacturerID));
+ util_PadStrSet(slot->token_info.model, (CK_CHAR *)"Unknown Model", sizeof(slot->token_info.model));
+ util_PadStrSet(slot->token_info.serialNumber, (CK_CHAR *)"1", sizeof(slot->token_info.serialNumber)); /* Fixme: */
+ slot->token_info.flags = (support_func & MSC_SUPPORT_GETCHALLENGE ? CKF_RNG : 0x00) |
+ CKF_LOGIN_REQUIRED |
+ (pin_bit_mask & (1 << st.prefs.user_pin_num) ? CKF_USER_PIN_INITIALIZED : 0x00) |
+ CKF_TOKEN_INITIALIZED;
+
+ /* None of these */ /* CKF_WRITE_PROTECTED | */
+ /* are used (yet) */ /* CKR_RESTORE_KEY_NOT_NEEDED | */ /* Not supported */
+ /* CKF_CLOCK_ON_TOKEN | */
+ /* CKF_PROTECTED_AUTHENICATION_PATH | */
+ /* CKF_DUAL_CRYPTO_OPERATIONS | */
+ /* CKF_SECONDARY_AUTHENTICATION | */
+ /* CKF_USER_PIN_COUNT_LOW | */
+ /* CKF_USER_PIN_FINAL_TRY | */
+ /* CKF_USER_PIN_LOCKED | */
+ /* CKF_USER_PIN_TO_BE_CHANGED | */
+ /* CKF_SO_PIN_COUNT_LOW | */
+ /* CKF_SO_PIN_FINAL_TRY | */
+ /* CKF_SO_PIN_LOCKED | */
+ /* CKF_SO_PIN_TO_BE_CHANGED | */
+
+ slot->token_info.ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
+ slot->token_info.ulSessionCount = sess_count;
+ slot->token_info.ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
+ slot->token_info.ulRwSessionCount = rw_sess_count;
+ slot->token_info.ulMaxPinLen = cap_pin_maxsize;
+ slot->token_info.ulMinPinLen = cap_pin_minsize;
+ slot->token_info.ulTotalPublicMemory = slot->status_info.totalMemory; /* Fixme: Does this conflict */
+ slot->token_info.ulFreePublicMemory = slot->status_info.freeMemory; /* with the private memory? */
+ slot->token_info.ulTotalPrivateMemory = slot->status_info.totalMemory; /* Fixme: Does this conflict */
+ slot->token_info.ulFreePrivateMemory = slot->status_info.freeMemory; /* with the public memory? */
+ slot->token_info.hardwareVersion.major = ((char *)(&slot->status_info.swVersion))[0]; /* Fixme: endian?? */;
+ slot->token_info.hardwareVersion.minor = ((char *)(&slot->status_info.swVersion))[1];
+ slot->token_info.firmwareVersion.major = ((char *)(&slot->status_info.appVersion))[0]; /* Fixme: endian?? */
+ slot->token_info.firmwareVersion.minor = ((char *)(&slot->status_info.appVersion))[1];
+ memset(slot->token_info.utcTime, '0', sizeof(slot->token_info.utcTime));
+
+ log_Log(LOG_LOW, "Token: %s", slot->conn.tokenInfo.tokenName);
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_UpdateSlotList
+**
+** Updates information about all connected slots
+**
+** Note: this wipes out all current sessions and objects
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_UpdateSlotList()
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i;
+ MSCTokenInfo *tokenArray = 0;
+ MSCULong32 arrayLength = 0;
+
+ /* Fixme: What happens if there are no readers connected? */
+ if (MSC_ERROR(msc_ListTokens(MSC_LIST_SLOTS, NULL, &arrayLength)))
+ {
+ rv = CKR_FUNCTION_FAILED;
+ P11_ERR("MSCListTokens failed");
+ }
+ else
+ {
+ tokenArray = (MSCTokenInfo *)calloc(arrayLength, sizeof(MSCTokenInfo));
+
+ if (!tokenArray)
+ rv = CKR_HOST_MEMORY;
+ else if (MSC_ERROR(msc_ListTokens(MSC_LIST_SLOTS, tokenArray, &arrayLength)))
+ {
+ rv = CKR_FUNCTION_FAILED;
+ P11_ERR("MSCListTokens failed");
+ }
+ else
+ {
+ slot_FreeAllSlots();
+
+ st.slots = (P11_Slot *)calloc(arrayLength, sizeof(P11_Slot));
+
+ if (!st.slots)
+ {
+ rv = CKR_HOST_MEMORY;
+ P11_ERR("calloc failed");
+ }
+ else for (i = 0; i < arrayLength; i++)
+ {
+ memcpy(&st.slots[i].conn.tokenInfo, &tokenArray[i], sizeof(MSCTokenInfo));
+ st.slot_count = i + 1;
+ log_Log(LOG_LOW, "Added reader: %s", tokenArray[i].slotName);
+ }
+
+ if (CKR_ERROR(rv) && st.slots)
+ {
+ free(st.slots);
+ st.slots = 0;
+ }
+ }
+ }
+
+ if (tokenArray)
+ free(tokenArray);
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_FreeAllSlots
+**
+** Releases all slots and all tokens. This assumes you are shutting down and
+** therefore cannot fail.
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_FreeAllSlots()
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i;
+
+ if (st.slots)
+ {
+ for (i = 1; i <= st.slot_count; i++)
+ slot_DisconnectSlot(i, MSC_RESET_TOKEN); /* Fixme: Don't care if this fails? */
+
+ free(st.slots);
+ log_Log(LOG_LOW, "Freed st.slots");
+
+ st.slots = 0;
+ st.slot_count = 0;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_DisconnectSlot
+**
+** Releases a slot and all information about any tokens in the slot.
+**
+** Parameters:
+** slotID - Slot number to release
+** action - A valid MSC card action: MSC_RESET_TOKEN or MSC_LEAVE_TOKEN
+**
+** Returns:
+** CKR_SLOT_ID_INVALID if slotID is invalid
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_DisconnectSlot(CK_ULONG slotID, CK_ULONG action)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session_l;
+ P11_Slot *slot;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ slot = &st.slots[slotID - 1];
+ session_l = st.sessions;
+
+ while (session_l)
+ {
+ if (session_l->session.slotID == slotID)
+ session_FreeSession((CK_SESSION_HANDLE)session_l);
+
+ session_l = st.sessions;
+ }
+
+ object_FreeAllObjects(slotID, st.slots[slotID - 1].objects);
+ slot_FreeAllMechanisms(slot->mechanisms);
+ slot->mechanisms = 0;
+ memset(slot->pins, 0x00, sizeof(slot->pins));
+ slot->pin_state = 0;
+ slot_BlankTokenInfo(&slot->token_info);
+
+ memset(&slot->status_info, 0x00, sizeof(slot->status_info));
+
+ if (slot->conn.hCard)
+ {
+ log_Log(LOG_LOW, "Releasing connection (slot_DisconnectSlot)");
+ (void)MSC_ERROR(msc_ReleaseConnection(&slot->conn, action));
+ }
+
+ slot->conn.hCard = 0;
+ slot->slot_info.flags = (slot->slot_info.flags & ~CKF_TOKEN_PRESENT);
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_PublicMode
+**
+** Switchs all sessions of a slot to PUBLIC mode (versus USER or SO mode)
+**
+** Parameters:
+** slotID - Slot number
+**
+** Returns:
+** CKR_SLOT_ID_INVALID if slotID is invalid
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_PublicMode(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session_l;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ st.slots[slotID - 1].pin_state = 0; /* Fixme: create #define for this */
+
+ session_l = st.sessions;
+ while (session_l)
+ {
+ if (session_l->session.slotID == slotID)
+ {
+ switch (session_l->session.state)
+ {
+ case CKS_RO_USER_FUNCTIONS:
+ session_l->session.state = CKS_RO_PUBLIC_SESSION;
+ break;
+ case CKS_RW_USER_FUNCTIONS:
+ session_l->session.state = CKS_RW_PUBLIC_SESSION;
+ break;
+ case CKS_RW_SO_FUNCTIONS: /* Fixme: can't really handle this one well */
+ session_l->session.state = CKS_RO_PUBLIC_SESSION;
+ break;
+ default:
+ break;
+ }
+
+ session_l->session.flags = (session_l->session.flags & ~CKF_RW_SESSION);
+ }
+
+ session_l = session_l->next;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_UserMode
+**
+** Switchs all sessions of a slot to USER mode (versus PUBLIC or SO mode)
+**
+** Parameters:
+** slotID - Slot number
+**
+** Returns:
+** CKR_SLOT_ID_INVALID if slotID is invalid
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_UserMode(CK_ULONG slotID)
+{
+ CK_RV rv = CKR_OK;
+ P11_Session *session_l;
+
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else
+ {
+ st.slots[slotID - 1].pin_state = 1; /* Fixme: create #define for this */
+
+ session_l = st.sessions;
+ while (session_l)
+ {
+ if (session_l->session.slotID == slotID)
+ {
+ switch (session_l->session.state)
+ {
+ case CKS_RO_PUBLIC_SESSION:
+ object_UserMode((CK_SESSION_HANDLE)session_l);
+ session_l->session.state = CKS_RO_USER_FUNCTIONS;
+ break;
+ case CKS_RW_PUBLIC_SESSION:
+ object_UserMode((CK_SESSION_HANDLE)session_l);
+ session_l->session.state = CKS_RW_USER_FUNCTIONS;
+ break;
+ default:
+ break;
+ }
+
+ session_l->session.flags = (session_l->session.flags | CKF_RW_SESSION);
+ }
+
+ session_l = session_l->next;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_TokenPresent
+**
+** Checks if a token is present in a slot
+**
+** Parameters:
+** slotID - Slot number to check
+**
+** Returns:
+** CKR_SLOT_ID_INVALID if slotID is invalid
+** CKR_TOKEN_NOT_PRESENT or CKR_TOKEN_NOT_RECOGNIZED
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_TokenPresent(CK_ULONG slotID)
+{
+ CK_RV rv;
+
+ /* Fixme: Use the MSC tests */
+ if (INVALID_SLOT)
+ rv = CKR_SLOT_ID_INVALID;
+ else if (strcmp(st.slots[slotID - 1].conn.tokenInfo.tokenName, MSC_TOKEN_EMPTY_STR) == 0)
+ rv = CKR_TOKEN_NOT_PRESENT;
+ else if (strcmp(st.slots[slotID - 1].conn.tokenInfo.tokenName, MSC_TOKEN_UNKNOWN_STR) == 0)
+ rv = CKR_TOKEN_NOT_RECOGNIZED;
+ else
+ rv = CKR_OK;
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_TokenChanged
+**
+** Master routine that checks the status of a token. This calls
+** slot_UpdateToken and slot_UpdateMechanisms to update information about the
+** current token. If a token status has not changed then this function does
+** not do anything.
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_CRYPTOKI_NOT_INITIALIZED
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_TokenChanged()
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i;
+ P11_Session *sess;
+
+ sess = st.sessions;
+ log_Log(LOG_LOW, "Active session list:");
+ while (sess)
+ {
+ log_Log(LOG_LOW, "Session ID: %X", sess);
+ sess = sess->next;
+ }
+
+ if (!st.initialized)
+ rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+ else if (!st.slot_status || !st.slots)
+ rv = CKR_FUNCTION_FAILED;
+ else
+ for (i = 0; i < st.slot_count; i++)
+ {
+ if (!st.prefs.threaded && !(st.slots[i].slot_info.flags & CKF_TOKEN_PRESENT))
+ {
+ slot_UpdateSlot(i + 1);
+ if ((st.slots[i].slot_info.flags & CKF_TOKEN_PRESENT))
+ st.slot_status[i] = 0x01;
+ }
+
+ /* Old code, may still be useful; handles reset differently
+ if (st.slot_status[i] || (st.slots[i].conn.hCard &&
+ (msc_IsTokenReset(&st.slots[i].conn) || msc_IsTokenMoved(&st.slots[i].conn))))
+ */
+
+ if (st.slot_status[i] || (st.slots[i].conn.hCard &&
+ msc_IsTokenMoved(&st.slots[i].conn)))
+ {
+ if (st.slots[i].conn.hCard)
+ msc_ClearReset(&st.slots[i].conn);
+
+ log_Log(LOG_LOW, "Slot %d changed", i + 1);
+
+ slot_DisconnectSlot(i + 1, MSC_RESET_TOKEN);
+ slot_UpdateSlot(i + 1);
+
+ if (!CKR_ERROR(slot_BeginTransaction(i + 1)))
+ {
+ (void)CKR_ERROR(slot_UpdateToken(i + 1));
+ (void)CKR_ERROR(slot_UpdateMechanisms(i + 1));
+ (void)CKR_ERROR(slot_EndTransaction(i + 1, MSC_LEAVE_TOKEN));
+ }
+
+ st.slot_status[i] = 0x00;
+
+ if (st.slots[i].conn.hCard)
+ rv = CKR_DEVICE_REMOVED;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: slot_BlankTokenInfo
+**
+** Sets a CK_TOKEN_INFO structure to blank data
+**
+** Parameters:
+** token_info - Structure to blank
+**
+** Returns:
+** none
+*******************************************************************************/
+void slot_BlankTokenInfo(CK_TOKEN_INFO *token_info)
+{
+ memset(token_info, 0x00, sizeof(MSCTokenInfo));
+
+ util_PadStrSet(token_info->label, (CK_CHAR *)"", sizeof(token_info->label));
+ util_PadStrSet(token_info->manufacturerID, (CK_CHAR *)"", sizeof(token_info->manufacturerID));
+ util_PadStrSet(token_info->model, (CK_CHAR *)"", sizeof(token_info->model));
+ util_PadStrSet(token_info->serialNumber, (CK_CHAR *)"", sizeof(token_info->serialNumber));
+ memset(token_info->utcTime, '0', sizeof(token_info->utcTime));
+}
+
+/******************************************************************************
+** Function: slot_ReverifyPins()
+**
+** Reverifies cached PIN's. If any cached PIN fails to verify then this will
+** kill that PIN so that it won't be used again. This is to prevent the
+** caching mechanism from inadvertantly locking a token.
+**
+** Parameters:
+** none
+**
+** Returns:
+** Error from slot_VerifyPIN
+** CKR_OK
+*******************************************************************************/
+CK_RV slot_ReverifyPins()
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i;
+
+ log_Log(LOG_LOW, "Reverifying all cached PIN's");
+
+ for (i = 0; i < st.slot_count; i++)
+ {
+ if (st.slots[i].conn.hCard && msc_IsTokenReset(&st.slots[i].conn))
+ {
+ msc_ClearReset(&st.slots[i].conn);
+
+ if (st.slots[i].pins[CKU_SO].pin_size)
+ rv = slot_VerifyPIN(i + 1,
+ CKU_SO,
+ st.slots[i].pins[CKU_SO].pin,
+ st.slots[i].pins[CKU_SO].pin_size);
+
+ if (CKR_ERROR(rv))
+ {
+ st.slots[i].pins[CKU_SO].pin_size = 0;
+ memset(st.slots[i].pins[CKU_SO].pin, 0x00, sizeof(st.slots[i].pins[CKU_SO].pin));
+ }
+ else if (st.slots[i].pins[CKU_USER].pin_size)
+ {
+ rv = slot_VerifyPIN(i + 1,
+ CKU_USER,
+ st.slots[i].pins[CKU_USER].pin,
+ st.slots[i].pins[CKU_USER].pin_size);
+
+ if (CKR_ERROR(rv))
+ {
+ st.slots[i].pins[CKU_USER].pin_size = 0;
+ memset(st.slots[i].pins[CKU_USER].pin, 0x00, sizeof(st.slots[i].pins[CKU_USER].pin));
+ }
+ else
+ slot_UserMode(i + 1);
+ }
+ }
+ }
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_state.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_state.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_state.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,108 @@
+/******************************************************************************
+**
+** $Id: p11x_state.c,v 1.2 2003/02/13 20:06:42 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Global state functions
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+/* Global state variable */
+P11_State st = { 0, /* initialized */
+ { 0, /* prefs.multi_app */
+ 0, /* prefs.threaded */
+ LOG_HIGH, /* prefs.log_level */
+ P11_OBJ_SORT_NEWEST_FIRST, /* prefs.obj_sort_order */
+ P11_SLOT_WATCH_THREAD_FULL, /* prefs.slot_watch_scheme */
+ 0, /* prefs.cache_pin */
+ PKCS11_MAJOR, /* prefs.version_major */
+ PKCS11_MINOR, /* prefs.version_minor */
+ PKCS11_MAX_PIN_TRIES, /* prefs.max_pin_tries */
+ PKCS11_SO_USER_PIN, /* prefs.so_user_pin_num */
+ PKCS11_USER_PIN, /* prefs.user_pin_num */
+ P11_DEFAULT_CERT_ATTRIB_OBJ_SIZE, /* prefs.cert_attrib_size */
+ P11_DEFAULT_ATTRIB_OBJ_SIZE, /* prefs.pubkey_attrib_size*/
+ P11_DEFAULT_PRK_ATTRIB_OBJ_SIZE, /* prefs.prvkey_attrib_size*/
+ P11_DEFAULT_ATTRIB_OBJ_SIZE, /* prefs.data_attrib_size */
+ 0, /* prefs.disable_security */
+ P11_DEFAULT_LOG_FILENAME }, /* prefs.log_filename */
+ 0, /* slots */
+ 0, /* slot_count */
+ 0, /* sessions */
+ 0, /* slot_status */
+ 0, /* log_lock */
+ 0, /* async_lock */
+ 0, /* native_locks */
+ 0 /* create_threads */
+ };
+
+/******************************************************************************
+** Function: state_Init
+**
+** Initializes global state. Read preferences via util_ReadPreferences
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_HOST_MEMORY if memory alloc fails
+** CKR_OK
+*******************************************************************************/
+CK_RV state_Init()
+{
+ CK_RV rv = CKR_OK;
+
+ if (!st.initialized)
+ util_ReadPreferences();
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: state_Free
+**
+** Frees the global state information
+**
+** Parameters:
+** none
+**
+** Returns:
+** Error from slot_FreeAllSlots (not checked and everything gets blasted)
+** CKR_OK
+*******************************************************************************/
+CK_RV state_Free()
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.initialized)
+ {
+ rv = slot_FreeAllSlots();
+
+ if (st.log_lock)
+ {
+ thread_MutexDestroy(st.log_lock);
+ free(st.log_lock);
+ st.log_lock = 0;
+ }
+
+ if (st.async_lock)
+ {
+ thread_MutexDestroy(st.async_lock);
+ free(st.async_lock);
+ st.async_lock = 0;
+ }
+
+ if (st.prefs.threaded)
+ thread_Finalize();
+
+ st.initialized = 0;
+ }
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_thread.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_thread.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_thread.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,256 @@
+/******************************************************************************
+**
+** $Id: p11x_thread.c,v 1.2 2003/02/13 20:06:42 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Thread functions. This should probably just use the Musclecard
+** framework functions instead (if in native mode).
+**
+******************************************************************************/
+
+#include "cryptoki.h"
+
+#include "thread_generic.h"
+
+static int (*p11_pthread_mutex_init)(PCSCLITE_MUTEX_T mMutex) = 0;
+static int (*p11_pthread_mutex_destroy)(PCSCLITE_MUTEX_T mMutex) = 0;
+static int (*p11_pthread_mutex_lock)(PCSCLITE_MUTEX_T mMutex) = 0;
+static int (*p11_pthread_mutex_unlock)(PCSCLITE_MUTEX_T mMutex) = 0;
+
+static CK_CREATEMUTEX p11_createmutex = 0;
+static CK_DESTROYMUTEX p11_destroymutex = 0;
+static CK_LOCKMUTEX p11_lockmutex = 0;
+static CK_UNLOCKMUTEX p11_unlockmutex = 0;
+
+/******************************************************************************
+** Function: thread_Initialize
+**
+** Initializes the thread subsystem
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_FUNCTION_FAILED on error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_Initialize()
+{
+ CK_RV rv = CKR_OK;
+
+#ifdef HAVE_LIBPTHREAD
+ if (st.prefs.threaded && st.native_locks)
+ {
+ p11_pthread_mutex_init = SYS_MutexInit;
+ p11_pthread_mutex_destroy = SYS_MutexDestroy;
+ p11_pthread_mutex_lock = SYS_MutexLock;
+ p11_pthread_mutex_unlock = SYS_MutexUnLock;
+ }
+#else
+ P11_ERR("Trying to initialize thread subsystem while threads are disabled");
+ rv = CKR_FUNCTION_FAILED;
+#endif
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: thread_InitFunctions
+**
+** Initializes the thread subsystem to use external locking mechanisms
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_ARGUMENTS_BAD if any function is null
+** CKR_FUNCTION_FAILED on error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_InitFunctions(CK_CREATEMUTEX fn_createmutex,
+ CK_DESTROYMUTEX fn_destroymutex,
+ CK_LOCKMUTEX fn_lockmutex,
+ CK_UNLOCKMUTEX fn_unlockmutex)
+{
+ CK_RV rv = CKR_OK;
+
+ if (!st.prefs.threaded)
+ rv = CKR_FUNCTION_FAILED;
+ else
+ {
+ if (!fn_createmutex || !fn_destroymutex || !fn_lockmutex || !fn_unlockmutex)
+ rv = CKR_ARGUMENTS_BAD;
+ else
+ {
+ log_Log(LOG_LOW, "Using application supplied locking functions");
+ p11_createmutex = fn_createmutex;
+ p11_destroymutex = fn_destroymutex;
+ p11_lockmutex = fn_lockmutex;
+ p11_unlockmutex = fn_unlockmutex;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: thread_Finalize
+**
+** Unloads the Pthread library
+**
+** Parameters:
+** none
+**
+** Returns:
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_Finalize()
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.threaded)
+ {
+ p11_pthread_mutex_init = 0;
+ p11_pthread_mutex_destroy = 0;
+ p11_pthread_mutex_lock = 0;
+ p11_pthread_mutex_unlock = 0;
+ p11_createmutex = 0;
+ p11_destroymutex = 0;
+ p11_lockmutex = 0;
+ p11_unlockmutex = 0;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: thread_MutexInit
+**
+** Initializes a mutex
+**
+** Parameters:
+** mutex - Pointer to mutex memory
+**
+** Returns:
+** CKR_HOST_MEMORY on memory alloc error
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_MutexInit(P11_Mutex *mutex)
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.threaded)
+ {
+ if (st.native_locks && mutex && p11_pthread_mutex_init)
+ {
+ *mutex = (P11_Mutex *)malloc(sizeof(PCSCLITE_MUTEX));
+
+ if (!*mutex)
+ rv = CKR_HOST_MEMORY;
+ else
+ p11_pthread_mutex_init((PCSCLITE_MUTEX_T)*mutex);
+ }
+ else if (!st.native_locks && mutex && p11_createmutex)
+ p11_createmutex(mutex);
+ else
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: thread_MutexDestroy
+**
+** Destroys a mutex
+**
+** Parameters:
+** mutex - Pointer to mutex memory
+**
+** Returns:
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_MutexDestroy(P11_Mutex mutex)
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.threaded)
+ {
+ if (st.native_locks && mutex && p11_pthread_mutex_destroy)
+ {
+ p11_pthread_mutex_destroy((PCSCLITE_MUTEX_T)mutex);
+ free(mutex);
+ }
+ else if (!st.native_locks && mutex && p11_destroymutex)
+ p11_destroymutex(mutex);
+ else
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: thread_MutexLock
+**
+** Locks a mutex
+**
+** Parameters:
+** mutex - Pointer to mutex memory
+**
+** Returns:
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_MutexLock(P11_Mutex mutex)
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.threaded)
+ {
+ if (st.native_locks && mutex && p11_pthread_mutex_lock)
+ p11_pthread_mutex_lock((PCSCLITE_MUTEX_T)mutex);
+ else if (!st.native_locks && mutex && p11_lockmutex)
+ p11_lockmutex(mutex);
+ else
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: thread_MutexUnlock
+**
+** Unlocks a mutex
+**
+** Parameters:
+** mutex - Pointer to mutex memory
+**
+** Returns:
+** CKR_FUNCTION_FAILED on general error
+** CKR_OK
+*******************************************************************************/
+CK_RV thread_MutexUnlock(P11_Mutex mutex)
+{
+ CK_RV rv = CKR_OK;
+
+ if (st.prefs.threaded)
+ {
+ if (st.native_locks && mutex && p11_pthread_mutex_unlock)
+ p11_pthread_mutex_unlock((PCSCLITE_MUTEX_T)mutex);
+ else if (!st.native_locks && mutex && p11_unlockmutex)
+ p11_unlockmutex(mutex);
+ else
+ rv = CKR_FUNCTION_FAILED;
+ }
+
+ return rv;
+}
+
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_unixdll.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_unixdll.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_unixdll.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,24 @@
+/******************************************************************************
+**
+** $Id: p11x_unixdll.c,v 1.2 2003/02/13 20:06:42 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Support for Linux (maybe others) shared library unloading.
+** This will automatically get called by the runtime system when the
+** library is finalized (just in case the application hasn't closed
+** everything down).
+**
+******************************************************************************/
+#ifdef __USE_FINI__
+
+#include "cryptoki.h"
+
+void _fini()
+{
+ C_Finalize(0);
+}
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_util.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_util.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_util.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,175 @@
+/******************************************************************************
+**
+** $Id: p11x_util.c,v 1.2 2003/02/13 20:06:42 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Utility functions
+**
+******************************************************************************/
+
+#include <stdio.h>
+#include "cryptoki.h"
+
+/******************************************************************************
+** Function: util_byterev
+**
+** Reverses a byte string in-place
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+void util_byterev(CK_BYTE *data, CK_ULONG len)
+{
+ CK_ULONG i;
+ CK_BYTE temp;
+
+ for (i = 0; i < len / 2; i++)
+ {
+ temp = data[i];
+ data[i] = data[len - i - 1];
+ data[len - i - 1] = temp;
+ }
+}
+
+/******************************************************************************
+** Function: util_strpadlen
+**
+** Find length of string that has been padded with spaces
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_ULONG util_strpadlen(CK_CHAR *string, CK_ULONG max_len)
+{
+ CK_ULONG i;
+
+ for (i = max_len; i > 0; i--)
+ {
+ if (string[i - 1] != 0x20)
+ break;
+ }
+
+ return (i);
+}
+
+/******************************************************************************
+** Function: util_PadStrSet
+**
+** Pads a string with spaces (of size length), then sets the value to a null
+** terminated string.
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV util_PadStrSet(CK_CHAR *string, CK_CHAR *value, CK_ULONG size)
+{
+ memset(string, 0x20, size);
+ memcpy((char *)string, value, strnlen((char *)value, size));
+
+ return CKR_OK;
+}
+
+/******************************************************************************
+** Function: util_StripPKCS1
+**
+** Strips PKCS #1 padding
+**
+** Note that this function strips the data in-place so the original information
+** is lost.
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+CK_RV util_StripPKCS1(CK_BYTE *data, CK_ULONG len, CK_BYTE *output, CK_ULONG *out_len)
+{
+ CK_RV rv = CKR_OK;
+ CK_ULONG i, pos, tag;
+
+ pos = tag = 0;
+
+ for (i = 0; i < len; i++)
+ {
+ if (data[i] == 0x02)
+ tag = 1;
+ else if (tag && !data[i] && (i+1 < len))
+ {
+ pos = i + 1;
+ break;
+ }
+ }
+
+ if (!pos)
+ rv = CKR_FUNCTION_FAILED;
+ else
+ {
+ len -= pos;
+
+ if (len > *out_len)
+ rv = CKR_BUFFER_TOO_SMALL;
+ else
+ {
+ memcpy(output, &data[pos], len);
+ *out_len = len;
+ }
+ }
+
+ return rv;
+}
+
+/******************************************************************************
+** Function: strnlen
+**
+** Limited length strlen function (normally included with GNU compiler)
+**
+** Parameters:
+** none
+**
+** Returns:
+** none
+*******************************************************************************/
+#ifndef __USE_GNU
+#ifndef WIN32
+size_t strnlen(__const char *__string, size_t __maxlen)
+#else
+size_t strnlen(const char *__string, size_t __maxlen)
+#endif
+{
+ size_t i;
+
+ for (i = 0; i < __maxlen; i++)
+ if (__string[i] == 0x00) break;
+
+ return i;
+}
+#endif
+
+/******************************************************************************
+** Function: util_IsLittleEndian
+**
+** Parameters:
+** none
+**
+** Returns:
+** True/False if machine is little endian or not
+*******************************************************************************/
+CK_BBOOL util_IsLittleEndian()
+{
+ CK_ULONG rv = 1;
+
+ return ((char *)&rv)[0];
+}
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_win32dll.c
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_win32dll.c (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/p11x_win32dll.c 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,53 @@
+/******************************************************************************
+**
+** $Id: p11x_win32dll.c,v 1.2 2003/02/13 20:06:42 ghoo Exp $
+**
+** Package: PKCS-11
+** Author : Chris Osgood <oznet at mac.com>
+** License: Copyright (C) 2002 Schlumberger Network Solutions
+** <http://www.slb.com/sns>
+** Purpose: Support for WIN32 DLL's
+**
+******************************************************************************/
+#ifdef WIN32
+
+#include "cryptoki.h"
+
+/******************************************************************************
+** Function: DllMain
+**
+** Required entry point for WIN32 DLL's
+**
+** Parameters:
+** hModule -
+** ul_reason_for_call -
+** lpReserved -
+**
+** Returns:
+** TRUE
+*******************************************************************************/
+BOOL APIENTRY DllMain( HANDLE hModule,
+ DWORD ul_reason_for_call,
+ LPVOID lpReserved
+ )
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ log_Log(LOG_LOW, "WIN32DLL: Process attach");
+ break;
+ case DLL_THREAD_ATTACH:
+ log_Log(LOG_LOW, "WIN32DLL: Thread attach");
+ break;
+ case DLL_THREAD_DETACH:
+ log_Log(LOG_LOW, "WIN32DLL: Thread detach");
+ break;
+ case DLL_PROCESS_DETACH:
+ log_Log(LOG_LOW, "WIN32DLL: Process detach");
+ C_Finalize(0);
+ break;
+ }
+ return TRUE;
+}
+
+#endif /* WIN32 */
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/* pkcs11.h include file for PKCS #11. 2001 June 25 */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 6 platform-specific macros must be defined. These
+ * macros are described below, and typical definitions for them
+ * are also given. Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 6 macros, the packing convention
+ * for Cryptoki structures should be set. The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this. You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object. It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
+ * an exportable Cryptoki library function definition out of a
+ * return type and a function name. It should be used in the
+ * following fashion to define the exposed Cryptoki functions in
+ * a Cryptoki library:
+ *
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * )
+ * {
+ * ...
+ * }
+ *
+ * If you're using Microsoft Developer Studio 5.0 to define a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllexport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to define a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name. It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name. It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV. It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h. */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y) x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points. That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points. A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library. This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(CK_,name) name;
+
+struct CK_FUNCTION_LIST {
+
+ CK_VERSION version; /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11f.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11f.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11f.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,915 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/* pkcs11f.h include file for PKCS #11. 2001 June 25 */
+
+/* This function contains pretty much everything about all the */
+/* Cryptoki function prototypes. Because this information is */
+/* used for more than just declaring function prototypes, the */
+/* order of the functions appearing herein is important, and */
+/* should not be altered. */
+
+
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
+ * cast to CK_C_INITIALIZE_ARGS_PTR
+ * and dereferenced */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_INFO_PTR pInfo /* location that receives information */
+);
+#endif
+
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
+ * function list */
+);
+#endif
+
+
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_BBOOL tokenPresent, /* only slots with tokens? */
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives number of slots */
+);
+#endif
+
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+);
+#endif
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+);
+#endif
+
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
+ CK_ULONG_PTR pulCount /* gets # of mechs. */
+);
+#endif
+
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* from CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* passed to callback */
+ CK_NOTIFY Notify, /* callback function */
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* gets state */
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session. */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* holds state */
+ CK_ULONG ulOperationStateLen, /* holds state length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy. */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes. */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
+ CK_ULONG ulMaxObjectCount, /* max handles to get */
+ CK_ULONG_PTR pulObjectCount /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext */
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext data len */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
+ CK_BYTE_PTR pData, /* gets plaintext */
+ CK_ULONG_PTR pulDataLen /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* input length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* gets plaintext */
+ CK_ULONG_PTR pulLastPartLen /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to digest */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested. */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ *signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data to sign */
+ CK_ULONG ulPartLen /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ * cannot be recovered from the signature (e.g. DSA). */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* signed data */
+ CK_ULONG ulDataLen, /* length of signed data */
+ CK_BYTE_PTR pSignature, /* signature */
+ CK_ULONG ulSignatureLen /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* signed data */
+ CK_ULONG ulPartLen /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen, /* signature length */
+ CK_BYTE_PTR pData, /* gets signed data */
+ CK_ULONG_PTR pulDataLen /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
+ CK_ULONG ulCount, /* # of attrs in template */
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session
+ * handle */
+ CK_MECHANISM_PTR pMechanism, /* key-gen
+ * mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
+ * for pub.
+ * key */
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
+ * attrs. */
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
+ * for priv.
+ * key */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
+ * attrs. */
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
+ * key
+ * handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
+ * priv. key
+ * handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object. */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
+ CK_OBJECT_HANDLE hBaseKey, /* base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator. */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel. */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+
+/* Functions added in for Cryptoki Version 2.01 or later */
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+);
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11t.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11t.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/pkcs11t.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,1351 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/* pkcs11t.h include file for PKCS #11. 2001 June 25 */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file. */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
+typedef void CK_PTR CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+ CK_BYTE minor; /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+
+ /* libraryDescription and libraryVersion are new for v2.0 */
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
+ CK_VERSION libraryVersion; /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0
+
+
+typedef CK_ULONG CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+ /* slotDescription and manufacturerID have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags;
+
+ /* hardwareVersion and firmwareVersion are new for v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
+#define CKF_HW_SLOT 0x00000004 /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR label[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR model[16]; /* blank padded */
+ CK_CHAR serialNumber[16]; /* blank padded */
+ CK_FLAGS flags; /* see below */
+
+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+ * changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulMaxSessionCount; /* max open sessions */
+ CK_ULONG ulSessionCount; /* sess. now open */
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
+ CK_ULONG ulMaxPinLen; /* in bytes */
+ CK_ULONG ulMinPinLen; /* in bytes */
+ CK_ULONG ulTotalPublicMemory; /* in bytes */
+ CK_ULONG ulFreePublicMemory; /* in bytes */
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
+ CK_ULONG ulFreePrivateMemory; /* in bytes */
+
+ /* hardwareVersion, firmwareVersion, and time are new for
+ * v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+ CK_CHAR utcTime[16]; /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001 /* has random #
+ * generator */
+#define CKF_WRITE_PROTECTED 0x00000002 /* token is
+ * write-
+ * protected */
+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
+ * login */
+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
+ * PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
+ * that the token has some sort of clock. The time on that
+ * clock is returned in the token info structure */
+#define CKF_CLOCK_ON_TOKEN 0x00000040
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
+
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED 0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED 0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0
+/* Normal user */
+#define CKU_USER 1
+
+
+/* CK_STATE enumerates the session states */
+/* CK_STATE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0
+#define CKS_RO_USER_FUNCTIONS 1
+#define CKS_RW_PUBLIC_SESSION 2
+#define CKS_RW_USER_FUNCTIONS 3
+#define CKS_RW_SO_FUNCTIONS 4
+
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+
+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002 /* session is r/w */
+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes. It is defined
+ * as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+#define CKO_HW_FEATURE 0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_VENDOR_DEFINED 0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+#define CKH_MONOTONIC_COUNTER 0x00000001
+#define CKH_CLOCK 0x00000002
+#define CKH_VENDOR_DEFINED 0x80000000
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000
+#define CKK_DSA 0x00000001
+#define CKK_DH 0x00000002
+
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+#define CKK_ECDSA 0x00000003
+#define CKK_EC 0x00000003
+#define CKK_X9_42_DH 0x00000004
+#define CKK_KEA 0x00000005
+
+#define CKK_GENERIC_SECRET 0x00000010
+#define CKK_RC2 0x00000011
+#define CKK_RC4 0x00000012
+#define CKK_DES 0x00000013
+#define CKK_DES2 0x00000014
+#define CKK_DES3 0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST 0x00000016
+#define CKK_CAST3 0x00000017
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+#define CKK_CAST5 0x00000018
+#define CKK_CAST128 0x00000018
+#define CKK_RC5 0x00000019
+#define CKK_IDEA 0x0000001A
+#define CKK_SKIPJACK 0x0000001B
+#define CKK_BATON 0x0000001C
+#define CKK_JUNIPER 0x0000001D
+#define CKK_CDMF 0x0000001E
+#define CKK_AES 0x0000001F
+
+#define CKK_VENDOR_DEFINED 0x80000000
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
+#define CKC_X_509 0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_VENDOR_DEFINED 0x80000000
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000
+#define CKA_TOKEN 0x00000001
+#define CKA_PRIVATE 0x00000002
+#define CKA_LABEL 0x00000003
+#define CKA_APPLICATION 0x00000010
+#define CKA_VALUE 0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID 0x00000012
+
+#define CKA_CERTIFICATE_TYPE 0x00000080
+#define CKA_ISSUER 0x00000081
+#define CKA_SERIAL_NUMBER 0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+ * for v2.10 */
+#define CKA_AC_ISSUER 0x00000083
+#define CKA_OWNER 0x00000084
+#define CKA_ATTR_TYPES 0x00000085
+
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED 0x00000086
+
+#define CKA_KEY_TYPE 0x00000100
+#define CKA_SUBJECT 0x00000101
+#define CKA_ID 0x00000102
+#define CKA_SENSITIVE 0x00000103
+#define CKA_ENCRYPT 0x00000104
+#define CKA_DECRYPT 0x00000105
+#define CKA_WRAP 0x00000106
+#define CKA_UNWRAP 0x00000107
+#define CKA_SIGN 0x00000108
+#define CKA_SIGN_RECOVER 0x00000109
+#define CKA_VERIFY 0x0000010A
+#define CKA_VERIFY_RECOVER 0x0000010B
+#define CKA_DERIVE 0x0000010C
+#define CKA_START_DATE 0x00000110
+#define CKA_END_DATE 0x00000111
+#define CKA_MODULUS 0x00000120
+#define CKA_MODULUS_BITS 0x00000121
+#define CKA_PUBLIC_EXPONENT 0x00000122
+#define CKA_PRIVATE_EXPONENT 0x00000123
+#define CKA_PRIME_1 0x00000124
+#define CKA_PRIME_2 0x00000125
+#define CKA_EXPONENT_1 0x00000126
+#define CKA_EXPONENT_2 0x00000127
+#define CKA_COEFFICIENT 0x00000128
+#define CKA_PRIME 0x00000130
+#define CKA_SUBPRIME 0x00000131
+#define CKA_BASE 0x00000132
+
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS 0x00000133
+#define CKA_SUB_PRIME_BITS 0x00000134
+
+#define CKA_VALUE_BITS 0x00000160
+#define CKA_VALUE_LEN 0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
+#define CKA_EXTRACTABLE 0x00000162
+#define CKA_LOCAL 0x00000163
+#define CKA_NEVER_EXTRACTABLE 0x00000164
+#define CKA_ALWAYS_SENSITIVE 0x00000165
+
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM 0x00000166
+
+#define CKA_MODIFIABLE 0x00000170
+
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
+ * CKA_EC_PARAMS is preferred. */
+#define CKA_ECDSA_PARAMS 0x00000180
+#define CKA_EC_PARAMS 0x00000180
+
+#define CKA_EC_POINT 0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_SECONDARY_AUTH 0x00000200
+#define CKA_AUTH_PIN_FLAGS 0x00000201
+#define CKA_HW_FEATURE_TYPE 0x00000300
+#define CKA_RESET_ON_INIT 0x00000301
+#define CKA_HAS_RESET 0x00000302
+
+#define CKA_VENDOR_DEFINED 0x80000000
+
+
+/* CK_ATTRIBUTE is a structure that includes the type, length
+ * and value of an attribute */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+
+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
+#define CKM_RSA_PKCS 0x00000001
+#define CKM_RSA_9796 0x00000002
+#define CKM_RSA_X_509 0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+ * are new for v2.0. They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS 0x00000004
+#define CKM_MD5_RSA_PKCS 0x00000005
+#define CKM_SHA1_RSA_PKCS 0x00000006
+
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
+#define CKM_RSA_PKCS_OAEP 0x00000009
+
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
+#define CKM_RSA_X9_31 0x0000000B
+#define CKM_SHA1_RSA_X9_31 0x0000000C
+#define CKM_RSA_PKCS_PSS 0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
+#define CKM_DSA 0x00000011
+#define CKM_DSA_SHA1 0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
+#define CKM_DH_PKCS_DERIVE 0x00000021
+
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+ * v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
+#define CKM_X9_42_DH_DERIVE 0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
+#define CKM_X9_42_MQV_DERIVE 0x00000033
+
+#define CKM_RC2_KEY_GEN 0x00000100
+#define CKM_RC2_ECB 0x00000101
+#define CKM_RC2_CBC 0x00000102
+#define CKM_RC2_MAC 0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+#define CKM_RC2_MAC_GENERAL 0x00000104
+#define CKM_RC2_CBC_PAD 0x00000105
+
+#define CKM_RC4_KEY_GEN 0x00000110
+#define CKM_RC4 0x00000111
+#define CKM_DES_KEY_GEN 0x00000120
+#define CKM_DES_ECB 0x00000121
+#define CKM_DES_CBC 0x00000122
+#define CKM_DES_MAC 0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+#define CKM_DES_MAC_GENERAL 0x00000124
+#define CKM_DES_CBC_PAD 0x00000125
+
+#define CKM_DES2_KEY_GEN 0x00000130
+#define CKM_DES3_KEY_GEN 0x00000131
+#define CKM_DES3_ECB 0x00000132
+#define CKM_DES3_CBC 0x00000133
+#define CKM_DES3_MAC 0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+#define CKM_DES3_MAC_GENERAL 0x00000135
+#define CKM_DES3_CBC_PAD 0x00000136
+#define CKM_CDMF_KEY_GEN 0x00000140
+#define CKM_CDMF_ECB 0x00000141
+#define CKM_CDMF_CBC 0x00000142
+#define CKM_CDMF_MAC 0x00000143
+#define CKM_CDMF_MAC_GENERAL 0x00000144
+#define CKM_CDMF_CBC_PAD 0x00000145
+
+#define CKM_MD2 0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD2_HMAC 0x00000201
+#define CKM_MD2_HMAC_GENERAL 0x00000202
+
+#define CKM_MD5 0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD5_HMAC 0x00000211
+#define CKM_MD5_HMAC_GENERAL 0x00000212
+
+#define CKM_SHA_1 0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+#define CKM_SHA_1_HMAC 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128 0x00000230
+#define CKM_RIPEMD128_HMAC 0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
+#define CKM_RIPEMD160 0x00000240
+#define CKM_RIPEMD160_HMAC 0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
+
+/* All of the following mechanisms are new for v2.0 */
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST_KEY_GEN 0x00000300
+#define CKM_CAST_ECB 0x00000301
+#define CKM_CAST_CBC 0x00000302
+#define CKM_CAST_MAC 0x00000303
+#define CKM_CAST_MAC_GENERAL 0x00000304
+#define CKM_CAST_CBC_PAD 0x00000305
+#define CKM_CAST3_KEY_GEN 0x00000310
+#define CKM_CAST3_ECB 0x00000311
+#define CKM_CAST3_CBC 0x00000312
+#define CKM_CAST3_MAC 0x00000313
+#define CKM_CAST3_MAC_GENERAL 0x00000314
+#define CKM_CAST3_CBC_PAD 0x00000315
+#define CKM_CAST5_KEY_GEN 0x00000320
+#define CKM_CAST128_KEY_GEN 0x00000320
+#define CKM_CAST5_ECB 0x00000321
+#define CKM_CAST128_ECB 0x00000321
+#define CKM_CAST5_CBC 0x00000322
+#define CKM_CAST128_CBC 0x00000322
+#define CKM_CAST5_MAC 0x00000323
+#define CKM_CAST128_MAC 0x00000323
+#define CKM_CAST5_MAC_GENERAL 0x00000324
+#define CKM_CAST128_MAC_GENERAL 0x00000324
+#define CKM_CAST5_CBC_PAD 0x00000325
+#define CKM_CAST128_CBC_PAD 0x00000325
+#define CKM_RC5_KEY_GEN 0x00000330
+#define CKM_RC5_ECB 0x00000331
+#define CKM_RC5_CBC 0x00000332
+#define CKM_RC5_MAC 0x00000333
+#define CKM_RC5_MAC_GENERAL 0x00000334
+#define CKM_RC5_CBC_PAD 0x00000335
+#define CKM_IDEA_KEY_GEN 0x00000340
+#define CKM_IDEA_ECB 0x00000341
+#define CKM_IDEA_CBC 0x00000342
+#define CKM_IDEA_MAC 0x00000343
+#define CKM_IDEA_MAC_GENERAL 0x00000344
+#define CKM_IDEA_CBC_PAD 0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
+#define CKM_XOR_BASE_AND_DATA 0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+
+#define CKM_SSL3_MD5_MAC 0x00000380
+#define CKM_SSL3_SHA1_MAC 0x00000381
+#define CKM_MD5_KEY_DERIVATION 0x00000390
+#define CKM_MD2_KEY_DERIVATION 0x00000391
+#define CKM_SHA1_KEY_DERIVATION 0x00000392
+#define CKM_PBE_MD2_DES_CBC 0x000003A0
+#define CKM_PBE_MD5_DES_CBC 0x000003A1
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
+#define CKM_PBE_SHA1_RC4_128 0x000003A6
+#define CKM_PBE_SHA1_RC4_40 0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2 0x000003B0
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+#define CKM_KEY_WRAP_LYNKS 0x00000400
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN 0x00001000
+#define CKM_SKIPJACK_ECB64 0x00001001
+#define CKM_SKIPJACK_CBC64 0x00001002
+#define CKM_SKIPJACK_OFB64 0x00001003
+#define CKM_SKIPJACK_CFB64 0x00001004
+#define CKM_SKIPJACK_CFB32 0x00001005
+#define CKM_SKIPJACK_CFB16 0x00001006
+#define CKM_SKIPJACK_CFB8 0x00001007
+#define CKM_SKIPJACK_WRAP 0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
+#define CKM_SKIPJACK_RELAYX 0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
+#define CKM_KEA_KEY_DERIVE 0x00001011
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
+#define CKM_BATON_KEY_GEN 0x00001030
+#define CKM_BATON_ECB128 0x00001031
+#define CKM_BATON_ECB96 0x00001032
+#define CKM_BATON_CBC128 0x00001033
+#define CKM_BATON_COUNTER 0x00001034
+#define CKM_BATON_SHUFFLE 0x00001035
+#define CKM_BATON_WRAP 0x00001036
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred */
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
+
+#define CKM_ECDSA 0x00001041
+#define CKM_ECDSA_SHA1 0x00001042
+
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+ * are new for v2.11 */
+#define CKM_ECDH1_DERIVE 0x00001050
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
+#define CKM_ECMQV_DERIVE 0x00001052
+
+#define CKM_JUNIPER_KEY_GEN 0x00001060
+#define CKM_JUNIPER_ECB128 0x00001061
+#define CKM_JUNIPER_CBC128 0x00001062
+#define CKM_JUNIPER_COUNTER 0x00001063
+#define CKM_JUNIPER_SHUFFLE 0x00001064
+#define CKM_JUNIPER_WRAP 0x00001065
+#define CKM_FASTHASH 0x00001070
+
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+ * new for v2.11 */
+#define CKM_AES_KEY_GEN 0x00001080
+#define CKM_AES_ECB 0x00001081
+#define CKM_AES_CBC 0x00001082
+#define CKM_AES_MAC 0x00001083
+#define CKM_AES_MAC_GENERAL 0x00001084
+#define CKM_AES_CBC_PAD 0x00001085
+#define CKM_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
+
+#define CKM_VENDOR_DEFINED 0x80000000
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+
+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism */
+typedef struct CK_MECHANISM_INFO {
+ CK_ULONG ulMinKeySize;
+ CK_ULONG ulMaxKeySize;
+ CK_FLAGS flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ * Bit Flag Mask Meaning */
+#define CKF_HW 0x00000001 /* performed by HW */
+
+/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
+ * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
+ * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
+ * and CKF_DERIVE are new for v2.0. They specify whether or not
+ * a mechanism can be used for a particular task */
+#define CKF_ENCRYPT 0x00000100
+#define CKF_DECRYPT 0x00000200
+#define CKF_DIGEST 0x00000400
+#define CKF_SIGN 0x00000800
+#define CKF_SIGN_RECOVER 0x00001000
+#define CKF_VERIFY 0x00002000
+#define CKF_VERIFY_RECOVER 0x00004000
+#define CKF_GENERATE 0x00008000
+#define CKF_GENERATE_KEY_PAIR 0x00010000
+#define CKF_WRAP 0x00020000
+#define CKF_UNWRAP 0x00040000
+#define CKF_DERIVE 0x00080000
+
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+ * describe a token's EC capabilities not available in mechanism
+ * information. */
+#define CKF_EC_F_P 0x00100000
+#define CKF_EC_F_2M 0x00200000
+#define CKF_EC_ECPARAMETERS 0x00400000
+#define CKF_EC_NAMEDCURVE 0x00800000
+#define CKF_EC_UNCOMPRESS 0x01000000
+#define CKF_EC_COMPRESS 0x02000000
+
+#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000
+#define CKR_CANCEL 0x00000001
+#define CKR_HOST_MEMORY 0x00000002
+#define CKR_SLOT_ID_INVALID 0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR 0x00000005
+#define CKR_FUNCTION_FAILED 0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD 0x00000007
+#define CKR_NO_EVENT 0x00000008
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
+#define CKR_CANT_LOCK 0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
+#define CKR_DATA_INVALID 0x00000020
+#define CKR_DATA_LEN_RANGE 0x00000021
+#define CKR_DEVICE_ERROR 0x00000030
+#define CKR_DEVICE_MEMORY 0x00000031
+#define CKR_DEVICE_REMOVED 0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
+#define CKR_FUNCTION_CANCELED 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE 0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+ * v2.0 */
+#define CKR_KEY_NOT_NEEDED 0x00000064
+#define CKR_KEY_CHANGED 0x00000065
+#define CKR_KEY_NEEDED 0x00000066
+#define CKR_KEY_INDIGESTIBLE 0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+
+#define CKR_MECHANISM_INVALID 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
+#define CKR_OPERATION_ACTIVE 0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
+#define CKR_PIN_INCORRECT 0x000000A0
+#define CKR_PIN_INVALID 0x000000A1
+#define CKR_PIN_LEN_RANGE 0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED 0x000000A3
+#define CKR_PIN_LOCKED 0x000000A4
+
+#define CKR_SESSION_CLOSED 0x000000B0
+#define CKR_SESSION_COUNT 0x000000B1
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
+#define CKR_SESSION_READ_ONLY 0x000000B5
+#define CKR_SESSION_EXISTS 0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
+
+#define CKR_SIGNATURE_INVALID 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
+#define CKR_USER_NOT_LOGGED_IN 0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
+#define CKR_USER_TYPE_INVALID 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
+#define CKR_USER_TOO_MANY_TYPES 0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG 0x00000121
+
+/* These are new to v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+
+/* These are new to v2.0 */
+#define CKR_BUFFER_TOO_SMALL 0x00000150
+#define CKR_SAVED_STATE_INVALID 0x00000160
+#define CKR_INFORMATION_SENSITIVE 0x00000170
+#define CKR_STATE_UNSAVEABLE 0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
+#define CKR_MUTEX_BAD 0x000001A0
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
+
+#define CKR_VENDOR_DEFINED 0x80000000
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize */
+typedef struct CK_C_INITIALIZE_ARGS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
+#define CKF_OS_LOCKING_OK 0x00000002
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+#define CKG_MGF1_SHA1 0x00000001
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s). */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_ULONG sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+ * holds the effective keysize */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism */
+typedef struct CK_RC2_CBC_PARAMS {
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
+ * the MAC */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+ CK_BYTE_PTR pInitVector;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG_PTR ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+#endif
Added: releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/thread_generic.h
===================================================================
--- releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/thread_generic.h (rev 0)
+++ releases/Apple/Mac OS X 10.5.6/SmartCardServices-34733/src/PKCS11/thread_generic.h 2009-09-07 21:49:09 UTC (rev 62)
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
+ * The contents of this file constitute Original Code as defined in and are
+ * subject to the Apple Public Source License Version 1.2 (the 'License').
+ * You may not use this file except in compliance with the License. Please
+ * obtain a copy of the License at http://www.apple.com/publicsource and
+ * read it before using this file.
+ *
+ * This Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
+ * see the License for the specific language governing rights and
+ * limitations under the License.
+ */
+
+/******************************************************************
+
+ MUSCLE SmartCard Development ( http://www.linuxnet.com )
+ Title : thread_generic.h
+ Package: pcsc lite
+ Author : David Corcoran
+ Date : 3/24/00
+ License: Copyright (C) 2000 David Corcoran
+ <corcoran at linuxnet.com>
+ Purpose: This provides system specific thread calls.
+
+********************************************************************/
+
+#ifndef __thread_generic_h__
+#define __thread_generic_h__
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define PCSCLITE_THREAD_T pthread_t
+#define PCSCLITE_MUTEX pthread_mutex_t
+#define PCSCLITE_MUTEX_T pthread_mutex_t*
+
+ int SYS_MutexInit(PCSCLITE_MUTEX_T);
+
+ int SYS_MutexDestroy(PCSCLITE_MUTEX_T);
+
+ int SYS_MutexLock(PCSCLITE_MUTEX_T);
+
+ int SYS_MutexUnLock(PCSCLITE_MUTEX_T);
+
+ int SYS_ThreadCreate(PCSCLITE_THREAD_T *, LPVOID, LPVOID, LPVOID);
+
+ int SYS_ThreadCancel(PCSCLITE_THREAD_T *);
+
+ int SYS_ThreadDetach(PCSCLITE_THREAD_T);
+
+ int SYS_ThreadJoin(PCSCLITE_THREAD_T *, LPVOID*);
+
+ int SYS_ThreadExit(LPVOID);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __thread_generic_h__ */
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/smartcardservices-changes/attachments/20090907/7a5b18d6/attachment-0001.html>
More information about the SmartcardServices-Changes
mailing list