esc/mac mac-build.sh,1.4,1.5
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv22673/mac
Modified Files:
mac-build.sh
Log Message:
Bug 369031 - ESC incompatible with OS X Leopard.
Index: mac-build.sh
===================================================================
RCS file: /cvs/dirsec/esc/mac/mac-build.sh,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mac-build.sh 6 Mar 2008 00:09:43 -0000 1.4
+++ mac-build.sh 17 Mar 2010 00:43:50 -0000 1.5
@@ -28,41 +28,38 @@
#Environment variables
# TOKEND_PATH_NAME - Path of where to obtain the TokenD bundle ex: /usr/local/tokend/COOLKEY.zip
-printf "\n \n"
-echo "Building ESC... for Mac.... "
-printf "\n"
+#GECKO_SDK_PATH - Path to the Universal Binary Xulrunner SDK
-OSX_RPM_PATH=/usr/local/bin
+if [ ! $XUL_FRAMEWORK_PATH ];
+then
+ XUL_FRAMEWORK_PATH=~/XUL.framework
+fi
-LIB_USB_URL_BASE=http://downloads.sourceforge.net/libusb
-LIB_USB_NAME=libusb-0.1.12
-LIB_USB_URL=$LIB_USB_URL_BASE/$LIB_USB_NAME
+TOKEND_PATH_NAME=/Users/slowjack/COOLKEY.zip
-IFD_EGATE_URL_BASE=ftp://download.fedora.redhat.com/pub/fedora/linux/core/6/source/SRPMS
-IFD_EGATE_NAME=ifd-egate-0.05
-IFD_EGATE_REL=15
+printf "\n \n"
+echo "Building ESC... for Mac.... "
+printf "\n"
-COOLKEY_PKG_NAME=SmartCardManager1.16.pkg
+COOLKEY_PKG_NAME=SmartCardManager1.19.pkg
COOLKEY_VOL_NAME=SMARTCARDMANAGER
COOLKEY_TAG=HEAD
+ESC_TAG=HEAD
+ESC_VERSION=1.1.0-12
-ESC_VERSION=1.0.1-6
-
-COOLKEY_DMG_NAME=SmartCardManager-$ESC_VERSION.OSX4.darwin.dmg
+COOLKEY_DMG_NAME=SmartCardManager-$ESC_VERSION.OSX5.darwin.dmg
-ENABLE_PK11INSTALL=
+ENABLE_PK11INSTALL=--enable-pk11install
#replacement libtool files
-LIBTOOL_USB_PATCH=../misc/libtool.usb.patch
LIBTOOL_COOLKEY=
#Various CVS repositories
FEDORA_CVS_ROOT=:pserver:anonymous@cvs.fedora.redhat.com/cvs/dirsec
MOZ_CVS_ROOT=:pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot
-MOZ_XULRUNNER_BRANCH=MOZILLA_1_8_0_7_RELEASE
# Various path constants
@@ -70,8 +67,7 @@
PK11INSTALL_PATH=/Applications/Utilities/PK11Install
TOKEND_DEST_PATH=/System/Library/Security/tokend
-#TOKEND_PATH_NAME=/share/builds/components/tokend/20070111/COOLKEY.zip
-TOKEND_DEST_NAME=A_COOLKEY.tokend
+TOKEND_DEST_NAME=COOLKEY.tokend
BASE_DIR=${PWD}
@@ -79,7 +75,7 @@
#Where to grab a few universal NSS dylib's for pk11install
-PK11INSTALL_LIB_PATH=$BASE_DIR/esc/dist/Darwin6.8_OPT.OBJ/xulrunner_build/i386/dist/universal/xulrunner/XUL.framework/Versions/Current
+PK11INSTALL_LIB_PATH=$GECKO_SDK_PATH/bin
function cleanup {
@@ -91,108 +87,11 @@
rm -f *.gz
- rm -f COOLKEY.zip
-
-}
-
-function buildUSB {
-
- if [ $NUM_ARGS -ne 0 ] && [ $THE_ARG != -doUsb ];
- then
- echo "Do not build Usb"
- return 0
- fi
-
- cd $BASE_DIR
-
- echo "Build Lib USB... "
- printf "\n"
-
- curl --verbose -O -L $LIB_USB_URL_BASE/$LIB_USB_NAME.tar.gz
-
- if [ $? != 0 ];
- then
- echo "Can't obtain tarball for Lib USB."
- return 1
- fi
-
-
- tar -xzvf $LIB_USB_NAME.tar.gz
-
- if [ $? != 0 ];
- then
- echo "Can't unpack Lib USB tarball."
- return 1
- fi
+ rm -rf $COOLKEY_PKG_NAME
- cd $LIB_USB_NAME
-
- ./configure --disable-dependency-tracking --prefix=$COOLKEY_PATH CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" CXXFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc" LDFLAGS="-arch ppc -arch i386"
-
- if [ $? != 0 ];
- then
- echo "Can't configure Lib USB."
- return 1
- fi
-
- cp $LIBTOOL_USB_PATCH .
- patch -p0 -N < libtool.usb.patch
-
- make
-
- if [ $? != 0 ];
- then
- echo "Can't make Lib USB."
- return 1
- fi
-
-
- make DESTDIR=${PWD}/../staging install
-
- return 0
-}
-
-function buildEGATE {
-
- if [ $NUM_ARGS -ne 0 ] && [ $THE_ARG != -doEgate ];
- then
- echo "Do not build Egate"
- return 0
- fi
-
- echo "Build IFD-EGATE ... "
-
- printf "\n"
-
- cd $BASE_DIR
-
- curl --verbose -O $IFD_EGATE_URL_BASE/$IFD_EGATE_NAME-$IFD_EGATE_REL.src.rpm
-
- if [ $? != 0 ];
- then
- echo "Can't obtain RPM for Egate."
- return 1
- fi
-
-
- $OSX_RPM_PATH/rpm -ihv --define="_topdir ${PWD}" $IFD_EGATE_NAME-$IFD_EGATE_REL.src.rpm
-
- $OSX_RPM_PATH/rpmbuild --nodeps -bp --define="_topdir ${PWD}" SPECS/ifd-egate.spec
-
- cd BUILD/$IFD_EGATE_NAME
-
- make PCSC_CFLAGS=-I/System/Library/Frameworks/PCSC.framework/Versions/Current/Headers USB_CFLAGS="-I../../staging/usr/local/CoolKey/include -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386" USB_LDFLAGS="-L../../staging/usr/local/CoolKey/lib -arch ppc -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386" -f Makefile-OSX
-
- if [ $? != 0 ];
- then
- echo "Can't buld Egate."
- return 1
- fi
-
- cp ../../misc/Makefile-OSX.egate.patch .
- patch -p0 -N < Makefile-OSX.egate.patch
+ rm -f COOLKEY.zip
- make -f Makefile-OSX DESTDIR=${PWD}/../../staging install
+ sudo rm -rf COOLKEY.tokend
}
@@ -201,19 +100,22 @@
echo "Build CoolKey... "
printf "\n"
-
if [ $NUM_ARGS -ne 0 ] && [ $THE_ARG != -doCoolKey ];
then
echo "Do not build CoolKey"
return 0
fi
-
echo "ENABLE_PK11INSTALLL $ENABLE_PK11INSTALL"
cd $BASE_DIR
- cvs -d $FEDORA_CVS_ROOT co -r $COOLKEY_TAG coolkey
+ if [ -d coolkey ];
+ then
+ echo "CoolKey checked out already."
+ else
+ cvs -d $FEDORA_CVS_ROOT co -r $COOLKEY_TAG coolkey
+ fi
if [ $? != 0 ];
then
@@ -221,10 +123,8 @@
return 1
fi
-
cd coolkey
-
/usr/bin/autoconf
if [ $? != 0 ];
@@ -233,7 +133,7 @@
return 1
fi
- ./configure --disable-dependency-tracking --prefix=$COOLKEY_PATH NSS_CFLAGS="-I ${PWD}/../esc/dist/Dar*/xulrunner_build/i386/dist/public/nss -I ${PWD}/../esc/dist/Dar*/xulrunner_build/i386/dist/include/nspr" NSS_LIBS="-L${PWD}/../esc/dist/Darwin6.8_OPT.OBJ/xulrunner_build/i386/dist/universal/xulrunner/XUL.framework/Versions/Current -Wl,-executable_path,${PWD}/../esc/dist/Darwin6.8_OPT.OBJ/xulrunner_build/i386/dist/universal/xulrunner/XUL.framework/Versions/Current"
+ ./configure --enable-debug --disable-dependency-tracking --prefix=$COOLKEY_PATH NSS_CFLAGS="-I $GECKO_SDK_PATH/sdk/include" NSS_LIBS="-L/Library/Frameworks/XUL.framework/Versions/Current -Wl,-executable_path,/System/Frameworks//XUL.framework/Versions/Current $ENABLE_PK11INSTALL"
if [ $? != 0 ];
then
@@ -261,7 +161,7 @@
if [ $? != 0 ];
then
- echo "Can't re-make coolkey."
+ echo "Can't make pk11install!"
return 1
fi
@@ -278,6 +178,8 @@
cp -f $PK11INSTALL_LIB_PATH/libplc4.dylib ../staging/$COOLKEY_PATH/bin
cp -f $PK11INSTALL_LIB_PATH/libplds4.dylib ../staging/$COOLKEY_PATH/bin
cp -f $PK11INSTALL_LIB_PATH/libnspr4.dylib ../staging/$COOLKEY_PATH/bin
+ cp -f $PK11INSTALL_LIB_PATH/libnssutil3.dylib ../staging/$COOLKEY_PATH/bin
+ cp -f $PK11INSTALL_LIB_PATH/libsqlite3.dylib ../staging/$COOLKEY_PATH/bin
return 0
}
@@ -300,9 +202,9 @@
if [ -d esc ];
then
- cvs -d $FEDORA_CVS_ROOT update esc
+ echo "ESC checked out already."
else
- cvs -d $FEDORA_CVS_ROOT co esc
+ cvs -d $FEDORA_CVS_ROOT co -r $ESC_TAG esc
fi
if [ $? != 0 ];
@@ -312,29 +214,18 @@
fi
cd esc
- mkdir -p dist/src
- cd dist/src
- cvs -d $MOZ_CVS_ROOT co -r $MOZ_XULRUNNER_BRANCH mozilla/client.mk
+ make BUILD_OPT=1 USE_XUL_SDK=1 clean
+ echo make BUILD_OPT=1 USE_XUL_SDK=1 ESC_VERSION=$ESC_VERSION CKY_INCLUDE=-I$BASE_DIR/staging/$COOLKEY_PATH/include CKY_LIB_LDD=-L$BASE_DIR/staging/$COOLKEY_PATH/lib XUL_FRAMEWORK_PATH=$XUL_FRAMEWORK_PATH
- if [ $? != 0 ];
- then
- echo "Can't checkout Xulrunner code."
- return 1
- fi
+ echo make BUILD_OPT=1 USE_XUL_SDK=1 ESC_VERSION=$ESC_VERSION CKY_INCLUDE=-I$BASE_DIR/staging/$COOLKEY_PATH/include CKY_LIB_LDD=-L$BASE_DIR/staging/$COOLKEY_PATH/lib XUL_FRAMEWORK_PATH=$XUL_FRAMEWORK_PATH > build.sh
- cd mozilla
- make -f client.mk checkout MOZ_CO_PROJECT=xulrunner
-
- if [ $? != 0 ];
- then
- echo "Can't checkout Xulrunner code."
- return 1
- fi
-
- cd ../../..
+ echo make BUILD_OPT=1 USE_XUL_SDK=1 clean > clean.sh
- make BUILD_OPT=1 ESC_VERSION=$ESC_VERSION CKY_INCLUDE=-I$BASE_DIR/staging/$COOLKEY_PATH/include CKY_LIB_LDD=-L$BASE_DIR/staging/$COOLKEY_PATH/lib
+ chmod 775 build.sh
+ chmod 775 clean.sh
+
+ make BUILD_OPT=1 USE_XUL_SDK=1 ESC_VERSION=$ESC_VERSION CKY_INCLUDE=-I$BASE_DIR/staging/$COOLKEY_PATH/include CKY_LIB_LDD=-L$BASE_DIR/staging/$COOLKEY_PATH/lib XUL_FRAMEWORK_PATH=$XUL_FRAMEWORK_PATH
if [ $? != 0 ];
then
@@ -387,7 +278,6 @@
fi
-
mkdir -p staging/$TOKEND_DEST_PATH
unzip COOLKEY.zip
@@ -398,8 +288,7 @@
return 0
fi
-
- mv COOLKEY.tokend ./staging/$TOKEND_DEST_PATH/A_COOLKEY.tokend
+ sudo mv COOLKEY.tokend ./staging/$TOKEND_DEST_PATH/COOLKEY.tokend
if [ $? != 0 ];
then
@@ -407,10 +296,7 @@
return 0
fi
-
return 0
-
-
}
function buildMacPackage {
@@ -458,7 +344,7 @@
echo "About to create pkg installer..."
- $PACKAGE_MAKER_PATH/PackageMaker -build -p $COOLKEY_PKG_NAME -f $BASE_DIR/staging -i $BASE_DIR/coolkey_package_data/Info.plist -d $BASE_DIR/coolkey_package_data/Description.plist -r $BASE_DIR/coolkey_package_data/Resources
+ $PACKAGE_MAKER_PATH/PackageMaker -build -p $COOLKEY_PKG_NAME -f $BASE_DIR/staging -i $BASE_DIR/coolkey_package_data/Info.plist -d $BASE_DIR/coolkey_package_data/Description.plist -r $BASE_DIR/coolkey_package_data/Resources --verbose
if [ $? != 0 ];
then
@@ -469,7 +355,7 @@
echo "Creating final dmg file .... "
printf "\n"
- hdiutil create -format UDZO -fs HFS+ -volname $COOLKEY_VOL_NAME -srcfolder $COOLKEY_PKG_NAME $COOLKEY_DMG_NAME
+ hdiutil create -format UDZO -fs HFS+ -volname $COOLKEY_VOL_NAME -srcfolder $BASE_DIR/$COOLKEY_PKG_NAME $COOLKEY_DMG_NAME
if [ $? != 0 ];
then
@@ -486,47 +372,26 @@
echo "Initializing system for Mac build..... "
printf "\n"
-
- sudo chown -R -v -h ${USER}:${USER} staging/usr
- sudo chown -R -v -h ${USER}:${USER} staging/System
- sudo chown -R -v -h ${USER}:${USER} staging/Applications
-
-
- echo "Setting default compiler to gcc 4.0.1 ...... "
- printf "\n"
-
- sudo gcc_select 4.0
+ mkdir -p staging
+ mkdir -p staging/usr
+ mkdir -p staging/System
+ mkdir -p staging/Applications
+
+ sudo chown -R -v -h ${USER}:staff staging/usr
+ sudo chown -R -v -h ${USER}:staff staging/System
+ sudo chown -R -v -h ${USER}:staff staging/Applications
rm -rf staging/CVS
rm -rf staging/$TOKEND_DEST_PATH
- rm -rf *.dmg
-
-
- mkdir -p BUILD
-
- if [ $? != 0 ];
- then
- echo "Problem setting up build...."
- exit 1
- fi
-
- mkdir -p SPECS
-
- if [ $? != 0 ];
- then
- echo "Problem setting up build...."
- exit 1
- fi
- mkdir -p SOURCES
+ rm -rf staging/Applications/*
+ rm -rf staging/System/*
+ rm -rf stating/usr/*
- if [ $? != 0 ];
- then
- echo "Problem setting up build...."
- exit 1
- fi
+ rm -rf *.dmg
+ export MACOSX_DEPLOYMENT_TARGET=10.5
}
@@ -554,7 +419,7 @@
return
fi
- if [ $THE_ARG != -doUsb ] && [ $THE_ARG != -doEgate ] && [ $THE_ARG != -doEsc ] && [ $THE_ARG != -doCoolKey ] && [ $THE_ARG != -doTokenD ] && [ $THE_ARG != -doInstaller ];
+ if [ $THE_ARG != -doEsc ] && [ $THE_ARG != -doCoolKey ] && [ $THE_ARG != -doTokenD ] && [ $THE_ARG != -doInstaller ];
then
echo "Incorrect arguments!"
usage
@@ -571,18 +436,13 @@
processARGS
-
initializeBuild
-buildUSB
-
if [ $? != 0 ];
then
exit 1
fi
-buildEGATE
-
if [ $? != 0 ];
then
exit 1
@@ -604,17 +464,6 @@
exit 1
fi
-# Build coolkey, now with pk11install
-
-ENABLE_PK11INSTALL=--enable-pk11install
-
-buildCOOLKEY
-
-if [ $? != 0 ];
-then
- exit 1
-fi
-
obtainTokenD
if [ $? != 0 ];
14 years
esc/mac/coolkey_package_data Info.plist,1.1,1.2
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/coolkey_package_data
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv22673/mac/coolkey_package_data
Modified Files:
Info.plist
Log Message:
Bug 369031 - ESC incompatible with OS X Leopard.
Index: Info.plist
===================================================================
RCS file: /cvs/dirsec/esc/mac/coolkey_package_data/Info.plist,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Info.plist 2 Aug 2007 18:22:20 -0000 1.1
+++ Info.plist 17 Mar 2010 00:43:51 -0000 1.2
@@ -19,7 +19,7 @@
<plist version="1.0">
<dict>
<key>CFBundleGetInfoString</key>
- <string>Smart Card Manager 1.14</string>
+ <string>Smart Card Manager 1.19</string>
<key>CFBundleName</key>
<string>Smart Card Manager</string>
<key>CFBundleIdentifier</key>
14 years
esc/src/app/xpcom Makefile.sdk,1.4,1.5
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/src/app/xpcom
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv22673/src/app/xpcom
Modified Files:
Makefile.sdk
Log Message:
Bug 369031 - ESC incompatible with OS X Leopard.
Index: Makefile.sdk
===================================================================
RCS file: /cvs/dirsec/esc/src/app/xpcom/Makefile.sdk,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- Makefile.sdk 19 Jun 2009 21:03:39 -0000 1.4
+++ Makefile.sdk 17 Mar 2010 00:43:51 -0000 1.5
@@ -42,6 +42,7 @@
GECKO_SDK_PATH =/Users/jmagne/Desktop/gecko-sdk-mac-universal
endif
GECKO_INCLUDE_PATH=$(GECKO_SDK_PATH)/include
+GECKO_SDK_INCLUDE_PATH=$(GECKO_SDK_PATH)/sdk/include
GECKO_BIN_PATH=$(GECKO_SDK_PATH)/bin
ifndef XUL_FRAMEWORK_PATH
XUL_FRAMEWORK_PATH=/Library/Frameworks/XUL.framework
@@ -92,16 +93,16 @@
ifeq ($(OS_ARCH),Darwin)
+CXX = c++-4.0
ifdef PPC_BUILD
-CXX = c++-3.3
-CPPFLAGS += -arch ppc
+CPPFLAGS += -arch ppc -fshort-wchar
else
-CPPFLAGS += -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386
+CPPFLAGS += -isysroot /Developer/SDKs/MacOSX10.5.sdk -arch i386 -fshort-wchar
endif
endif
ifeq ($(OS_ARCH),Darwin)
-GECKO_LD_LIBS=-L$(GECKO_SDK_PATH)/lib -W1, $(GECKO_SDK_PATH)/lib/libxpcomglue.a -L$(XUL_FRAMEWORK_BIN_PATH) -lnss3 -lssl3 -lsoftokn3 -lplds4 -lplc4 -lnssutil3
+GECKO_LD_LIBS=-L$(GECKO_SDK_PATH)/sdk/lib -W1, $(GECKO_SDK_PATH)/lib/libxpcomglue.a -L$(GECKO_SDK_PATH)/bin -lnss3 -lssl3 -lnssutil3
endif
@@ -133,7 +134,7 @@
NSPR_INCLUDE = /usr/include/nspr4
-GECKO_INCLUDES = -I $(GECKO_SDK_PATH)/include -I $(GECKO_INCLUDE_PATH) -I $(NSPR_INCLUDE) -I $(NSS_INCLUDE) -I $(GECKO_INCLUDE_PATH)/xpcom
+GECKO_INCLUDES = -I $(GECKO_SDK_INCLUDE_PATH) -I $(GECKO_INCLUDE_PATH) -I $(NSPR_INCLUDE) -I $(NSS_INCLUDE) -I $(GECKO_INCLUDE_PATH)/xpcom -I $(GECKO_INCLUDE_PATH)/nspr
COOL_INCLUDES = -I $(CORE_INC)/ckymanager -I $(CORE_INC)/httpchuncked
@@ -145,14 +146,14 @@
GECKO_INCLUDES += -I $(GECKO_SDK_PATH)/sdk/include
OBJECT = rhCoolKey.obj
OBJECTCSP = CoolKeyCSP.obj
-COOL_LDFLAGS = -IMPLIB:fake-import /LIBPATH:$(CORE_DIST)/lib ckymanager.lib httpchunked.lib $(GECKO_LD_LIBS) nssutil3.lib nss3.lib ssl3.lib smime3.lib softokn3.lib /LIBPATH:$(CKY_LIB_LDD) libckyapplet.lib crypt32.lib kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib /NODEFAULTLIB:libc.lib
+COOL_LDFLAGS = -IMPLIB:fake-import /LIBPATH:$(CORE_DIST)/lib ckymanager.lib httpchunked.lib $(GECKO_LD_LIBS) nssutil3.lib nss3.lib ssl3.lib smime3.lib softokn3.lib /LIBPATH:$(CKY_LIB_LDD) libckyapplet.lib crypt32.lib kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib /NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:libmsvcrt.lib
endif
ifeq ($(OS_ARCH),Darwin)
COOL_LDFLAGS += -lsystemStubs -framework Carbon -bundle -lm
endif
-GECKO_LDFLAGS= -lnspr4 \
+GECKO_LDFLAGS= -L$(GECKO_SDK_PATH)/lib -lnspr4 \
-lplds4 -lplc4 -ldl -lpthread -Wl -z \
$(GECKO_LD_LIBS)
@@ -252,7 +253,7 @@
ifeq ($(OS_ARCH), Darwin)
mkdir $(DEPLOY_OBJDIR)/$(XULRUNNER_FRAME_BASE)
- cp -Rf -v $(XUL_FRAMEWORK_PATH) $(DEPLOY_OBJDIR)/$(XULRUNNER_FRAME_DEST)
+ rsync -r -v --links $(XUL_FRAMEWORK_PATH) $(DEPLOY_OBJDIR)/$(XULRUNNER_FRAME_BASE)
endif
ifeq ($(OS_ARCH),Linux)
14 years
esc/mac/Tokend-35209/Tokend Adornment.cpp, NONE, 1.1.2.2 Adornment.h, NONE, 1.1.2.2 Attribute.cpp, NONE, 1.1.2.2 Attribute.h, NONE, 1.1.2.2 AttributeCoder.cpp, NONE, 1.1.2.2 AttributeCoder.h, NONE, 1.1.2.2 Cursor.cpp, NONE, 1.1.2.2 Cursor.h, NONE, 1.1.2.2 DbValue.cpp, NONE, 1.1.2.2 DbValue.h, NONE, 1.1.2.2 KeyHandle.cpp, NONE, 1.1.2.2 KeyHandle.h, NONE, 1.1.2.2 MetaAttribute.cpp, NONE, 1.1.2.2 MetaAttribute.h, NONE, 1.1.2.2 MetaRecord.cpp, NONE, 1.1.2.2 MetaRecord.h, NONE, 1.1.2.2 PKCS11Object
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/Tokend
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528/Tokend
Added Files:
Tag: PKI_8_0_RTM_BRANCH
Adornment.cpp Adornment.h Attribute.cpp Attribute.h
AttributeCoder.cpp AttributeCoder.h Cursor.cpp Cursor.h
DbValue.cpp DbValue.h KeyHandle.cpp KeyHandle.h
MetaAttribute.cpp MetaAttribute.h MetaRecord.cpp MetaRecord.h
PKCS11Object.cpp PKCS11Object.h Record.cpp Record.h
RecordHandle.cpp RecordHandle.h Relation.cpp Relation.h
SCardError.cpp SCardError.h Schema.cpp Schema.h
SelectionPredicate.cpp SelectionPredicate.h Token.cpp Token.h
TokenContext.cpp TokenContext.h
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE Adornment.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Adornment.cpp
* TokendMuscle
*/
#include "Adornment.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Record.h"
namespace Tokend
{
//
// LinkedRecordAdornment
//
//const Adornment::Key LinkedRecordAdornment::key = "LinkedRecordAdornment";
LinkedRecordAdornment::LinkedRecordAdornment(RefPointer<Record> record) :
mRecord(record)
{
}
LinkedRecordAdornment::~LinkedRecordAdornment()
{
}
Record &LinkedRecordAdornment::record()
{
return *mRecord;
}
//
// SecCertificateAdornment
//
SecCertificateAdornment::SecCertificateAdornment(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
// Get the data for record (the actual certificate).
const MetaAttribute &dma =
metaAttribute.metaRecord().metaAttributeForData();
const Attribute &data = dma.attribute(tokenContext, record);
// Data should have exactly one value.
if (data.size() != 1)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
// Create a new adornment using the data from the certificate.
OSStatus status = SecCertificateCreateFromData(&data[0], CSSM_CERT_X_509v3,
CSSM_CERT_ENCODING_BER, &mCertificate);
if (status)
MacOSError::throwMe(status);
}
SecCertificateAdornment::~SecCertificateAdornment()
{
CFRelease(mCertificate);
}
SecCertificateRef SecCertificateAdornment::certificate()
{
return mCertificate;
}
SecKeychainItemRef SecCertificateAdornment::certificateItem()
{
return SecKeychainItemRef(mCertificate);
}
} // end namespace Tokend
--- NEW FILE Adornment.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Adornment.h
* TokendMuscle
*/
#ifndef _TOKEND_ADORNMENT_H_
#define _TOKEND_ADORNMENT_H_
#include <security_utilities/adornments.h>
#include <security_utilities/refcount.h>
#include <Security/SecCertificate.h>
namespace Tokend
{
class TokenContext;
class MetaRecord;
class MetaAttribute;
class Record;
//
// Adornment that refers to another record
//
class LinkedRecordAdornment : public Adornment
{
NOCOPY(LinkedRecordAdornment)
public:
LinkedRecordAdornment(RefPointer<Record> record);
~LinkedRecordAdornment();
Record &record();
private:
RefPointer<Record> mRecord;
};
class SecCertificateAdornment : public Adornment
{
NOCOPY(SecCertificateAdornment)
public:
SecCertificateAdornment(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
~SecCertificateAdornment();
SecCertificateRef certificate();
SecKeychainItemRef certificateItem();
private:
SecCertificateRef mCertificate;
};
} // end namespace Tokend
#endif /* !_TOKEND_ADORNMENT_H_ */
--- NEW FILE Attribute.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Attribute.cpp
* TokendMuscle
*/
#include "Attribute.h"
namespace Tokend
{
Attribute::Attribute()
{
mCount = 0;
mValues = NULL;
}
Attribute::Attribute(const Attribute &attribute)
{
set(attribute.mValues, attribute.mCount);
}
Attribute::Attribute(bool value)
{
uint32 v = value ? 1 : 0;
set(&v, sizeof(v));
}
Attribute::Attribute(sint32 value)
{
set(&value, sizeof(value));
}
Attribute::Attribute(uint32 value)
{
set(&value, sizeof(value));
}
Attribute::Attribute(const char *value)
{
set(value, strlen(value));
}
Attribute::Attribute(const std::string &value)
{
set(value.c_str(), value.size());
}
Attribute::Attribute(const void *data, uint32 length)
{
set(data, length);
}
Attribute::Attribute(const CSSM_DATA *datas, uint32 count)
{
set(datas, count);
}
Attribute::~Attribute()
{
if (mValues)
free(mValues);
}
Attribute &Attribute::operator = (const Attribute &attribute)
{
if (mValues)
free(mValues);
set(attribute.mValues, attribute.mCount);
return *this;
}
void Attribute::set(const CSSM_DATA *datas, uint32 count)
{
mCount = count;
uint32 size = count * sizeof(CSSM_DATA);
for (uint32 ix = 0; ix < count; ++ix)
size += datas[ix].Length;
uint8 *buffer = (uint8 *)malloc(size);
mValues = CSSM_DATA_PTR(buffer);
buffer += sizeof(CSSM_DATA) * count;
for (uint32 ix = 0; ix < count; ++ix)
{
uint32 length = datas[ix].Length;
mValues[ix].Data = buffer;
mValues[ix].Length = length;
memcpy(mValues[ix].Data, datas[ix].Data, length);
buffer += length;
}
}
void Attribute::set(const void *data, uint32 length)
{
mCount = 1;
uint8 *buffer = (uint8 *)malloc(sizeof(CSSM_DATA) + length);
mValues = CSSM_DATA_PTR(buffer);
mValues[0].Data = buffer + sizeof(CSSM_DATA);
mValues[0].Length = length;
memcpy(mValues[0].Data, data, length);
}
void Attribute::getDateValue(CSSM_DATE &date) const
{
if (mCount == 0 || mValues[0].Length == 0)
{
memset(&date, 0, sizeof(date));
}
else if (mCount == 1 && mValues[0].Length == sizeof(date))
{
memcpy(&date, mValues[0].Data, sizeof(date));
}
else
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
uint32 Attribute::uint32Value() const
{
if (mCount != 1 || mValues[0].Length != 4)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
return *reinterpret_cast<uint32 *>(mValues[0].Data);
}
} // end namespace Tokend
--- NEW FILE Attribute.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Attribute.h
* TokendMuscle
*/
#ifndef _TOKEND_ATTRIBUTE_H_
#define _TOKEND_ATTRIBUTE_H_
#include <Security/cssmtype.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <string>
namespace Tokend
{
class Attribute
{
public:
Attribute();
Attribute(const Attribute &attribute);
Attribute(bool value);
Attribute(sint32 value);
Attribute(uint32 value);
Attribute(const char *value);
Attribute(const std::string &value);
Attribute(const void *data, uint32 length);
Attribute(const CSSM_DATA *datas, uint32 count);
~Attribute();
Attribute &operator = (const Attribute &attribute);
uint32 size() const { return mCount; }
const CSSM_DATA &operator [](uint32 ix) const { return mValues[ix]; }
const CSSM_DATA *values() const { return mValues; }
void getDateValue(CSSM_DATE &date) const;
uint32 uint32Value() const;
bool boolValue() const { return uint32Value() != 0; }
private:
void set(const CSSM_DATA *datas, uint32 count);
void set(const void *data, uint32 length);
uint32 mCount;
CSSM_DATA_PTR mValues;
};
} // end namespace Tokend
#endif /* !_TOKEND_ATTRIBUTE_H_ */
--- NEW FILE AttributeCoder.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* AttributeCoder.cpp
* TokendMuscle
*/
#include "AttributeCoder.h"
#include "Attribute.h"
#include "Adornment.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Record.h"
#include <security_cdsa_utilities/cssmerrors.h>
#include <security_cdsa_utilities/cssmkey.h>
#include <Security/cssmerr.h>
#include <Security/SecKey.h>
#include <Security/SecCertificate.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecKeychainItemPriv.h>
namespace Tokend
{
//
// AttributeCoder
//
AttributeCoder::~AttributeCoder() {}
//
// CertificateAttributeCoder
//
CertificateAttributeCoder::~CertificateAttributeCoder() {}
void CertificateAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute,
Record &record)
{
// Get the SecCertificateAdornment off record using a pointer to ourself as
// the key
SecCertificateAdornment &sca =
record.adornment<SecCertificateAdornment>(this, tokenContext,
metaAttribute, record);
// Get the keychain item for the certificate from the record's adornment.
SecKeychainItemRef certificate = sca.certificateItem();
// Read the attribute with the requested attributeId from the item.
SecKeychainAttribute ska = { metaAttribute.attributeId() };
SecKeychainAttributeList skal = { 1, &ska };
OSStatus status = SecKeychainItemCopyContent(certificate, NULL, &skal,
NULL, NULL);
if (status)
MacOSError::throwMe(status);
// Add the retrieved attribute as an attribute to the record.
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(ska.data, ska.length));
// Free the retrieved attribute.
status = SecKeychainItemFreeContent(&skal, NULL);
if (status)
MacOSError::throwMe(status);
// @@@ The code above only returns one email address. Fix this.
}
//
// ConstAttributeCoder
//
ConstAttributeCoder::ConstAttributeCoder(uint32 value) : mValue(value) {}
ConstAttributeCoder::ConstAttributeCoder(bool value) : mValue(value ? 1 : 0) {}
ConstAttributeCoder::~ConstAttributeCoder() {}
void ConstAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(mValue));
}
//
// GuidAttributeCoder
//
GuidAttributeCoder::GuidAttributeCoder(const CSSM_GUID &guid) : mGuid(guid) {}
GuidAttributeCoder::~GuidAttributeCoder() {}
void GuidAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(&mGuid, sizeof(CSSM_GUID)));
}
//
// NullAttributeCoder
//
NullAttributeCoder::~NullAttributeCoder() {}
void NullAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute());
}
//
// ZeroAttributeCoder
//
ZeroAttributeCoder::~ZeroAttributeCoder() {}
void ZeroAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(reinterpret_cast<const void *>(NULL), 0));
}
//
// KeyDataAttributeCoder
//
KeyDataAttributeCoder::~KeyDataAttributeCoder() {}
void KeyDataAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
const MetaRecord &mr = metaAttribute.metaRecord();
CssmKey key;
key.header().cspGuid(Guid::overlay(gGuidAppleSdCSPDL));
key.blobType(CSSM_KEYBLOB_REFERENCE);
key.blobFormat(CSSM_KEYBLOB_REF_FORMAT_INTEGER);
key.algorithm(mr.metaAttribute(kSecKeyKeyType)
.attribute(tokenContext, record).uint32Value());
key.keyClass(mr.metaAttribute(kSecKeyKeyClass)
.attribute(tokenContext, record).uint32Value());
key.header().LogicalKeySizeInBits =
mr.metaAttribute(kSecKeyKeySizeInBits).attribute(tokenContext, record)
.uint32Value();
key.header().KeyAttr =
(mr.metaAttribute(kSecKeyPermanent).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_PERMANENT : 0)
| (mr.metaAttribute(kSecKeyPrivate).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_PRIVATE : 0)
| (mr.metaAttribute(kSecKeyModifiable).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_MODIFIABLE : 0)
| (mr.metaAttribute(kSecKeySensitive).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_SENSITIVE : 0)
| (mr.metaAttribute(kSecKeyAlwaysSensitive)
.attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_ALWAYS_SENSITIVE : 0)
| (mr.metaAttribute(kSecKeyExtractable).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_EXTRACTABLE : 0)
| (mr.metaAttribute(kSecKeyNeverExtractable)
.attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_NEVER_EXTRACTABLE : 0);
CSSM_KEYUSE usage =
(mr.metaAttribute(kSecKeyEncrypt).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_ENCRYPT : 0)
| (mr.metaAttribute(kSecKeyDecrypt).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_DECRYPT : 0)
| (mr.metaAttribute(kSecKeySign).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_SIGN : 0)
| (mr.metaAttribute(kSecKeyVerify).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_VERIFY : 0)
| (mr.metaAttribute(kSecKeySignRecover).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_SIGN_RECOVER : 0)
| (mr.metaAttribute(kSecKeyVerifyRecover)
.attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_VERIFY_RECOVER : 0)
| (mr.metaAttribute(kSecKeyWrap).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_WRAP : 0)
| (mr.metaAttribute(kSecKeyUnwrap).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_UNWRAP : 0)
| (mr.metaAttribute(kSecKeyDerive).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_DERIVE : 0);
if (usage == (CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN
| CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_SIGN_RECOVER
| CSSM_KEYUSE_VERIFY_RECOVER | CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP
| CSSM_KEYUSE_DERIVE))
usage = CSSM_KEYUSE_ANY;
key.header().KeyUsage = usage;
// Dates
mr.metaAttribute(kSecKeyStartDate).attribute(tokenContext, record)
.getDateValue(key.header().StartDate);
mr.metaAttribute(kSecKeyEndDate).attribute(tokenContext, record)
.getDateValue(key.header().EndDate);
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(&key, sizeof(key)));
}
//
// LinkedRecordAttributeCoder
//
LinkedRecordAttributeCoder::~LinkedRecordAttributeCoder() {}
void LinkedRecordAttributeCoder::decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute,
Tokend::Record &record)
{
const Tokend::MetaAttribute *lma = NULL;
LinkedRecordAdornment *lra = NULL;
if (mCertificateMetaAttribute)
{
lma = mCertificateMetaAttribute;
lra = record.getAdornment<LinkedRecordAdornment>(certificateKey());
}
if (!lra && mPublicKeyMetaAttribute)
{
lma = mPublicKeyMetaAttribute;
lra = record.getAdornment<LinkedRecordAdornment>(publicKeyKey());
}
if (!lma || !lra)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
// Get the linked record's attribute and set it on record.
const Attribute &attribute = lma->attribute(tokenContext, lra->record());
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(attribute));
}
//
// DecriptionAttributeCoder
//
DescriptionAttributeCoder::~DescriptionAttributeCoder()
{
}
void DescriptionAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(record.description()));
}
//
// DataAttributeCoder
//
DataAttributeCoder::~DataAttributeCoder()
{
}
void DataAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
record.getDataAttribute(tokenContext));
}
} // end namespace Tokend
--- NEW FILE AttributeCoder.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* AttributeCoder.h
* TokendMuscle
*/
#ifndef _TOKEND_ATTRIBUTECODER_H_
#define _TOKEND_ATTRIBUTECODER_H_
#include <security_utilities/utilities.h>
#include <Security/cssmtype.h>
namespace Tokend
{
class MetaAttribute;
class Record;
class TokenContext;
class AttributeCoder
{
NOCOPY(AttributeCoder)
public:
AttributeCoder() {}
virtual ~AttributeCoder() = 0;
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record) = 0;
};
//
// A coder that derives certificate attributes for the certificate data
//
class CertificateAttributeCoder : public AttributeCoder
{
NOCOPY(CertificateAttributeCoder)
public:
CertificateAttributeCoder() {}
virtual ~CertificateAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
private:
};
//
// A coder with a constant value
//
class ConstAttributeCoder : public AttributeCoder
{
NOCOPY(ConstAttributeCoder)
public:
ConstAttributeCoder(uint32 value);
ConstAttributeCoder(bool value);
virtual ~ConstAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
private:
uint32 mValue;
};
//
// A coder whose value is a guid.
//
class GuidAttributeCoder : public AttributeCoder
{
NOCOPY(GuidAttributeCoder)
public:
GuidAttributeCoder(const CSSM_GUID &guid);
virtual ~GuidAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
private:
const CSSM_GUID mGuid;
};
//
// A coder whose value contains 0 values.
//
class NullAttributeCoder : public AttributeCoder
{
NOCOPY(NullAttributeCoder)
public:
NullAttributeCoder() {}
virtual ~NullAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A coder whose value contains 1 zero length value.
//
class ZeroAttributeCoder : public AttributeCoder
{
NOCOPY(ZeroAttributeCoder)
public:
ZeroAttributeCoder() {}
virtual ~ZeroAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A data coder for key relations
//
class KeyDataAttributeCoder : public AttributeCoder
{
NOCOPY(KeyDataAttributeCoder)
public:
KeyDataAttributeCoder() {}
virtual ~KeyDataAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A coder for private key objects value is the public key hash of a
// certificate. Generic get an attribute of a linked record coder.
//
class LinkedRecordAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(LinkedRecordAttributeCoder)
public:
LinkedRecordAttributeCoder() {}
virtual ~LinkedRecordAttributeCoder();
const void *certificateKey() const { return mCertificateMetaAttribute; }
const void *publicKeyKey() const { return mPublicKeyMetaAttribute; }
void setCertificateMetaAttribute(
const Tokend::MetaAttribute *linkedRecordMetaAttribute)
{ mCertificateMetaAttribute = linkedRecordMetaAttribute; }
void setPublicKeyMetaAttribute(
const Tokend::MetaAttribute *linkedRecordMetaAttribute)
{ mPublicKeyMetaAttribute = linkedRecordMetaAttribute; }
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute,
Tokend::Record &record);
private:
const Tokend::MetaAttribute *mCertificateMetaAttribute;
const Tokend::MetaAttribute *mPublicKeyMetaAttribute;
};
//
// A coder that reads the description of an object
//
class DescriptionAttributeCoder : public AttributeCoder
{
NOCOPY(DescriptionAttributeCoder)
public:
DescriptionAttributeCoder() {}
virtual ~DescriptionAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A coder that reads the data of an object
//
class DataAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(DataAttributeCoder)
public:
DataAttributeCoder() {}
virtual ~DataAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
} // end namespace Tokend
#endif /* !_TOKEND_ATTRIBUTECODER_H_ */
--- NEW FILE Cursor.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Cursor.cpp
* TokendMuscle
*/
#include "Cursor.h"
#include "MetaRecord.h"
#include "Record.h"
#include "RecordHandle.h"
#include "Relation.h"
#include "Token.h"
#include "SelectionPredicate.h"
namespace Tokend
{
#pragma mark ---------------- Cursor methods --------------
//
// Cursor implemetation
//
Cursor::Cursor()
{
}
Cursor::~Cursor()
{
}
//
// LinearCursor implemetation
//
LinearCursor::LinearCursor(const CSSM_QUERY *inQuery,
const Relation &inRelation) :
mIterator(inRelation.begin()),
mEnd(inRelation.end()),
mMetaRecord(inRelation.metaRecord())
{
mConjunctive = inQuery->Conjunctive;
mQueryFlags = inQuery->QueryFlags;
// @@@ Do something with inQuery->QueryLimits?
uint32 aPredicatesCount = inQuery->NumSelectionPredicates;
mPredicates.resize(aPredicatesCount);
try
{
for (uint32 anIndex = 0; anIndex < aPredicatesCount; anIndex++)
{
CSSM_SELECTION_PREDICATE &aPredicate =
inQuery->SelectionPredicate[anIndex];
mPredicates[anIndex] =
new SelectionPredicate(mMetaRecord, aPredicate);
}
}
catch (...)
{
for_each_delete(mPredicates.begin(), mPredicates.end());
throw;
}
}
LinearCursor::~LinearCursor()
{
for_each_delete(mPredicates.begin(), mPredicates.end());
}
RecordHandle *LinearCursor::next(TokenContext *tokenContext)
{
while (mIterator != mEnd)
{
RefPointer<Record> rec = *mIterator;
++mIterator;
PredicateVector::const_iterator anIt = mPredicates.begin();
PredicateVector::const_iterator anEnd = mPredicates.end();
bool aMatch;
if (anIt == anEnd) // If there are no predicates we have a match.
aMatch = true;
else if (mConjunctive == CSSM_DB_OR)
{
// If mConjunctive is OR, the first predicate that returns
// true indicates a match. Dropthough means no match
aMatch = false;
for (; anIt != anEnd; anIt++)
{
if ((*anIt)->evaluate(tokenContext, *rec))
{
aMatch = true;
break;
}
}
}
else if (mConjunctive == CSSM_DB_AND || mConjunctive == CSSM_DB_NONE)
{
// If mConjunctive is AND (or NONE), the first predicate that
// returns false indicates a mismatch. Dropthough means a match.
aMatch = true;
for (; anIt != anEnd; anIt++)
{
if (!(*anIt)->evaluate(tokenContext, *rec))
{
aMatch = false;
break;
}
}
}
else
{
CssmError::throwMe(CSSMERR_DL_INVALID_QUERY);
}
if (aMatch)
return new RecordHandle(mMetaRecord, rec);
}
return NULL;
}
#pragma mark ---------------- MultiCursor methods --------------
MultiCursor::MultiCursor(const CSSM_QUERY *inQuery, const Schema &inSchema) :
mRelationIterator(inSchema.begin()),
mRelationEnd(inSchema.end())
{
if (inQuery)
mQuery.reset(new CssmAutoQuery(*inQuery));
else
{
mQuery.reset(new CssmAutoQuery());
mQuery->recordType(CSSM_DL_DB_RECORD_ANY);
}
}
MultiCursor::~MultiCursor()
{
}
RecordHandle *MultiCursor::next(TokenContext *tokenContext)
{
RecordHandle *result = NULL;
for (;;)
{
if (!mCursor.get())
{
if (mRelationIterator == mRelationEnd)
return NULL;
const Relation &aRelation = *(mRelationIterator->second);
++mRelationIterator;
if (!aRelation.matchesId(mQuery->recordType()))
continue;
mCursor.reset(new LinearCursor(mQuery.get(), aRelation));
}
if ((result = mCursor->next(tokenContext)))
return result;
mCursor.reset(NULL);
}
}
} // end namespace Tokend
--- NEW FILE Cursor.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Cursor.h
* TokendMuscle
*/
#ifndef _TOKEND_CURSOR_H_
#define _TOKEND_CURSOR_H_
#include "Relation.h"
#include "Schema.h"
#include <security_cdsa_utilities/handleobject.h>
#include <vector>
namespace Tokend
{
class MetaRecord;
class RecordHandle;
class Relation;
class SelectionPredicate;
class Cursor : public HandleObject
{
NOCOPY(Cursor)
public:
Cursor();
virtual ~Cursor() = 0;
virtual RecordHandle *next(TokenContext *tokenContext) = 0;
};
class LinearCursor : public Cursor
{
NOCOPY(LinearCursor)
public:
LinearCursor(const CSSM_QUERY *inQuery, const Relation &inRelation);
virtual ~LinearCursor();
virtual RecordHandle *next(TokenContext *tokenContext);
private:
Relation::const_iterator mIterator;
Relation::const_iterator mEnd;
const MetaRecord &mMetaRecord;
CSSM_DB_CONJUNCTIVE mConjunctive;
// If CSSM_QUERY_RETURN_DATA is set return the raw key bits
CSSM_QUERY_FLAGS mQueryFlags;
typedef vector<SelectionPredicate *> PredicateVector;
PredicateVector mPredicates;
};
class MultiCursor : public Cursor
{
NOCOPY(MultiCursor)
public:
MultiCursor(const CSSM_QUERY *inQuery, const Schema &inSchema);
virtual ~MultiCursor();
virtual RecordHandle *next(TokenContext *tokenContext);
private:
Schema::ConstRelationMapIterator mRelationIterator;
Schema::ConstRelationMapIterator mRelationEnd;
auto_ptr<CssmAutoQuery> mQuery;
auto_ptr<Cursor> mCursor;
};
} // end namespace Tokend
#endif /* !_TOKEND_CURSOR_H_ */
--- NEW FILE DbValue.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* DbValue.cpp
* TokendMuscle
*/
#include "DbValue.h"
#include <ctype.h>
// @@@ missing "pack" methods with WriteSection parameter
namespace Tokend
{
//
// DbValue
//
DbValue::DbValue()
{
}
DbValue::~DbValue()
{
}
UInt32Value::UInt32Value(const CSSM_DATA &data)
{
switch (data.Length)
{
case 1: mValue = *reinterpret_cast<uint8 *>(data.Data); break;
case 2: mValue = *reinterpret_cast<uint16 *>(data.Data); break;
case 4: mValue = *reinterpret_cast<uint32 *>(data.Data); break;
default:
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
}
UInt32Value::~UInt32Value()
{
}
//
// SInt32Value
//
SInt32Value::SInt32Value(const CSSM_DATA &data)
{
switch (data.Length)
{
case 1: mValue = *reinterpret_cast<sint8 *>(data.Data); break;
case 2: mValue = *reinterpret_cast<sint16 *>(data.Data); break;
case 4: mValue = *reinterpret_cast<sint32 *>(data.Data); break;
default:
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
}
SInt32Value::~SInt32Value()
{
}
//
// DoubleValue
//
DoubleValue::DoubleValue(const CSSM_DATA &data)
{
switch (data.Length)
{
case 4: mValue = *reinterpret_cast<float *>(data.Data); break;
case 8: mValue = *reinterpret_cast<double *>(data.Data); break;
default:
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
}
DoubleValue::~DoubleValue()
{
}
//
// BlobValue
//
BlobValue::BlobValue(const CSSM_DATA &data) : CssmData(CssmData::overlay(data))
{
}
BlobValue::~BlobValue()
{
}
BlobValue::Comparator::~Comparator()
{
}
int
BlobValue::Comparator::operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length)
{
return memcmp(ptr1, ptr2, length);
}
bool
BlobValue::evaluate(const BlobValue &other, CSSM_DB_OPERATOR op) const
{
return evaluate(*this, other, op, Comparator());
}
bool
BlobValue::evaluate(const CssmData &inData1, const CssmData &inData2,
CSSM_DB_OPERATOR op, Comparator compare)
{
uint32 length1 = inData1.Length, length2 = inData2.Length;
const uint8 *data1 = inData1.Data;
const uint8 *data2 = inData2.Data;
switch (op) {
case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
if (length1 > length2)
return false;
length2 = length1;
goto DB_EQUAL;
case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
if (length1 > length2)
return false;
data2 += (length2 - length1);
length2 = length1;
// dropthrough...
case CSSM_DB_EQUAL:
DB_EQUAL:
if (length1 != length2)
return false;
if (length1 == 0)
return true;
return compare(data1, data2, length1) == 0;
case CSSM_DB_NOT_EQUAL:
if (length1 != length2)
return true;
if (length1 == 0)
return false;
return compare(data1, data2, length1) != 0;
case CSSM_DB_LESS_THAN:
case CSSM_DB_GREATER_THAN:
{
uint32 length = min(length1, length2);
int result = (length == 0) ? 0 : compare(data1, data2, length);
if (result < 0 || (result == 0 && length1 < length2))
return op == CSSM_DB_LESS_THAN;
else if (result > 0 || (result == 0 && length1 > length2))
return op == CSSM_DB_GREATER_THAN;
break;
}
case CSSM_DB_CONTAINS:
if (length1 > length2)
return false;
if (length1 == 0)
return true;
// Both buffers are at least 1 byte long.
for (const uint8 *data = data2; data + length1 <= data2 + length2;
++data)
if (compare(data1, data, length1) == 0)
return true;
break;
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
return false;
}
//
// TimeDateValue
//
TimeDateValue::TimeDateValue(const CSSM_DATA &data)
: BlobValue(data)
{
if (Length != kTimeDateSize || !isValidDate())
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
TimeDateValue::~TimeDateValue()
{
}
bool
TimeDateValue::isValidDate() const
{
if (Length != kTimeDateSize || Data[kTimeDateSize - 1] != 0 ||
Data[kTimeDateSize - 2] != 'Z')
return false;
for (uint32 i = 0; i < kTimeDateSize - 2; i++)
if (!isdigit(Data[i]))
return false;
uint32 month = rangeValue(4, 2);
if (month < 1 || month > 12)
return false;
uint32 day = rangeValue(6, 2);
if (day < 1 || day > 31)
return false;
uint32 hour = rangeValue(8, 2);
if (hour < 0 || hour > 23)
return false;
uint32 minute = rangeValue(10, 2);
if (minute < 0 || minute > 59)
return false;
uint32 second = rangeValue(12, 2);
if (second < 0 || second > 59)
return false;
return true;
}
uint32
TimeDateValue::rangeValue(uint32 start, uint32 length) const
{
uint32 value = 0;
for (uint32 i = 0; i < length; i++)
value = value * 10 + Data[start + i] - '0';
return value;
}
//
// StringValue
//
StringValue::StringValue(const CSSM_DATA &data)
: BlobValue(data)
{
}
StringValue::~StringValue()
{
}
int
StringValue::Comparator::operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length)
{
return strncmp(reinterpret_cast<const char *>(ptr1),
reinterpret_cast<const char *>(ptr2), length);
}
bool
StringValue::evaluate(const StringValue &other, CSSM_DB_OPERATOR op) const
{
return BlobValue::evaluate(*this, other, op, StringValue::Comparator());
}
//
// BigNumValue
//
BigNumValue::BigNumValue(const CSSM_DATA &data)
: BlobValue(data)
{
// remove trailing zero bytes
while (Length > 1 && Data[Length - 1] == 0)
Length--;
// if the number is zero (positive or negative), make the length zero
if (Length == 1 && (Data[0] & ~kSignBit) == 0)
Length = 0;
}
BigNumValue::~BigNumValue()
{
}
// Walk the contents of two equal-sized bignums, moving backward
// from the high-order bytes, and return the comparison result
// ala memcmp.
int
BigNumValue::compare(const uint8 *a, const uint8 *b, int length)
{
for (int diff, i = length - 1; i >= 1; i--)
if ((diff = a[i] - b[i]))
return diff;
// for the last (i.e. first) byte, mask out the sign bit
return (a[0] & ~kSignBit) - (b[0] & ~kSignBit);
}
// Compare two bignums, assuming they are in canonical form (i.e.,
// no bytes containing trailing zeros.
bool
BigNumValue::evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const
{
uint32 length1 = Length, length2 = other.Length;
uint8 sign1 = length1 ? (Data[0] & kSignBit) : 0;
uint8 sign2 = length2 ? (other.Data[0] & kSignBit) : 0;
switch (op)
{
case CSSM_DB_EQUAL:
case CSSM_DB_NOT_EQUAL:
return BlobValue::evaluate(other, op);
case CSSM_DB_LESS_THAN:
if (sign1 ^ sign2)
// different signs: return true iff left value is the negative one
return sign1;
else if (length1 != length2)
// in canonical form, shorter numbers have smaller absolute value
return sign1 ? (length1 > length2) : (length1 < length2);
else {
// same length, same sign...
int c = compare(Data, other.Data, length1);
return sign1 ? (c > 0) : (c < 0);
}
break;
case CSSM_DB_GREATER_THAN:
if (sign1 ^ sign2)
return sign2;
else if (length1 != length2)
return sign1 ? (length1 < length2) : (length1 > length2);
else {
int c = compare(Data, other.Data, length1);
return sign1 ? (c < 0) : (c > 0);
}
break;
case CSSM_DB_CONTAINS:
case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
}
//
// MultiUInt32Value
//
MultiUInt32Value::MultiUInt32Value(const CSSM_DATA &data)
{
if (data.Length & (sizeof(uint32) - 1))
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
mNumValues = data.Length / sizeof(uint32);
mValues = reinterpret_cast<uint32 *>(data.Data);
mOwnsValues = false;
}
MultiUInt32Value::~MultiUInt32Value()
{
if (mOwnsValues)
delete [] mValues;
}
static inline int
uint32cmp(const uint32 *a, const uint32 *b, uint32 length)
{
return memcmp(a, b, length * sizeof(uint32));
}
bool
MultiUInt32Value::evaluate(const MultiUInt32Value &other,
CSSM_DB_OPERATOR op) const
{
uint32 length1 = mNumValues, length2 = other.mNumValues;
const uint32 *values1 = mValues;
const uint32 *values2 = other.mValues;
switch (op)
{
case CSSM_DB_EQUAL:
if (length1 == length2)
return uint32cmp(values1, values2, length1) == 0;
break;
case CSSM_DB_NOT_EQUAL:
if (length1 != length2 || uint32cmp(values1, values2, length1))
return true;
break;
case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
if (length1 <= length2)
return uint32cmp(values1, values2, length1) == 0;
break;
case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
if (length1 <= length2)
return uint32cmp(values1, values2 + (length2 - length1), length1)
== 0;
break;
case CSSM_DB_CONTAINS:
if (length1 <= length2) {
if (length1 == 0)
return true;
for (const uint32 *values = values2;
values + length1 < values2 + length2; values++)
if (uint32cmp(values1, values, length1) == 0)
return true;
}
break;
case CSSM_DB_LESS_THAN:
// this is not required by the spec, but is required to sort indexes
// over multi uint32 keys...
if (length1 < length2)
return true;
else if (length1 == length2)
return uint32cmp(values1, values2, length1) < 0;
break;
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
return false;
}
} // end namespace Tokend
--- NEW FILE DbValue.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* DbValue.h
* TokendMuscle
*/
#ifndef _TOKEND_DBVALUE_H_
#define _TOKEND_DBVALUE_H_
#include <security_cdsa_utilities/cssmdata.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <Security/cssmerr.h>
#include <map>
#include <vector>
namespace Tokend
{
//
// DbValue -- A base class for all types of database values.
//
class DbValue
{
NOCOPY(DbValue)
public:
DbValue();
virtual ~DbValue() = 0;
};
// A collection of subclasses of DbValue that work for simple
// data types, e.g. uint32, sint32, and double, that have
// the usual C comparison and sizeof operations. Defining this
// template saves typing below.
template <class T>
class BasicValue : public DbValue
{
NOCOPY(BasicValue)
public:
BasicValue() {}
BasicValue(T value) : mValue(value) {}
bool evaluate(const BasicValue<T> &other, CSSM_DB_OPERATOR op) const
{
switch (op)
{
case CSSM_DB_EQUAL: return mValue == other.mValue;
case CSSM_DB_NOT_EQUAL: return mValue != other.mValue;
case CSSM_DB_LESS_THAN: return mValue < other.mValue;
case CSSM_DB_GREATER_THAN: return mValue > other.mValue;
default: CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
}
size_t size() const { return sizeof(T); }
const uint8 *bytes() const
{ return reinterpret_cast<const uint8 *>(&mValue); }
protected:
T mValue;
};
// Actual useful subclasses of DbValue as instances of BasicValue.
// Note that all of these require a constructor of the form
// (const ReadSection &, uint32 &offset) that advances the offset
// to just after the value.
class UInt32Value : public BasicValue<uint32>
{
NOCOPY(UInt32Value)
public:
UInt32Value(const CSSM_DATA &data);
virtual ~UInt32Value();
};
class SInt32Value : public BasicValue<sint32>
{
NOCOPY(SInt32Value)
public:
SInt32Value(const CSSM_DATA &data);
virtual ~SInt32Value();
};
class DoubleValue : public BasicValue<double>
{
NOCOPY(DoubleValue)
public:
DoubleValue(const CSSM_DATA &data);
virtual ~DoubleValue();
};
// Subclasses of Value for more complex types.
class BlobValue : public DbValue, public CssmData
{
NOCOPY(BlobValue)
public:
BlobValue() {}
BlobValue(const CSSM_DATA &data);
virtual ~BlobValue();
bool evaluate(const BlobValue &other, CSSM_DB_OPERATOR op) const;
size_t size() const { return Length; }
const uint8 *bytes() const { return Data; }
protected:
class Comparator {
public:
virtual ~Comparator();
virtual int operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length);
};
static bool evaluate(const CssmData &data1, const CssmData &data2,
CSSM_DB_OPERATOR op, Comparator compare);
};
class TimeDateValue : public BlobValue
{
NOCOPY(TimeDateValue)
public:
enum { kTimeDateSize = 16 };
TimeDateValue(const CSSM_DATA &data);
virtual ~TimeDateValue();
bool isValidDate() const;
private:
uint32 rangeValue(uint32 start, uint32 length) const;
};
class StringValue : public BlobValue
{
NOCOPY(StringValue)
public:
StringValue(const CSSM_DATA &data);
virtual ~StringValue();
bool evaluate(const StringValue &other, CSSM_DB_OPERATOR op) const;
private:
class Comparator : public BlobValue::Comparator {
public:
virtual int operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length);
};
};
class BigNumValue : public BlobValue
{
NOCOPY(BigNumValue)
public:
static const uint8 kSignBit = 0x80;
BigNumValue(const CSSM_DATA &data);
virtual ~BigNumValue();
bool evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const;
private:
static int compare(const uint8 *a, const uint8 *b, int length);
};
class MultiUInt32Value : public DbValue
{
NOCOPY(MultiUInt32Value)
public:
MultiUInt32Value(const CSSM_DATA &data);
virtual ~MultiUInt32Value();
bool evaluate(const MultiUInt32Value &other, CSSM_DB_OPERATOR op) const;
size_t size() const { return mNumValues * sizeof(uint32); }
const uint8 *bytes() const { return reinterpret_cast<uint8 *>(mValues); }
private:
uint32 mNumValues;
uint32 *mValues;
bool mOwnsValues;
};
} // end namespace Tokend
#endif /* !_TOKEND_DBVALUE_H_ */
--- NEW FILE KeyHandle.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* KeyHandle.cpp
* TokendMuscle
*/
#include "KeyHandle.h"
namespace Tokend
{
//
// KeyHandle
//
KeyHandle::KeyHandle(const MetaRecord &metaRecord,
const RefPointer<Record> &record) :
RecordHandle(metaRecord, record)
{
}
KeyHandle::~KeyHandle()
{
}
void KeyHandle::wrapUsingKey(const Context &context,
const AccessCredentials *cred, KeyHandle *wrappingKeyHandle,
const CssmKey *wrappingKey, const CssmData *descriptiveData,
CssmKey &wrappedKey)
{
/* We are being asked to wrap this key using another key. */
secdebug("crypto", "wrapKey alg: %u", context.algorithm());
IFDUMPING("crypto", context.dump("wrapKey context"));
if (wrappingKeyHandle)
{
secdebug("tokend",
"wrapKey of a reference key using a reference key not supported");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
/* First export the key from the card. */
exportKey(context, cred, wrappedKey);
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void KeyHandle::wrapKey(const Context &context, const CssmKey &subjectKey,
const CssmData *descriptiveData, CssmKey &wrappedKey)
{
/* We are being asked to wrap a raw subject key using a key on the card. */
secdebug("tokend", "wrapKey of a raw subject key not supported");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void KeyHandle::unwrapKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *access,
const CssmKey &wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CssmData *descriptiveData,
CSSM_HANDLE &hUnwrappedKey, CssmKey &unwrappedKey)
{
secdebug("crypto", "unwrapKey alg: %u", context.algorithm());
IFDUMPING("crypto", context.dump("unwrapKey context"));
#if 0
/* Make sure our key type matches the context type */
if (keyClass() == CSSM_KEYCLASS_SESSION_KEY)
{
if (context.type() != CSSM_ALGCLASS_SYMMETRIC))
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
}
else
#endif
if (context.type() != CSSM_ALGCLASS_ASYMMETRIC)
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
/* validate wrappedKey */
if (wrappedKey.keyClass() != CSSM_KEYCLASS_SESSION_KEY)
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
if(wrappedKey.blobType() != CSSM_KEYBLOB_WRAPPED)
CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
/* validate requested storage and usage */
if (!(attributes & CSSM_KEYATTR_RETURN_DATA)
|| (attributes & (CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE
| CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_PRIVATE)) != 0)
CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
/* prepare outgoing header */
CssmKey::Header &hdr = unwrappedKey.header();
hdr.clearPod();
hdr.HeaderVersion = CSSM_KEYHEADER_VERSION;
hdr.cspGuid(gGuidAppleSdCSPDL);
hdr.blobType(CSSM_KEYBLOB_RAW);
hdr.algorithm(wrappedKey.algorithm());
hdr.keyClass(wrappedKey.keyClass());
hdr.KeyUsage = usage;
hdr.KeyAttr = attributes & ~(CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE);
// defaults (change as needed)
hdr.StartDate = wrappedKey.header().StartDate;
hdr.EndDate = wrappedKey.header().EndDate;
unwrappedKey.KeyData.Data = NULL; // ignore possible incoming KeyData
unwrappedKey.KeyData.Length = 0;
/* validate wrappedKey format */
if (wrappedKey.blobFormat() != CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7)
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT);
/* There is no descriptiveData in a PKCS7 wrapped blob. */
if (descriptiveData)
{
descriptiveData->Data = NULL;
descriptiveData->Length = 0;
}
/* Decrypt the key blob. */
decrypt(context, wrappedKey.keyData(), unwrappedKey.keyData());
/* We are assuming a CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7 from here on. */
hdr.blobFormat(CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING);
hdr.LogicalKeySizeInBits = unwrappedKey.length() * 8;
}
//
// KeyHandleFactory
//
KeyHandleFactory::~KeyHandleFactory()
{
}
} // end namespace Tokend
--- NEW FILE KeyHandle.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* KeyHandle.h
* TokendMuscle
*/
#ifndef _TOKEND_KEYHANDLE_H_
#define _TOKEND_KEYHANDLE_H_
#include "RecordHandle.h"
#include <security_cdsa_utilities/handleobject.h>
#include <security_cdsa_utilities/context.h>
#include <security_cdsa_utilities/cssmaclpod.h>
namespace Tokend
{
class MetaRecord;
class Record;
class TokenContext;
//
// A (nearly pure virtual) KeyHandle object which implements the crypto
// interface.
//
class KeyHandle : public RecordHandle
{
NOCOPY(KeyHandle)
public:
KeyHandle(const MetaRecord &metaRecord, const RefPointer<Record> &record);
~KeyHandle();
virtual void getKeySize(CSSM_KEY_SIZE &keySize) = 0;
virtual uint32 getOutputSize(const Context &context, uint32 inputSize,
bool encrypting) = 0;
virtual void generateSignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input,
CssmData &signature) = 0;
virtual void verifySignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input,
const CssmData &signature) = 0;
virtual void generateMac(const Context &context, const CssmData &input,
CssmData &output) = 0;
virtual void verifyMac(const Context &context, const CssmData &input,
const CssmData &compare) = 0;
virtual void encrypt(const Context &context, const CssmData &clear,
CssmData &cipher) = 0;
virtual void decrypt(const Context &context, const CssmData &cipher,
CssmData &clear) = 0;
virtual void exportKey(const Context &context,
const AccessCredentials *cred, CssmKey &wrappedKey) = 0;
virtual void wrapUsingKey(const Context &context,
const AccessCredentials *cred, KeyHandle *wrappingKeyHandle,
const CssmKey *wrappingKey, const CssmData *descriptiveData,
CssmKey &wrappedKey);
virtual void wrapKey(const Context &context, const CssmKey &subjectKey,
const CssmData *descriptiveData, CssmKey &wrappedKey);
virtual void unwrapKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *access,
const CssmKey &wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CssmData *descriptiveData,
CSSM_HANDLE &hUnwrappedKey, CssmKey &unwrappedKey);
private:
};
//
// A (pure virtual) factory that creates KeyHandle objects.
//
class KeyHandleFactory
{
NOCOPY(KeyHandleFactory)
public:
KeyHandleFactory() {}
virtual ~KeyHandleFactory() = 0;
virtual KeyHandle *keyHandle(TokenContext *tokenContext,
const MetaRecord &metaRecord, Record &record) const = 0;
};
} // end namespace Tokend
#endif /* !_TOKEND_KEYHANDLE_H_ */
--- NEW FILE MetaAttribute.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaAttribute.cpp
* TokendMuscle
*/
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Record.h"
#include "DbValue.h"
#include "DbValue.h"
namespace Tokend
{
MetaAttribute::~MetaAttribute()
{
}
// Construct an instance of an appropriate subclass of MetaAttribute based on
// the given format. Called in MetaRecord.cpp createAttribute.
MetaAttribute *MetaAttribute::create(MetaRecord& metaRecord, Format format,
uint32 attributeIndex, uint32 attributeId)
{
switch (format)
{
case kAF_STRING:
return new TypedMetaAttribute<StringValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_SINT32:
return new TypedMetaAttribute<SInt32Value>(metaRecord, format,
attributeIndex, attributeId);
case kAF_UINT32:
return new TypedMetaAttribute<UInt32Value>(metaRecord, format,
attributeIndex, attributeId);
case kAF_BIG_NUM:
return new TypedMetaAttribute<BigNumValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_REAL:
return new TypedMetaAttribute<DoubleValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_TIME_DATE:
return new TypedMetaAttribute<TimeDateValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_BLOB:
return new TypedMetaAttribute<BlobValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_MULTI_UINT32:
return new TypedMetaAttribute<MultiUInt32Value>(metaRecord, format,
attributeIndex, attributeId);
case kAF_COMPLEX:
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_FIELD_FORMAT);
}
}
const Attribute &
MetaAttribute::attribute(TokenContext *tokenContext, Record &record) const
{
if (!record.hasAttributeAtIndex(mAttributeIndex))
{
if (!mCoder)
{
secdebug("coder",
"No coder for r: %p rid: 0x%08X aid: %u aix: %u",
&record, mMetaRecord.relationId(), mAttributeId,
mAttributeIndex);
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
secdebug("coder",
"Asking coder %p for r: %p rid: 0x%08X aid: %u aix: %u",
mCoder, &record, mMetaRecord.relationId(), mAttributeId,
mAttributeIndex);
mCoder->decode(tokenContext, *this, record);
// The coder had better put something useful in the attribute we asked it to.
if (!record.hasAttributeAtIndex(mAttributeIndex))
{
secdebug("coder",
"Coder %p did not set r: %p rid: 0x%08X aid: %u aix: %u",
mCoder, &record, mMetaRecord.relationId(), mAttributeId,
mAttributeIndex);
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
}
const Attribute &attribute = record.attributeAtIndex(mAttributeIndex);
#ifndef NDEBUG
if (attribute.size() == 1)
secdebug("mscread",
"r: %p rid: 0x%08X aid: %u aix: %u has: 1 value of length: %lu",
&record, mMetaRecord.relationId(), mAttributeId, mAttributeIndex,
attribute[0].Length);
else
secdebug("mscread",
"r: %p rid: 0x%08X aid: %u aix: %u has: %u values",
&record, mMetaRecord.relationId(), mAttributeId, mAttributeIndex,
attribute.size());
#endif
return attribute;
}
} // end namespace Tokend
--- NEW FILE MetaAttribute.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaAttribute.h
* TokendMuscle
*/
#ifndef _TOKEND_METAATTRIBUTE_H_
#define _TOKEND_METAATTRIBUTE_H_
#include <Security/cssmtype.h>
#include <security_utilities/utilities.h>
#include "Attribute.h"
namespace Tokend
{
class Attribute;
class AttributeCoder;
class DbValue;
class MetaRecord;
class Record;
class TokenContext;
// A base class for all meta attributes.
class MetaAttribute
{
NOCOPY(MetaAttribute)
public:
typedef CSSM_DB_ATTRIBUTE_FORMAT Format;
virtual ~MetaAttribute();
// construct an appropriate subclass of MetaAttribute
static MetaAttribute *create(MetaRecord& metaRecord, Format format,
uint32 attributeIndex, uint32 attributeId);
void attributeCoder(AttributeCoder *coder) { mCoder = coder; }
Format attributeFormat() const { return mFormat; }
uint32 attributeIndex() const { return mAttributeIndex; }
uint32 attributeId() const { return mAttributeId; }
const Attribute &attribute(TokenContext *tokenContext,
Record &record) const;
const MetaRecord &metaRecord() const { return mMetaRecord; }
// interface required of all subclasses, implemented with templates below
virtual DbValue *createValue(const CSSM_DATA &data) const = 0;
virtual bool evaluate(TokenContext *tokenContext, const DbValue *value,
Record& record, CSSM_DB_OPERATOR op) const = 0;
protected:
MetaAttribute(MetaRecord& metaRecord, Format format, uint32 attributeIndex,
uint32 attributeId)
: mCoder(NULL), mMetaRecord(metaRecord), mFormat(format),
mAttributeIndex(attributeIndex), mAttributeId(attributeId) {}
AttributeCoder *mCoder;
MetaRecord &mMetaRecord;
Format mFormat;
uint32 mAttributeIndex;
uint32 mAttributeId;
};
// Template used to describe particular subclasses of MetaAttribute
template <class T>
class TypedMetaAttribute : public MetaAttribute
{
public:
TypedMetaAttribute(MetaRecord& metaRecord, Format format,
uint32 attributeIndex, uint32 attributeId)
: MetaAttribute(metaRecord, format, attributeIndex, attributeId) {}
DbValue *createValue(const CSSM_DATA &data) const
{
return new T(data);
}
bool evaluate(TokenContext *tokenContext, const DbValue *value,
Record &record, CSSM_DB_OPERATOR op) const
{
const Attribute &attr = attribute(tokenContext, record);
uint32 numValues = attr.size();
/* If any of the values for this attribute match we have a match. */
for (uint32 ix = 0; ix < numValues; ++ix)
if (dynamic_cast<const T *>(value)->evaluate(static_cast<const T &>(attr[ix]), op))
return true;
return false;
}
bool evaluate(const DbValue *value1, const DbValue *value2,
CSSM_DB_OPERATOR op) const
{
return (dynamic_cast<const T *>(value1))->
evaluate(*dynamic_cast<const T *>(value2), op);
}
};
} // end namespace Tokend
#endif /* !_TOKEND_METAATTRIBUTE_H_ */
--- NEW FILE MetaRecord.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaRecord.cpp
* TokendMuscle
*/
#include "MetaRecord.h"
#include "Attribute.h"
#include "KeyHandle.h"
#include "MetaAttribute.h"
#include "Record.h"
#include <security_utilities/trackingallocator.h>
#include <security_cdsa_utilities/cssmbridge.h>
namespace Tokend
{
#pragma mark ---------------- MetaRecord methods --------------
// Used for normal relations.
MetaRecord::MetaRecord(RelationId inRelationId) : mRelationId(inRelationId),
mKeyHandleFactory(NULL)
{
// Passing in a bogus attributeId for the attribute at index 0 (which is
// the data). It's not possible to look up the attribute by attributeId,
// nor should any coder rely on it's value.
mAttributeVector.push_back(MetaAttribute::create(*this, kAF_BLOB, 0,
'data'));
}
MetaRecord::~MetaRecord()
{
for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
}
MetaAttribute &MetaRecord::createAttribute(const std::string &inAttributeName,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
{
uint32 anAttributeId = mAttributeVector.size() - 1;
return createAttribute(&inAttributeName, NULL, anAttributeId,
inAttributeFormat);
}
MetaAttribute &MetaRecord::createAttribute(const string *inAttributeName,
const CssmOid *inAttributeOID, uint32 inAttributeID,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
{
// Index of new element is current size of vector
uint32 anAttributeIndex = mAttributeVector.size();
bool aInsertedAttributeName = false;
bool aInsertedAttributeOID = false;
bool aInsertedAttributeID = false;
if (inAttributeName)
{
if (!mNameStringMap.insert(NameStringMap::value_type(*inAttributeName,
anAttributeIndex)).second)
CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
aInsertedAttributeName = true;
}
try
{
if (inAttributeOID)
{
if (!mNameOIDMap.insert(NameOIDMap::value_type(*inAttributeOID,
anAttributeIndex)).second)
CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
aInsertedAttributeOID = true;
}
if (!mNameIntMap.insert(NameIntMap::value_type(inAttributeID,
anAttributeIndex)).second)
CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
aInsertedAttributeID = true;
// Note: this no longer throws INVALID_FIELD_NAME since the attribute
// will always have an attribute ID by which it is known.
MetaAttribute *ma = MetaAttribute::create(*this, inAttributeFormat,
anAttributeIndex, inAttributeID);
mAttributeVector.push_back(ma);
return *ma;
}
catch (...)
{
if (aInsertedAttributeName)
mNameStringMap.erase(*inAttributeName);
if (aInsertedAttributeOID)
mNameOIDMap.erase(*inAttributeOID);
if (inAttributeID)
mNameIntMap.erase(inAttributeID);
throw;
}
}
// Return the index (0 though NumAttributes - 1) of the attribute
// represented by inAttributeInfo
uint32 MetaRecord::attributeIndex(
const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
{
uint32 anIndex;
switch (inAttributeInfo.AttributeNameFormat)
{
case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
{
string aName(inAttributeInfo.Label.AttributeName);
NameStringMap::const_iterator it = mNameStringMap.find(aName);
if (it == mNameStringMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
anIndex = it->second;
break;
}
case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
{
const CssmOid &aName =
CssmOid::overlay(inAttributeInfo.Label.AttributeOID);
NameOIDMap::const_iterator it = mNameOIDMap.find(aName);
if (it == mNameOIDMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
anIndex = it->second;
break;
}
case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
{
uint32 aName = inAttributeInfo.Label.AttributeID;
NameIntMap::const_iterator it = mNameIntMap.find(aName);
if (it == mNameIntMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
anIndex = it->second;
break;
}
default:
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
break;
}
return anIndex;
}
const MetaAttribute &MetaRecord::metaAttribute(
const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
{
return *mAttributeVector[attributeIndex(inAttributeInfo)];
}
const MetaAttribute &MetaRecord::metaAttribute(uint32 name) const
{
NameIntMap::const_iterator it = mNameIntMap.find(name);
if (it == mNameIntMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
return *mAttributeVector[it->second];
}
const MetaAttribute &MetaRecord::metaAttribute(const std::string &name) const
{
NameStringMap::const_iterator it = mNameStringMap.find(name);
if (it == mNameStringMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
return *mAttributeVector[it->second];
}
const MetaAttribute &MetaRecord::metaAttributeForData() const
{
return *mAttributeVector[0];
}
void MetaRecord::attributeCoder(uint32 name, AttributeCoder *coder)
{
const_cast<MetaAttribute &>(metaAttribute(name)).attributeCoder(coder);
}
void MetaRecord::attributeCoder(const std::string &name, AttributeCoder *coder)
{
const_cast<MetaAttribute &>(metaAttribute(name)).attributeCoder(coder);
}
void MetaRecord::attributeCoderForData(AttributeCoder *coder)
{
const_cast<MetaAttribute &>(metaAttributeForData()).attributeCoder(coder);
}
void
MetaRecord::get(TokenContext *tokenContext, Record &record,
TOKEND_RETURN_DATA &data) const
{
if (data.attributes)
{
// Fetch the requested attributes.
CSSM_DB_RECORD_ATTRIBUTE_DATA &drad = *data.attributes;
drad.DataRecordType = mRelationId;
drad.SemanticInformation = 0;
for (uint32 ix = 0; ix < drad.NumberOfAttributes; ++ix)
{
CSSM_DB_ATTRIBUTE_DATA &dad = drad.AttributeData[ix];
const MetaAttribute &ma = metaAttribute(dad.Info);
dad.Info.AttributeFormat = ma.attributeFormat();
const Attribute &attr = ma.attribute(tokenContext, record);
dad.NumberOfValues = attr.size();
dad.Value = const_cast<CSSM_DATA_PTR>(attr.values());
}
}
if (data.data)
{
// Fetch the data.
const MetaAttribute &ma = metaAttributeForData();
const Attribute &attr = ma.attribute(tokenContext, record);
if (attr.size() != 1)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
(*data.data) = attr.values()[0];
if (mKeyHandleFactory)
{
KeyHandle *keyHandle = mKeyHandleFactory->keyHandle(tokenContext,
*this, record);
data.keyhandle = keyHandle ? keyHandle->handle() : 0;
}
else
data.keyhandle = 0;
}
}
} // end namespace Tokend
--- NEW FILE MetaRecord.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaRecord.h
* TokendMuscle
*/
#ifndef _TOKEND_METARECORD_H_
#define _TOKEND_METARECORD_H_
#include <security_cdsa_utilities/cssmdata.h>
#include <map>
#include <string>
#include <vector>
#include <SecurityTokend/SecTokend.h>
namespace Tokend
{
// Shorter names for some long cssm constants
enum
{
kAF_STRING = CSSM_DB_ATTRIBUTE_FORMAT_STRING,
kAF_SINT32 = CSSM_DB_ATTRIBUTE_FORMAT_SINT32,
kAF_UINT32 = CSSM_DB_ATTRIBUTE_FORMAT_UINT32,
kAF_BIG_NUM = CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM,
kAF_REAL = CSSM_DB_ATTRIBUTE_FORMAT_REAL,
kAF_TIME_DATE = CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE,
kAF_BLOB = CSSM_DB_ATTRIBUTE_FORMAT_BLOB,
kAF_MULTI_UINT32 = CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32,
kAF_COMPLEX = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
};
typedef CSSM_DB_RECORDTYPE RelationId;
class AttributeCoder;
class KeyHandleFactory;
class MetaAttribute;
class Record;
class TokenContext;
//
// Meta (or Schema) representation of an a Record. Used for packing and
// unpacking objects.
//
class MetaRecord
{
NOCOPY(MetaRecord)
public:
// Used for normal relations
// dataCoder is the coder which will be used for the "data" value
// (metaAttributeForData() returns a metaAttribute using this coder.
MetaRecord(RelationId inRelationId);
~MetaRecord();
MetaAttribute &createAttribute(const std::string &inAttributeName,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat);
MetaAttribute &createAttribute(const std::string *inAttributeName,
const CssmOid *inAttributeOID,
uint32 inAttributeID,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat);
const MetaAttribute &metaAttribute(
const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
const MetaAttribute &MetaRecord::metaAttribute(uint32 name) const;
const MetaAttribute &MetaRecord::metaAttribute(
const std::string &name) const;
const MetaAttribute &metaAttributeForData() const;
void attributeCoder(uint32 name, AttributeCoder *coder);
void attributeCoder(const std::string &name, AttributeCoder *coder);
void attributeCoderForData(AttributeCoder *coder);
RelationId relationId() const { return mRelationId; }
// Return the index (0 though NumAttributes - 1) of the attribute
// represented by inAttributeInfo
uint32 attributeIndex(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
void get(TokenContext *tokenContext, Record &record,
TOKEND_RETURN_DATA &data) const;
void keyHandleFactory(KeyHandleFactory *keyHandleFactory)
{ mKeyHandleFactory = keyHandleFactory; }
private:
//friend class MetaAttribute;
RelationId mRelationId;
typedef std::map<std::string, uint32> NameStringMap;
typedef std::map<CssmBuffer<CssmOidContainer>, uint32> NameOIDMap;
typedef std::map<uint32, uint32> NameIntMap;
NameStringMap mNameStringMap;
NameOIDMap mNameOIDMap;
NameIntMap mNameIntMap;
typedef std::vector<MetaAttribute *> AttributeVector;
typedef AttributeVector::iterator AttributeIterator;
typedef AttributeVector::const_iterator ConstAttributeIterator;
AttributeVector mAttributeVector;
KeyHandleFactory *mKeyHandleFactory;
};
} // end namespace Tokend
#endif /* !_TOKEND_METARECORD_H_ */
--- NEW FILE PKCS11Object.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* PKCS11Object.cpp
* TokendMuscle
*/
#include "PKCS11Object.h"
#include <security_utilities/debugging.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include <Security/cssmerr.h>
#if defined(DEBUGDUMP)
#include "cryptoki.h"
#include "pkcs11.h"
#endif /* !defined(DEBUGDUMP) */
namespace Tokend
{
PKCS11Object::PKCS11Object(const void *inData, size_t inSize)
{
const PKCS11ObjectHeader *object =
reinterpret_cast<const PKCS11ObjectHeader *>(inData);
if (inSize < sizeof(PKCS11ObjectHeader) || !object
|| inSize < (object->size() + sizeof(PKCS11ObjectHeader)))
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
size_t objectSize = object->size();
const uint8_t *data = object->data();
for (size_t bytesRead = 0; bytesRead < objectSize;)
{
const PKCS11Attribute *attribute =
reinterpret_cast<const PKCS11Attribute *>(&data[bytesRead]);
IFDUMPING("pkcs11", debugDump(*attribute));
mAttributeMap.insert(pair<uint32_t,
const PKCS11Attribute *>(attribute->attributeId(), attribute));
bytesRead += sizeof(PKCS11Attribute) + attribute->size();
}
}
const PKCS11Object::PKCS11Attribute *
PKCS11Object::attribute(uint32_t attributeId) const
{
AttributeMap::const_iterator it = mAttributeMap.find(attributeId);
if (it == mAttributeMap.end())
{
secdebug("pkcs11", "pkcs11 attribute: %08X not found", attributeId);
return NULL;
}
secdebug("pkcs11-d", "accessing pkcs11 attribute: %08X size: %lu",
attributeId, it->second->size());
return it->second;
}
bool PKCS11Object::attributeValueAsBool(uint32_t attributeId) const
{
const PKCS11Attribute *attr = attribute(attributeId);
if (!attr)
return false;
if (attr->size() != 1)
{
secdebug("pkcs11",
"attributeValueAsBool: pkcs11 attribute: %08X size: %lu",
attributeId, attr->size());
CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
}
return *attr->data() != 0;
}
uint32_t PKCS11Object::attributeValueAsUint32(uint32_t attributeId) const
{
const PKCS11Attribute *attr = attribute(attributeId);
if (!attr)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
if (attr->size() != 4)
{
secdebug("pkcs11",
"attributeValueAsUint32: pkcs11 attribute: %08X size: %lu",
attributeId, attr->size());
CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
}
const uint8_t *data = attr->data();
return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
}
void PKCS11Object::attributeValueAsData(uint32_t attributeId,
const uint8_t *&data, size_t &size) const
{
const PKCS11Attribute *attr = attribute(attributeId);
if (!attr)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
size = attr->size();
data = attr->data();
}
#if defined(DEBUGDUMP)
void PKCS11Object::debugDump(const PKCS11Attribute &attribute)
{
Debug::dump("found pkcs11 attribute: %s size: %lu ",
attributeName(attribute.attributeId()), attribute.size());
Debug::dumpData(attribute.data(), attribute.size());
Debug::dump("\n");
}
const char *PKCS11Object::attributeName(uint32_t attributeId)
{
static char buffer[20];
switch (attributeId)
{
case CKA_CLASS: return "CLASS";
case CKA_TOKEN: return "TOKEN";
case CKA_PRIVATE: return "PRIVATE";
case CKA_LABEL: return "LABEL";
case CKA_APPLICATION: return "APPLICATION";
case CKA_VALUE: return "VALUE";
case CKA_OBJECT_ID: return "OBJECT_ID";
case CKA_CERTIFICATE_TYPE: return "CERTIFICATE_TYPE";
case CKA_ISSUER: return "ISSUER";
case CKA_SERIAL_NUMBER: return "SERIAL_NUMBER";
case CKA_AC_ISSUER: return "AC_ISSUER";
case CKA_OWNER: return "OWNER";
case CKA_ATTR_TYPES: return "ATTR_TYPES";
case CKA_TRUSTED: return "TRUSTED";
case CKA_KEY_TYPE: return "KEY_TYPE";
case CKA_SUBJECT: return "SUBJECT";
case CKA_ID: return "ID";
case CKA_SENSITIVE: return "SENSITIVE";
case CKA_ENCRYPT: return "ENCRYPT";
case CKA_DECRYPT: return "DECRYPT";
case CKA_WRAP: return "WRAP";
case CKA_UNWRAP: return "UNWRAP";
case CKA_SIGN: return "SIGN";
case CKA_SIGN_RECOVER: return "SIGN_RECOVER";
case CKA_VERIFY: return "VERIFY";
case CKA_VERIFY_RECOVER: return "VERIFY_RECOVER";
case CKA_DERIVE: return "DERIVE";
case CKA_START_DATE: return "START_DATE";
case CKA_END_DATE: return "END_DATE";
case CKA_MODULUS: return "MODULUS";
case CKA_MODULUS_BITS: return "MODULUS_BITS";
case CKA_PUBLIC_EXPONENT: return "PUBLIC_EXPONENT";
case CKA_PRIVATE_EXPONENT: return "PRIVATE_EXPONENT";
case CKA_PRIME_1: return "PRIME_1";
case CKA_PRIME_2: return "PRIME_2";
case CKA_EXPONENT_1: return "EXPONENT_1";
case CKA_EXPONENT_2: return "EXPONENT_2";
case CKA_COEFFICIENT: return "COEFFICIENT";
case CKA_PRIME: return "PRIME";
case CKA_SUBPRIME: return "SUBPRIME";
case CKA_BASE: return "BASE";
case CKA_PRIME_BITS: return "PRIME_BITS";
case CKA_SUB_PRIME_BITS: return "SUB_PRIME_BITS";
case CKA_VALUE_BITS: return "VALUE_BITS";
case CKA_VALUE_LEN: return "VALUE_LEN";
case CKA_EXTRACTABLE: return "EXTRACTABLE";
case CKA_LOCAL: return "LOCAL";
case CKA_NEVER_EXTRACTABLE: return "NEVER_EXTRACTABLE";
case CKA_ALWAYS_SENSITIVE: return "ALWAYS_SENSITIVE";
case CKA_KEY_GEN_MECHANISM: return "KEY_GEN_MECHANISM";
case CKA_MODIFIABLE: return "MODIFIABLE";
case CKA_EC_PARAMS: return "EC_PARAMS";
case CKA_EC_POINT: return "EC_POINT";
case CKA_SECONDARY_AUTH: return "SECONDARY_AUTH";
case CKA_AUTH_PIN_FLAGS: return "AUTH_PIN_FLAGS";
case CKA_HW_FEATURE_TYPE: return "HW_FEATURE_TYPE";
case CKA_RESET_ON_INIT: return "RESET_ON_INIT";
case CKA_HAS_RESET: return "HAS_RESET";
case CKA_VENDOR_DEFINED: return "VENDOR_DEFINED";
default:
snprintf(buffer, sizeof(buffer), "unknown(%0x08X)", attributeId);
return buffer;
}
}
#endif /* !defined(DEBUGDUMP) */
} // end namespace Tokend
--- NEW FILE PKCS11Object.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* PKCS11Object.h
* TokendMuscle
*/
#ifndef _TOKEND_PKCS11OBJECT_H_
#define _TOKEND_PKCS11OBJECT_H_
#include <stdint.h>
#include <map>
#include <security_utilities/debugging.h>
namespace Tokend
{
// This object doesn't copy it's data. It's assumed that the data will live at
// least as long as this object does.
class PKCS11Object
{
public:
PKCS11Object(const void *inData, size_t inSize);
bool attributeValueAsBool(uint32_t attributeId) const;
uint32_t attributeValueAsUint32(uint32_t attributeId) const;
void PKCS11Object::attributeValueAsData(uint32_t attributeId,
const uint8_t *&data, size_t &size) const;
private:
struct PKCS11ObjectHeader
{
uint8_t oh_type;
uint8_t oh_id[2];
uint8_t oh_next_id[2];
uint8_t oa_size[2];
uint8_t oh_data[0];
size_t size() const { return (oa_size[0] << 8) + oa_size[1]; }
const uint8_t *data() const { return oh_data; }
};
struct PKCS11Attribute
{
uint8_t oa_id[4]; // big endian attribute type
uint8_t oa_size[2]; // big endian attribute length
uint8_t oa_data[0];
uint32_t attributeId() const { return (oa_id[0] << 24)
+ (oa_id[1] << 16) + (oa_id[2] << 8) + oa_id[3]; }
size_t size() const { return (oa_size[0] << 8) + oa_size[1]; }
const uint8_t *data() const { return oa_data; }
};
const PKCS11Attribute *attribute(uint32_t attributeId) const;
#if defined(DEBUGDUMP)
void debugDump(const PKCS11Attribute &attribute);
static const char *attributeName(uint32_t attributeId);
#endif /* !defined(DEBUGDUMP) */
typedef std::map<uint32_t, const PKCS11Attribute *> AttributeMap;
AttributeMap mAttributeMap;
};
} // end namespace Tokend
#endif /* !_TOKEND_PKCS11OBJECT_H_ */
--- NEW FILE Record.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Record.cpp
* TokendMuscle
*/
#include "Record.h"
#include <security_cdsa_client/aclclient.h>
namespace Tokend
{
AutoAclOwnerPrototype Record::gNobodyAclOwner;
AutoAclEntryInfoList Record::gAnyReadAclEntries;
Record::Record()
{
}
Record::~Record()
{
for_each_delete(mAttributes.begin(), mAttributes.end());
}
bool
Record::hasAttributeAtIndex(uint32 attributeIndex) const
{
if (attributeIndex < mAttributes.size())
return mAttributes[attributeIndex] != NULL;
return false;
}
const Attribute &
Record::attributeAtIndex(uint32 attributeIndex) const
{
if (attributeIndex < mAttributes.size())
{
Attribute *attribute = mAttributes[attributeIndex];
if (attribute)
return *attribute;
}
CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
}
void Record::attributeAtIndex(uint32 attributeIndex, Attribute *attribute)
{
auto_ptr<Attribute> _(attribute);
if (attributeIndex >= mAttributes.size())
mAttributes.resize(attributeIndex + 1);
if (mAttributes[attributeIndex] != NULL)
CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
mAttributes[attributeIndex] = _.release();
}
void Record::getOwner(AclOwnerPrototype &owner)
{
// Normally nobody can change the acl of an object on a smartcard.
if (!gNobodyAclOwner)
{
Allocator &alloc = Allocator::standard();
gNobodyAclOwner.allocator(alloc);
gNobodyAclOwner = CssmClient::AclFactory::NobodySubject(alloc);
}
owner = gNobodyAclOwner;
}
void Record::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
// Normally anyone can read an object on a smartcard (subclasses might
// override this).
if (!gAnyReadAclEntries) {
gAnyReadAclEntries.allocator(Allocator::standard());
gAnyReadAclEntries.add(CssmClient::AclFactory::AnySubject(
gAnyReadAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
}
count = gAnyReadAclEntries.size();
acls = gAnyReadAclEntries.entries();
}
void Record::changeOwner(const AclOwnerPrototype &owner)
{
// Default changeOwner on a record always fails.
CssmError::throwMe(CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED);
}
void Record::changeAcl(const AccessCredentials &cred, const AclEdit &edit)
{
// Default changeAcl on a record always fails.
CssmError::throwMe(CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED);
}
const char *Record::description()
{
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
Attribute *Record::getDataAttribute(TokenContext *tokenContext)
{
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
} // end namespace Tokend
--- NEW FILE Record.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Record.h
* TokendMuscle
*/
#ifndef _TOKEND_RECORD_H_
#define _TOKEND_RECORD_H_
#include "AttributeCoder.h"
#include "MetaRecord.h"
#include "Attribute.h"
#include <security_utilities/refcount.h>
#include <security_utilities/adornments.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <SecurityTokend/SecTokend.h>
namespace Tokend
{
class Record : public RefCount, public Security::Adornable
{
NOCOPY(Record)
public:
Record();
virtual ~Record();
bool hasAttributeAtIndex(uint32 attributeIndex) const;
const Attribute &attributeAtIndex(uint32 attributeIndex) const;
void attributeAtIndex(uint32 attributeIndex, Attribute *attribute);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&aclList);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
virtual const char *description();
virtual Attribute *getDataAttribute(TokenContext *tokenContext);
protected:
typedef std::vector<Attribute *> Attributes;
typedef Attributes::iterator AttributesIterator;
typedef Attributes::const_iterator ConstAttributesIterator;
Attributes mAttributes;
// temporary ACL cache hack - to be removed
static AutoAclOwnerPrototype gNobodyAclOwner;
static AutoAclEntryInfoList gAnyReadAclEntries;
};
} // end namespace Tokend
#endif /* !_TOKEND_RECORD_H_ */
--- NEW FILE RecordHandle.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* RecordHandle.cpp
* TokendMuscle
*/
#include "RecordHandle.h"
#include "MetaRecord.h"
#include "Record.h"
namespace Tokend
{
RecordHandle::RecordHandle(const MetaRecord &metaRecord,
const RefPointer<Record> &record) :
mMetaRecord(metaRecord), mRecord(record)
{
}
RecordHandle::~RecordHandle()
{
}
void RecordHandle::get(TokenContext *tokenContext, TOKEND_RETURN_DATA &data)
{
mMetaRecord.get(tokenContext, *mRecord, data);
data.record = handle();
}
void RecordHandle::getOwner(AclOwnerPrototype &owner)
{
mRecord->getOwner(owner);
}
void RecordHandle::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
mRecord->getAcl(tag, count, acls);
}
void RecordHandle::changeOwner(const AclOwnerPrototype &owner)
{
mRecord->changeOwner(owner);
}
void RecordHandle::changeAcl(const AccessCredentials &cred,
const AclEdit &edit)
{
mRecord->changeAcl(cred, edit);
}
} // end namespace Tokend
--- NEW FILE RecordHandle.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* RecordHandle.h
* TokendMuscle
*/
#ifndef _TOKEND_RECORDHANDLE_H_
#define _TOKEND_RECORDHANDLE_H_
#include <security_cdsa_utilities/handleobject.h>
#include <security_utilities/refcount.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <SecurityTokend/SecTokend.h>
namespace Tokend
{
class MetaRecord;
class Record;
class TokenContext;
class RecordHandle: public HandleObject
{
NOCOPY(RecordHandle)
public:
RecordHandle(const MetaRecord &metaRecord,
const RefPointer<Record> &record);
virtual ~RecordHandle();
virtual void get(TokenContext *tokenContext, TOKEND_RETURN_DATA &data);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&aclList);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
private:
const MetaRecord &mMetaRecord;
RefPointer<Record> mRecord;
};
} // end namespace Tokend
#endif /* !_TOKEND_RECORDHANDLE_H_ */
--- NEW FILE Relation.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Relation.cpp
* TokendMuscle
*/
#include "Relation.h"
namespace Tokend
{
// @@@ need to distinguish between records that exist at db open time, and
// those that are being added and must be written back to the card
#pragma mark ---------------- Relation methods --------------
Relation::~Relation()
{
delete mMetaRecord;
}
void Relation::insertRecord(const RefPointer<Record> &record)
{
push_back(record);
}
bool Relation::matchesId(RelationId inRelationId) const
{
RelationId anId = mMetaRecord->relationId();
if (inRelationId == CSSM_DL_DB_RECORD_ANY) // All non schema tables.
return !(CSSM_DB_RECORDTYPE_SCHEMA_START <= anId
&& anId < CSSM_DB_RECORDTYPE_SCHEMA_END);
if (inRelationId == CSSM_DL_DB_RECORD_ALL_KEYS) // All key tables.
return (anId == CSSM_DL_DB_RECORD_PUBLIC_KEY
|| anId == CSSM_DL_DB_RECORD_PRIVATE_KEY
|| anId == CSSM_DL_DB_RECORD_SYMMETRIC_KEY);
return inRelationId == anId; // Only if exact match.
}
} // end namespace Tokend
--- NEW FILE Relation.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Relation.h
* TokendMuscle
*/
#ifndef _TOKEND_RELATION_H_
#define _TOKEND_RELATION_H_
#include "Record.h"
#include <vector>
namespace Tokend
{
class MetaRecord;
class Record;
class Relation : public std::vector< RefPointer<Record> >
{
NOCOPY(Relation)
public:
Relation(MetaRecord *metaRecord) : mMetaRecord(metaRecord) { }
~Relation();
const MetaRecord &metaRecord() const { return *mMetaRecord; }
MetaRecord &metaRecord() { return *mMetaRecord; }
void insertRecord(const RefPointer<Record> &record);
bool matchesId(RelationId inRelationId) const;
protected:
MetaRecord *mMetaRecord;
};
} // end namespace Tokend
#endif /* !_TOKEND_RELATION_H_ */
--- NEW FILE SCardError.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* SCardError.cpp
* TokendMuscle
*/
#include "SCardError.h"
#include <Security/cssmerr.h>
namespace Tokend
{
/*
Excerpt from ISO/IEC 7816 part 3:
Status bytes (SW1=$6x or $9x, expect $60; SW2 any value)
--------------------------------------------------------
The end sequence SW1-SW2 gives the card status at the end of the command.
The normal ending is indicated by SW1-SW2 = $90-$00.
When the most significant half byte SW1 is $6, the meaning of SW1 is
independant of the application. The following five values are defined:
$6E The card does not support the instruction class.
$6D The instruction code is not programmed or is invalid.
$6B The reference is incorrect.
$67 The length is incorrect.
$6F No precise diagnostic is given.
Other values are reserved for future use by ISO7816. When SW1 is neither $6E
nor $6D, the card support the instruction. This part of ISO7816 does not
interprets neither $9X SW1 bytes, nor SW2
bytes; Their meaning relates to the application itself.
Supplement (were seen sometimes):
---------------------------------
SW1 SW2 Meaning
62 81 Returned data may be corrupted.
62 82 The end of the file has been reached before the end of reading.
62 84 Selected file is not valid.
65 01 Memory failure. There have been problems in writing or reading
the EEPROM. Other hardware problems may also bring this error.
68 00 The request function is not supported by the card.
6A 00 Bytes P1 and/or P2 are incorrect.
6A 80 The parameters in the data field are incorrect.
6A 82 File not found.
6A 83 Record not found.
6A 84 There is insufficient memory space in record or file.
6A 87 The P3 value is not consistent with the P1 and P2 values.
6A 88 Referenced data not found.
6C XX Incorrect P3 length.
Excerpt from ISO/IEC 7816 part 4:
Due to specifications in part 3 of ISO/IEC 7816, this part does not define the
following values of SW1-SW2 :
'60XX'
'67XX', '6BXX', '6DXX', '6EXX', '6FXX'; in each case if 'XX'!='00'
'9XXX', if 'XXX'!='000'
The following values of SW1-SW2 are defined whichever protocol is used (see
examples in annex A).
If a command is aborted with a response where SW1='6C', then SW2 indicates the
value to be given to the short Le field (exact length of requested data) when
re-issuing the same command before issuing any other command.
If a command (which may be of case 2 or 4, see table 4 and figure 4) is
processed with a response where SW1='61', then SW2 indicates the maximum value
to be given to the short Le field (length of extra data still available) in
a GET RESPONSE command issued before issuing any other command.
NOTE - A functionality similar to that offered by '61XX' may be offered at
application level by '9FXX'. However, applications may use '9FXX' for other
purposes.
Table 12 completed by tables 13 to 18 shows the general meanings of the values
of SW1-SW2 defined in this part of ISO/IEC 7816. For each command, an
appropriate clause provides more detailed meanings.
Tables 13 to 18 specify values of SW2 when SW1 is valued to '62', '63', '65',
'68', '69' and '6A'. The values of SW2 not defined in tables 13 to 18 are RFU,
except the values from 'F0' to 'FF' which are not defined in this part of
ISO/IEC 7816.
Table 12 - Coding of SW1-SW2
SW1-SW2 Meaning
Normal processing
'9000' No further qualification
'61XX' SW2 indicates the number of response bytes still available
(see text below)
Warning processings
'62XX' State of non-volatile memory unchanged (further qualification in SW2,
see table 13)
'63XX' State of non-volatile memory changed (further qualification in SW2,
see table 14)
Execution errors
'64XX' State of non-volatile memory unchanged (SW2='00', other values are RFU)
'65XX' State of non-volatile memory changed (further qualification in SW2,
see table 15)
'66XX' Reserved for security-related issues (not defined in this part of
ISO/IEC 7816)
Checking errors
'6700' Wrong length
'68XX' Functions in CLA not supported (further qualification in SW2, see
table 16)
'69XX' Command not allowed (further qualification in SW2, see table 17)
'6AXX' Wrong parameter(s) P1-P2 (further qualification in SW2, see table 18)
'6B00' Wrong parameter(s) P1-P2
'6CXX' Wrong length Le: SW2 indicates the exact length (see text below)
'6D00' Instruction code not supported or invalid
'6E00' Class not supported
'6F00' No precise diagnosis
Table 13 - Coding of SW2 when SW1='62'
SW2 Meaning
'00' No information given
'81' Part of returned data may be corrupted
'82' End of file/record reached before reading Le bytes
'83' Selected file invalidated
'84' FCI not formatted according to 1.1.5
Table 14 - Coding of SW2 when SW1='63'
SW2 Meaning
'00' No information given
'81' File filled up by the last write
'CX' Counter provided by 'X' (valued from 0 to 15) (exact meaning depending
on the command)
Table 15 - Coding of SW2 when SW1='65'
SW2 Meaning
'00' No information given
'81' Memory failure
Table 16 - Coding of SW2 when SW1='68'
SW2 Meaning
'00' No information given
'81' Logical channel not supported
'82' Secure messaging not supported
Table 17 - Coding of SW2 when SW1='69'
SW2 Meaning
'00' No information given
'81' Command incompatible with file structure
'82' Security status not satisfied
'83' Authentication method blocked
'84' Referenced data invalidated
'85' Conditions of use not satisfied
'86' Command not allowed (no current EF)
'87' Expected SM data objects missing
'88' SM data objects incorrect
Table 18 - Coding of SW2 when SW1='6A'
SW2 Meaning
'00' No information given
'80' Incorrect parameters in the data field
'81' Function not supported
'82' File not found
'83' Record not found
'84' Not enough memory space in the file
'85' Lc inconsistent with TLV structure
'86' Incorrect parameters P1-P2
'87' Lc inconsistent with P1-P2
'88' Referenced data not found
*/
//
// SCardError exceptions
//
SCardError::SCardError(uint16_t sw) : statusWord(sw)
{
IFDEBUG(debugDiagnose(this));
}
const char *SCardError::what() const throw ()
{ return "SCardError"; }
OSStatus SCardError::osStatus() const
{
switch (statusWord)
{
case SCARD_SUCCESS:
return 0;
case SCARD_FILE_FILLED:
case SCARD_MEMORY_FAILURE:
case SCARD_NO_MEMORY_LEFT:
return CSSM_ERRCODE_MEMORY_ERROR;
case SCARD_AUTHENTICATION_FAILED:
case SCARD_AUTHENTICATION_FAILED_0:
case SCARD_AUTHENTICATION_FAILED_1:
case SCARD_AUTHENTICATION_FAILED_2:
case SCARD_AUTHENTICATION_FAILED_3:
case SCARD_AUTHENTICATION_FAILED_4:
case SCARD_AUTHENTICATION_FAILED_5:
case SCARD_AUTHENTICATION_FAILED_6:
case SCARD_AUTHENTICATION_FAILED_7:
case SCARD_AUTHENTICATION_FAILED_8:
case SCARD_AUTHENTICATION_FAILED_9:
case SCARD_AUTHENTICATION_FAILED_10:
case SCARD_AUTHENTICATION_FAILED_11:
case SCARD_AUTHENTICATION_FAILED_12:
case SCARD_AUTHENTICATION_FAILED_13:
case SCARD_AUTHENTICATION_FAILED_14:
case SCARD_AUTHENTICATION_FAILED_15:
case SCARD_AUTHENTICATION_BLOCKED:
return CSSM_ERRCODE_OPERATION_AUTH_DENIED;
case SCARD_COMMAND_NOT_ALLOWED:
case SCARD_NOT_AUTHORIZED:
case SCARD_USE_CONDITIONS_NOT_MET:
return CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED;
case SCARD_FUNCTION_NOT_SUPPORTED:
case SCARD_INSTRUCTION_CODE_INVALID:
return CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED;
case SCARD_FILE_NOT_FOUND:
case SCARD_RECORD_NOT_FOUND:
return CSSMERR_DL_RECORD_NOT_FOUND;
case SCARD_BYTES_LEFT_IN_SW2:
case SCARD_EXECUTION_WARNING:
case SCARD_RETURNED_DATA_CORRUPTED:
case SCARD_END_OF_FILE_REACHED:
case SCARD_FILE_INVALIDATED:
case SCARD_FCI_INVALID:
case SCARD_EXECUTION_ERROR:
case SCARD_CHANGED_ERROR:
case SCARD_LENGTH_INCORRECT:
case SCARD_CLA_UNSUPPORTED:
case SCARD_LOGICAL_CHANNEL_UNSUPPORTED:
case SCARD_SECURE_MESSAGING_UNSUPPORTED:
case SCARD_COMMAND_INCOMPATIBLE:
case SCARD_REFERENCED_DATA_INVALIDATED:
case SCARD_NO_CURRENT_EF:
case SCARD_SM_DATA_OBJECTS_MISSING:
case SCARD_SM_DATA_NOT_ALLOWED:
case SCARD_WRONG_PARAMETER:
case SCARD_DATA_INCORRECT:
case SCARD_LC_INCONSISTENT_TLV:
case SCARD_INCORRECT_P1_P2:
case SCARD_LC_INCONSISTENT_P1_P2:
case SCARD_REFERENCED_DATA_NOT_FOUND:
case SCARD_WRONG_PARAMETER_P1_P2:
case SCARD_LE_IN_SW2:
case SCARD_INSTRUCTION_CLASS_UNSUPPORTED:
case SCARD_UNSPECIFIED_ERROR:
default:
return CSSM_ERRCODE_INTERNAL_ERROR;
}
}
int SCardError::unixError() const
{
switch (statusWord)
{
default:
// cannot map this to errno space
return -1;
}
}
void SCardError::throwMe(uint16_t sw)
{ throw SCardError(sw); }
#if !defined(NDEBUG)
void SCardError::debugDiagnose(const void *id) const
{
secdebug("exception", "%p Error %s (%04hX)",
id, errorstr(statusWord), statusWord);
}
const char *SCardError::errorstr(uint16_t sw)
{
switch (sw)
{
case SCARD_SUCCESS:
return "Success";
case SCARD_BYTES_LEFT_IN_SW2:
return "SW2 indicates the number of response bytes still available";
case SCARD_EXECUTION_WARNING:
return "Execution warning, state of non-volatile memory unchanged";
case SCARD_RETURNED_DATA_CORRUPTED:
return "Part of returned data may be corrupted.";
case SCARD_END_OF_FILE_REACHED:
return "End of file/record reached before reading Le bytes.";
case SCARD_FILE_INVALIDATED:
return "Selected file invalidated.";
case SCARD_FCI_INVALID:
return "FCI not formatted according to 1.1.5.";
case SCARD_AUTHENTICATION_FAILED:
return "Authentication failed.";
case SCARD_FILE_FILLED:
return "File filled up by the last write.";
case SCARD_AUTHENTICATION_FAILED_0:
return "Authentication failed, 0 retries left.";
case SCARD_AUTHENTICATION_FAILED_1:
return "Authentication failed, 1 retry left.";
case SCARD_AUTHENTICATION_FAILED_2:
return "Authentication failed, 2 retries left.";
case SCARD_AUTHENTICATION_FAILED_3:
return "Authentication failed, 3 retries left.";
case SCARD_AUTHENTICATION_FAILED_4:
return "Authentication failed, 4 retries left.";
case SCARD_AUTHENTICATION_FAILED_5:
return "Authentication failed, 5 retries left.";
case SCARD_AUTHENTICATION_FAILED_6:
return "Authentication failed, 6 retries left.";
case SCARD_AUTHENTICATION_FAILED_7:
return "Authentication failed, 7 retries left.";
case SCARD_AUTHENTICATION_FAILED_8:
return "Authentication failed, 8 retries left.";
case SCARD_AUTHENTICATION_FAILED_9:
return "Authentication failed, 9 retries left.";
case SCARD_AUTHENTICATION_FAILED_10:
return "Authentication failed, 10 retries left.";
case SCARD_AUTHENTICATION_FAILED_11:
return "Authentication failed, 11 retries left.";
case SCARD_AUTHENTICATION_FAILED_12:
return "Authentication failed, 12 retries left.";
case SCARD_AUTHENTICATION_FAILED_13:
return "Authentication failed, 13 retries left.";
case SCARD_AUTHENTICATION_FAILED_14:
return "Authentication failed, 14 retries left.";
case SCARD_AUTHENTICATION_FAILED_15:
return "Authentication failed, 15 retries left.";
case SCARD_EXECUTION_ERROR:
return "Execution error, state of non-volatile memory unchanged.";
case SCARD_CHANGED_ERROR:
return "Execution error, state of non-volatile memory changed.";
case SCARD_MEMORY_FAILURE:
return "Memory failure.";
case SCARD_LENGTH_INCORRECT:
return "The length is incorrect.";
case SCARD_CLA_UNSUPPORTED:
return "Functions in CLA not supported.";
case SCARD_LOGICAL_CHANNEL_UNSUPPORTED:
return "Logical channel not supported.";
case SCARD_SECURE_MESSAGING_UNSUPPORTED:
return "Secure messaging not supported.";
case SCARD_COMMAND_NOT_ALLOWED:
return "Command not allowed.";
case SCARD_COMMAND_INCOMPATIBLE:
return "Command incompatible with file structure.";
case SCARD_NOT_AUTHORIZED:
return "Security status not satisfied.";
case SCARD_AUTHENTICATION_BLOCKED:
return "Authentication method blocked.";
case SCARD_REFERENCED_DATA_INVALIDATED:
return "Referenced data invalidated.";
case SCARD_USE_CONDITIONS_NOT_MET:
return "Conditions of use not satisfied.";
case SCARD_NO_CURRENT_EF:
return "Command not allowed (no current EF).";
case SCARD_SM_DATA_OBJECTS_MISSING:
return "Expected SM data objects missing.";
case SCARD_SM_DATA_NOT_ALLOWED:
return "SM data objects incorrect.";
case SCARD_WRONG_PARAMETER:
return "Wrong parameter.";
case SCARD_DATA_INCORRECT:
return "Incorrect parameters in the data field.";
case SCARD_FUNCTION_NOT_SUPPORTED:
return "Function not supported.";
case SCARD_FILE_NOT_FOUND:
return "File not found.";
case SCARD_RECORD_NOT_FOUND:
return "Record not found.";
case SCARD_NO_MEMORY_LEFT:
return "Not enough memory space in the file.";
case SCARD_LC_INCONSISTENT_TLV:
return "Lc inconsistent with TLV structure.";
case SCARD_INCORRECT_P1_P2:
return "Incorrect parameters P1-P2.";
case SCARD_LC_INCONSISTENT_P1_P2:
return "Lc inconsistent with P1-P2.";
case SCARD_REFERENCED_DATA_NOT_FOUND:
return "Referenced data not found.";
case SCARD_WRONG_PARAMETER_P1_P2:
return "Wrong parameter(s) P1-P2.";
case SCARD_LE_IN_SW2:
return "Wrong length Le: SW2 indicates the exact length";
case SCARD_INSTRUCTION_CODE_INVALID:
return "The instruction code is not programmed or is invalid.";
case SCARD_INSTRUCTION_CLASS_UNSUPPORTED:
return "The card does not support the instruction class.";
case SCARD_UNSPECIFIED_ERROR:
return "No precise diagnostic is given.";
default:
return "Unknown error";
}
}
#endif //NDEBUG
} // end namespace Tokend
--- NEW FILE SCardError.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* SCardError.h
* TokendMuscle
*/
#ifndef _TOKEND_SCARDERROR_H_
#define _TOKEND_SCARDERROR_H_
#include <security_utilities/debugging.h>
#include <security_utilities/errors.h>
/* ISO/IEC 7816 part 3 and 4 error codes. */
/** success */
#define SCARD_SUCCESS 0x9000
/* '61XX' SW2 indicates the number of response bytes still available. */
#define SCARD_BYTES_LEFT_IN_SW2 0x6100
/* '62XX' Warning processings - State of non-volatile memory unchanged. */
/** Execution warning, state of non-volatile memory unchanged */
#define SCARD_EXECUTION_WARNING 0x6200
/** Part of returned data may be corrupted. */
#define SCARD_RETURNED_DATA_CORRUPTED 0x6281
/** End of file/record reached before reading Le bytes. */
#define SCARD_END_OF_FILE_REACHED 0x6282
/** Selected file invalidated. */
#define SCARD_FILE_INVALIDATED 0x6283
/** FCI not formatted according to 1.1.5. */
#define SCARD_FCI_INVALID 0x6284
/* '62XX' Warning processings - State of non-volatile memory changed. */
/** Authentication failed. */
#define SCARD_AUTHENTICATION_FAILED 0x6300
/** File filled up by the last write. */
#define SCARD_FILE_FILLED 0x6381
/** Authentication failed, 0 retries left. */
#define SCARD_AUTHENTICATION_FAILED_0 0x63C0
/** Authentication failed, 1 retry left. */
#define SCARD_AUTHENTICATION_FAILED_1 0x63C1
/** Authentication failed, 2 retries left. */
#define SCARD_AUTHENTICATION_FAILED_2 0x63C2
/** Authentication failed, 3 retries left. */
#define SCARD_AUTHENTICATION_FAILED_3 0x63C3
/** Authentication failed, 4 retries left. */
#define SCARD_AUTHENTICATION_FAILED_4 0x63C4
/** Authentication failed, 5 retries left. */
#define SCARD_AUTHENTICATION_FAILED_5 0x63C5
/** Authentication failed, 6 retries left. */
#define SCARD_AUTHENTICATION_FAILED_6 0x63C6
/** Authentication failed, 7 retries left. */
#define SCARD_AUTHENTICATION_FAILED_7 0x63C7
/** Authentication failed, 8 retries left. */
#define SCARD_AUTHENTICATION_FAILED_8 0x63C8
/** Authentication failed, 9 retries left. */
#define SCARD_AUTHENTICATION_FAILED_9 0x63C9
/** Authentication failed, 10 retries left. */
#define SCARD_AUTHENTICATION_FAILED_10 0x63CA
/** Authentication failed, 11 retries left. */
#define SCARD_AUTHENTICATION_FAILED_11 0x63CB
/** Authentication failed, 12 retries left. */
#define SCARD_AUTHENTICATION_FAILED_12 0x63CC
/** Authentication failed, 13 retries left. */
#define SCARD_AUTHENTICATION_FAILED_13 0x63CD
/** Authentication failed, 14 retries left. */
#define SCARD_AUTHENTICATION_FAILED_14 0x63CE
/** Authentication failed, 15 retries left. */
#define SCARD_AUTHENTICATION_FAILED_15 0x63CF
/* '64XX' Execution errors - State of non-volatile memory unchanged. */
/** Execution error, state of non-volatile memory unchanged. */
#define SCARD_EXECUTION_ERROR 0x6400
/* '65XX' Execution errors - State of non-volatile memory changed. */
/** Execution error, state of non-volatile memory changed. */
#define SCARD_CHANGED_ERROR 0x6500
/** Memory failure. */
#define SCARD_MEMORY_FAILURE 0x6581
/* '66XX' Reserved for security-related issues. */
/* '6700' Wrong length. */
/** The length is incorrect. */
#define SCARD_LENGTH_INCORRECT 0x6700
/* '68XX' Functions in CLA not supported. */
/** No information given. */
#define SCARD_CLA_UNSUPPORTED 0x6800
/** Logical channel not supported. */
#define SCARD_LOGICAL_CHANNEL_UNSUPPORTED 0x6881
/** Secure messaging not supported. */
#define SCARD_SECURE_MESSAGING_UNSUPPORTED 0x6882
/* '69XX' Command not allowed. */
/** Command not allowed. */
#define SCARD_COMMAND_NOT_ALLOWED 0x6900
/** Command incompatible with file structure. */
#define SCARD_COMMAND_INCOMPATIBLE 0x6981
/** Security status not satisfied. */
#define SCARD_NOT_AUTHORIZED 0x6982
/** Authentication method blocked. */
#define SCARD_AUTHENTICATION_BLOCKED 0x6983
/** Referenced data invalidated. */
#define SCARD_REFERENCED_DATA_INVALIDATED 0x6984
/** Conditions of use not satisfied. */
#define SCARD_USE_CONDITIONS_NOT_MET 0x6985
/** Command not allowed (no current EF). */
#define SCARD_NO_CURRENT_EF 0x6986
/** Expected SM data objects missing. */
#define SCARD_SM_DATA_OBJECTS_MISSING 0x6987
/** SM data objects incorrect. */
#define SCARD_SM_DATA_NOT_ALLOWED 0x6988
/* '6AXX' Wrong parameter(s) P1-P2. */
/** Wrong parameter. */
#define SCARD_WRONG_PARAMETER 0x6A00
/** Incorrect parameters in the data field. */
#define SCARD_DATA_INCORRECT 0x6A80
/** Function not supported. */
#define SCARD_FUNCTION_NOT_SUPPORTED 0x6A81
/** File not found. */
#define SCARD_FILE_NOT_FOUND 0x6A82
/** Record not found. */
#define SCARD_RECORD_NOT_FOUND 0x6A83
/** Not enough memory space in the file. */
#define SCARD_NO_MEMORY_LEFT 0x6A84
/** Lc inconsistent with TLV structure. */
#define SCARD_LC_INCONSISTENT_TLV 0x6A85
/** Incorrect parameters P1-P2. */
#define SCARD_INCORRECT_P1_P2 0x6A86
/** Lc inconsistent with P1-P2. */
#define SCARD_LC_INCONSISTENT_P1_P2 0x6A87
/** Referenced data not found. */
#define SCARD_REFERENCED_DATA_NOT_FOUND 0x6A88
/* '6B00' Wrong parameter(s) P1-P2. */
/** Wrong parameter(s) P1-P2. */
#define SCARD_WRONG_PARAMETER_P1_P2 0x6B00
/* '6CXX' Wrong length Le: SW2 indicates the exact length */
#define SCARD_LE_IN_SW2 0x6C00
/* '6D00' Instruction code not supported or invalid. */
/** The instruction code is not programmed or is invalid. */
#define SCARD_INSTRUCTION_CODE_INVALID 0x6D00
/* '6E00' Class not supported. */
/** The card does not support the instruction class. */
#define SCARD_INSTRUCTION_CLASS_UNSUPPORTED 0x6E00
/* '6F00' No precise diagnosis. */
/** No precise diagnostic is given. */
#define SCARD_UNSPECIFIED_ERROR 0x6F00
namespace Tokend
{
class SCardError : public Security::CommonError
{
protected:
SCardError(uint16_t sw);
public:
const uint16_t statusWord;
virtual OSStatus osStatus() const;
virtual int unixError() const;
virtual const char *what () const throw ();
static void check(uint16_t sw) { if (sw != SCARD_SUCCESS) throwMe(sw); }
static void throwMe(uint16_t sw) __attribute__((noreturn));
protected:
IFDEBUG(void debugDiagnose(const void *id) const;)
IFDEBUG(static const char *errorstr(uint16_t sw);)
};
} // end namespace Tokend
#endif /* !_TOKEND_SCARDERROR_H_ */
--- NEW FILE Schema.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Schema.cpp
* TokendMuscle
*/
#include "Schema.h"
#include "Attribute.h"
#include "MetaRecord.h"
#include "MetaAttribute.h"
#include <Security/SecKey.h>
#include <Security/SecCertificate.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecKeychainItemPriv.h>
#include <Security/cssmapple.h>
namespace Tokend
{
#pragma mark ---------------- Schema --------------
Schema::Schema() :
mTrueCoder(true),
mFalseCoder(false),
mCertEncodingBERCoder(CSSM_CERT_ENCODING(CSSM_CERT_ENCODING_BER)),
mSdCSPDLGuidCoder(gGuidAppleSdCSPDL),
mPublicKeyClassCoder(CSSM_KEYCLASS(CSSM_KEYCLASS_PUBLIC_KEY)),
mPrivateKeyClassCoder(CSSM_KEYCLASS(CSSM_KEYCLASS_PRIVATE_KEY)),
mSessionKeyClassCoder(CSSM_KEYCLASS(CSSM_KEYCLASS_SESSION_KEY))
{
}
Schema::~Schema()
{
try
{
for_each_map_delete(mRelationMap.begin(), mRelationMap.end());
}
catch(...) {}
}
void Schema::create()
{
// Attribute names.
std::string
an_RelationID("RelationID"),
an_RelationName("RelationName"),
an_AttributeID("AttributeID"),
an_AttributeNameFormat("AttributeNameFormat"),
an_AttributeName("AttributeName"),
an_AttributeNameID("AttributeNameID"),
an_AttributeFormat("AttributeFormat"),
an_IndexID("IndexID"),
an_IndexType("IndexType"),
an_IndexedDataLocation("IndexedDataLocation");
// Record the attributeIndex of each created attribute for use by our
// register functions laster on.
// Create CSSM_DL_DB_SCHEMA_INFO relation.
MetaRecord *mrio = new MetaRecord(CSSM_DL_DB_SCHEMA_INFO);
io_rid = mrio->createAttribute(an_RelationID,
kAF_UINT32).attributeIndex();
io_rn = mrio->createAttribute(an_RelationName,
kAF_STRING).attributeIndex();
mInfo = createRelation(mrio);
// Create CSSM_DL_DB_SCHEMA_ATTRIBUTES relation
MetaRecord *mras = new MetaRecord(CSSM_DL_DB_SCHEMA_ATTRIBUTES);
as_rid = mras->createAttribute(an_RelationID,
kAF_UINT32).attributeIndex();
as_aid = mras->createAttribute(an_AttributeID,
kAF_UINT32).attributeIndex();
as_anf = mras->createAttribute(an_AttributeNameFormat,
kAF_UINT32).attributeIndex();
as_an = mras->createAttribute(an_AttributeName,
kAF_STRING).attributeIndex();
as_anid= mras->createAttribute(an_AttributeNameID,
kAF_BLOB ).attributeIndex();
as_af = mras->createAttribute(an_AttributeFormat,
kAF_UINT32).attributeIndex();
mAttributes = createRelation(mras);
// Create CSSM_DL_DB_SCHEMA_INDEXES relation
MetaRecord *mrix = new MetaRecord(CSSM_DL_DB_SCHEMA_INDEXES);
ix_rid = mrix->createAttribute(an_RelationID,
kAF_UINT32).attributeIndex();
ix_iid = mrix->createAttribute(an_IndexID,
kAF_UINT32).attributeIndex();
ix_aid = mrix->createAttribute(an_AttributeID,
kAF_UINT32).attributeIndex();
ix_it = mrix->createAttribute(an_IndexType,
kAF_UINT32).attributeIndex();
ix_idl = mrix->createAttribute(an_IndexedDataLocation,
kAF_UINT32).attributeIndex();
mIndices = createRelation(mrix);
#ifdef ADD_SCHEMA_PARSING_MODULE
// @@@ Skipping CSSM_DL_DB_SCHEMA_PARSING_MODULE relation since no one uses
// it and it's definition in CDSA is broken anyway
// Attribute names.
std::string
an_ModuleID("ModuleID"),
an_AddinVersion("AddinVersion"),
an_SSID("SSID"),
an_SubserviceType("SubserviceType");
// Create CSSM_DL_DB_SCHEMA_PARSING_MODULE Relation
MetaRecord *mr_parsing = new MetaRecord(CSSM_DL_DB_SCHEMA_PARSING_MODULE);
mr_parsing->createAttribute(an_AttributeID, kAF_UINT32);
mr_parsing->createAttribute(an_ModuleID, kAF_BLOB );
mr_parsing->createAttribute(an_AddinVersion, kAF_STRING);
mr_parsing->createAttribute(an_SSID, kAF_UINT32);
mr_parsing->createAttribute(an_SubserviceType, kAF_UINT32);
createRelation(mr_parsing);
#endif
#ifdef REGISTER_SCHEMA_RELATIONS
registerRelation("CSSM_DL_DB_SCHEMA_INFO", CSSM_DL_DB_SCHEMA_INFO)
registerAttribute(CSSM_DL_DB_SCHEMA_INFO, &an_RelationID, 0,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INFO, &an_RelationName, 1,
kAF_UINT32, false);
registerRelation("CSSM_DL_DB_SCHEMA_ATTRIBUTES",
CSSM_DL_DB_SCHEMA_ATTRIBUTES)
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_RelationID, 0,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeID, 2,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeNameFormat, 3,
kAF_UINT32, false);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeName, 4,
kAF_STRING, false);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeNameId, 5,
kAF_BLOB, false);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeFormat, 6,
kAF_UINT32, false);
registerRelation("CSSM_DL_DB_SCHEMA_INDEXES", CSSM_DL_DB_SCHEMA_INDEXES)
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_RelationID, 0,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexID, 1,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_AttributeID, 2,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexType, 3,
kAF_UINT32, false);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexedDataLocation, 4,
kAF_UINT32, false);
#endif
}
// Create one of the standard relations conforming to what the SecKeychain
// layer expects.
Relation *Schema::createStandardRelation(RelationId relationId)
{
std::string relationName;
// Get the name based on the relation
switch (relationId)
{
case CSSM_DL_DB_RECORD_PRIVATE_KEY:
relationName = "CSSM_DL_DB_RECORD_PRIVATE_KEY"; break;
case CSSM_DL_DB_RECORD_PUBLIC_KEY:
relationName = "CSSM_DL_DB_RECORD_PUBLIC_KEY"; break;
case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
relationName = "CSSM_DL_DB_RECORD_SYMMETRIC_KEY"; break;
case CSSM_DL_DB_RECORD_X509_CERTIFICATE:
relationName = "CSSM_DL_DB_RECORD_X509_CERTIFICATE"; break;
case CSSM_DL_DB_RECORD_GENERIC:
relationName = "CSSM_DL_DB_RECORD_GENERIC"; break;
default: CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
}
Relation *rt = createRelation(relationName, relationId);
std::string
an_CertType = "CertType",
an_CertEncoding = "CertEncoding",
an_PrintName = "PrintName",
an_Alias = "Alias",
an_Subject = "Subject",
an_Issuer = "Issuer",
an_SerialNumber = "SerialNumber",
an_SubjectKeyIdentifier = "SubjectKeyIdentifier",
an_PublicKeyHash = "PublicKeyHash",
an_KeyClass = "KeyClass",
an_Permanent = "Permanent",
an_Private = "Private",
an_Modifiable = "Modifiable",
an_Label = "Label",
an_ApplicationTag = "ApplicationTag",
an_KeyCreator = "KeyCreator",
an_KeyType = "KeyType",
an_KeySizeInBits = "KeySizeInBits",
an_EffectiveKeySize = "EffectiveKeySize",
an_StartDate = "StartDate",
an_EndDate = "EndDate",
an_Sensitive = "Sensitive",
an_AlwaysSensitive = "AlwaysSensitive",
an_Extractable = "Extractable",
an_NeverExtractable = "NeverExtractable",
an_Encrypt = "Encrypt",
an_Decrypt = "Decrypt",
an_Derive = "Derive",
an_Sign = "Sign",
an_Verify = "Verify",
an_SignRecover = "SignRecover",
an_VerifyRecover = "VerifyRecover",
an_Wrap = "Wrap",
an_Unwrap = "Unwrap";
// @@@ HARDWIRED Based on what SecKeychain layer expects @@@
switch (relationId)
{
case CSSM_DL_DB_RECORD_GENERIC:
createAttribute(*rt, &an_PrintName, kSecLabelItemAttr, kAF_BLOB, false)
.attributeCoder(&mDescriptionCoder);
createAttribute(*rt, &an_Alias, kSecAlias, kAF_BLOB, false)
.attributeCoder(&mZeroCoder);
rt->metaRecord().attributeCoderForData(&mDataAttributeCoder);
break;
case CSSM_DL_DB_RECORD_X509_CERTIFICATE:
createAttribute(*rt, &an_CertType, kSecCertTypeItemAttr,
kAF_UINT32, true).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_CertEncoding, kSecCertEncodingItemAttr,
kAF_UINT32, false).attributeCoder(&mCertEncodingBERCoder);
createAttribute(*rt, &an_PrintName, kSecLabelItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_Alias, kSecAlias,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_Subject, kSecSubjectItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_Issuer, kSecIssuerItemAttr,
kAF_BLOB, true).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_SerialNumber, kSecSerialNumberItemAttr,
kAF_BLOB, true).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_SubjectKeyIdentifier,
kSecSubjectKeyIdentifierItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_PublicKeyHash, kSecPublicKeyHashItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
rt->metaRecord().attributeCoderForData(&mDataAttributeCoder);
// Initialize mPublicKeyHashCoder so it knows which attribute of a
// certificate to use to get the public key hash of a key.
mPublicKeyHashCoder.setCertificateMetaAttribute(&(rt->metaRecord()
.metaAttribute(kSecPublicKeyHashItemAttr)));
break;
case CSSM_DL_DB_RECORD_PUBLIC_KEY:
case CSSM_DL_DB_RECORD_PRIVATE_KEY:
case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
rt->metaRecord().attributeCoderForData(&mKeyDataCoder);
createAttribute(*rt, &an_KeyClass, kSecKeyKeyClass,
kAF_UINT32, false).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY
? &mPublicKeyClassCoder
: relationId == CSSM_DL_DB_RECORD_PRIVATE_KEY
? &mPrivateKeyClassCoder
: &mSessionKeyClassCoder);
createAttribute(*rt, &an_PrintName, kSecKeyPrintName,
kAF_BLOB, false).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_Alias, kSecKeyAlias,
kAF_BLOB, false).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_Permanent, kSecKeyPermanent,
kAF_UINT32, false).attributeCoder(&mTrueCoder);
createAttribute(*rt, &an_Private, kSecKeyPrivate,
kAF_UINT32, false).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY
? &mFalseCoder : &mTrueCoder);
createAttribute(*rt, &an_Modifiable, kSecKeyModifiable,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_Label, kSecKeyLabel,
kAF_BLOB, true).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PRIVATE_KEY
? &mPublicKeyHashCoder : NULL);
createAttribute(*rt, &an_ApplicationTag, kSecKeyApplicationTag,
kAF_BLOB, true).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_KeyCreator, kSecKeyKeyCreator,
kAF_BLOB, true).attributeCoder(&mSdCSPDLGuidCoder);
createAttribute(*rt, &an_KeyType, kSecKeyKeyType, kAF_UINT32, true);
createAttribute(*rt, &an_KeySizeInBits, kSecKeyKeySizeInBits,
kAF_UINT32, true);
createAttribute(*rt, &an_EffectiveKeySize, kSecKeyEffectiveKeySize,
kAF_UINT32, true);
createAttribute(*rt, &an_StartDate, kSecKeyStartDate,
kAF_TIME_DATE, true).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_EndDate, kSecKeyEndDate,
kAF_TIME_DATE, true).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_Sensitive, kSecKeySensitive,
kAF_UINT32, false).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY
? &mFalseCoder : &mTrueCoder);
createAttribute(*rt, &an_AlwaysSensitive, kSecKeyAlwaysSensitive,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_Extractable, kSecKeyExtractable,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_NeverExtractable, kSecKeyNeverExtractable,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_Encrypt, kSecKeyEncrypt, kAF_UINT32, false);
createAttribute(*rt, &an_Decrypt, kSecKeyDecrypt, kAF_UINT32, false);
createAttribute(*rt, &an_Derive, kSecKeyDerive, kAF_UINT32, false);
createAttribute(*rt, &an_Sign, kSecKeySign, kAF_UINT32, false);
createAttribute(*rt, &an_Verify, kSecKeyVerify, kAF_UINT32, false);
createAttribute(*rt, &an_SignRecover, kSecKeySignRecover,
kAF_UINT32, false);
createAttribute(*rt, &an_VerifyRecover, kSecKeyVerifyRecover,
kAF_UINT32, false);
createAttribute(*rt, &an_Wrap, kSecKeyWrap, kAF_UINT32, false);
createAttribute(*rt, &an_Unwrap, kSecKeyUnwrap, kAF_UINT32, false);
// Initialize mPublicKeyHashCoder so it knows which attribute of a
// public key to use to get the public key hash of a key.
if (relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY)
mPublicKeyHashCoder.setPublicKeyMetaAttribute(&(rt->metaRecord()
.metaAttribute(kSecKeyLabel)));
break;
}
return rt;
}
// Create a new relation using metaRecord. Does not register this in the
// CSSM_DL_DB_SCHEMA_INFO relation. This is used for creating the schema
// relations themselves only.
Relation *Schema::createRelation(MetaRecord *metaRecord)
{
auto_ptr<Relation> aRelation(new Relation(metaRecord));
if (!mRelationMap.insert(RelationMap::value_type(metaRecord->relationId(),
aRelation.get())).second)
{
// @@@ Should be CSSMERR_DL_DUPLICATE_RECORDTYPE. Since that
// doesn't exist we report that the meta-relation's unique index would
// no longer be valid
CssmError::throwMe(CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA);
}
return aRelation.release();
}
// Create a new relation and register this in the CSSM_DL_DB_SCHEMA_INFO
// relation.
Relation *Schema::createRelation(const std::string &relationName,
RelationId relationId)
{
MetaRecord *mr = new MetaRecord(relationId);
Relation *rt = createRelation(mr);
registerRelation(relationName, relationId);
return rt;
}
// Create a new attribute and register this with the schema. Do not use this
// for creating schema relations.
MetaAttribute &Schema::createAttribute(Relation &relation,
const std::string *name, uint32 attributeId,
CSSM_DB_ATTRIBUTE_FORMAT attributeFormat, bool isIndex)
{
MetaRecord &mr = relation.metaRecord();
registerAttribute(mr.relationId(), name, attributeId, attributeFormat,
isIndex);
return mr.createAttribute(name, NULL, attributeId, attributeFormat);
}
// Insert a record containing a relationId and it's name into
// CSSM_DL_DB_SCHEMA_INFO relation
void Schema::registerRelation(const std::string &relationName,
RelationId relationId)
{
RefPointer<Record> record = new Record();
record->attributeAtIndex(io_rid, new Attribute(relationId));
record->attributeAtIndex(io_rn, new Attribute(relationName));
mInfo->insertRecord(record);
}
// Insert a record containing a relationId, attributeId and other meta
// information into the CSSM_DL_DB_SCHEMA_ATTRIBUTES relation. In addition, if
// isIndex is true insert a record into the CSSM_DL_DB_SCHEMA_INDEXES relation.
void Schema::registerAttribute(RelationId relationId, const std::string *name,
uint32 attributeId, CSSM_DB_ATTRIBUTE_FORMAT attributeFormat, bool isIndex)
{
CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat = name
? CSSM_DB_ATTRIBUTE_NAME_AS_STRING : CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
RefPointer<Record> rc_attribute = new Record();
rc_attribute->attributeAtIndex(as_rid, new Attribute(relationId));
rc_attribute->attributeAtIndex(as_aid, new Attribute(attributeId));
rc_attribute->attributeAtIndex(as_anf, new Attribute(nameFormat));
rc_attribute->attributeAtIndex(as_an, name
? new Attribute(*name) : new Attribute()); // AttributeName
rc_attribute->attributeAtIndex(as_anid, new Attribute());// AttributeNameId
rc_attribute->attributeAtIndex(as_af, new Attribute(attributeFormat));
mAttributes->insertRecord(rc_attribute);
if (isIndex)
{
RefPointer<Record> rc_index = new Record();
rc_index->attributeAtIndex(ix_rid, // RelationId
new Attribute(relationId));
rc_index->attributeAtIndex(ix_iid, // IndexId
new Attribute(uint32(0)));
rc_index->attributeAtIndex(ix_aid, // AttributeId
new Attribute(attributeId));
rc_index->attributeAtIndex(ix_it, // IndexType
new Attribute(uint32(CSSM_DB_INDEX_UNIQUE)));
rc_index->attributeAtIndex(ix_idl, // IndexedDataLocation
new Attribute(uint32(CSSM_DB_INDEX_ON_UNKNOWN)));
mIndices->insertRecord(rc_index);
}
}
#pragma mark ---------------- Utility methods --------------
const Relation &Schema::findRelation(RelationId inRelationId) const
{
RelationMap::const_iterator it = mRelationMap.find(inRelationId);
if (it == mRelationMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
return *it->second;
}
Relation &Schema::findRelation(RelationId inRelationId)
{
RelationMap::iterator it = mRelationMap.find(inRelationId);
if (it == mRelationMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
return *it->second;
}
MetaRecord &Schema::findMetaRecord(RelationId inRelationId)
{
return findRelation(inRelationId).metaRecord();
}
} // end namespace Tokend
--- NEW FILE Schema.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Schema.h
* TokendMuscle
*/
#ifndef _TOKEND_SCHEMA_H_
#define _TOKEND_SCHEMA_H_
#include <security_cdsa_utilities/cssmdata.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <map>
#include "MetaRecord.h"
#include "Relation.h"
#include "AttributeCoder.h"
namespace Tokend
{
class Relation;
//
// Schema
//
class Schema
{
NOCOPY(Schema)
public:
typedef std::map<RelationId, Relation *> RelationMap;
typedef RelationMap::const_iterator ConstRelationMapIterator;
Schema();
virtual ~Schema();
virtual void create();
const Relation &findRelation(RelationId inRelationId) const;
Relation &findRelation(RelationId inRelationId);
MetaRecord &findMetaRecord(RelationId inRelationId);
ConstRelationMapIterator begin() const { return mRelationMap.begin(); }
ConstRelationMapIterator end() const { return mRelationMap.end(); }
const LinkedRecordAttributeCoder &publicKeyHashCoder() const
{ return mPublicKeyHashCoder; }
protected:
Relation *createRelation(const std::string &relationName,
RelationId relationId);
Relation *createStandardRelation(RelationId relationId);
MetaAttribute &createAttribute(Relation &relation,
const std::string *name, uint32 attributeId,
CSSM_DB_ATTRIBUTE_FORMAT attributeFormat, bool isIndex);
private:
Relation *createRelation(MetaRecord *inMetaRecord);
void registerRelation(const std::string &relationName,
RelationId relationId);
void registerAttribute(RelationId relationId, const std::string *name,
uint32 attributeId, CSSM_DB_ATTRIBUTE_FORMAT attributeFormat,
bool isIndex);
private:
Relation *mInfo, *mAttributes, *mIndices;
RelationMap mRelationMap;
// AttributeIndices for attributes of CSSM_DL_DB_SCHEMA_INFO relation.
uint32 io_rid;
uint32 io_rn;
// AttributeIndices for attributes of CSSM_DL_DB_SCHEMA_ATTRIBUTES
// relation.
uint32 as_rid;
uint32 as_aid;
uint32 as_anf;
uint32 as_an;
uint32 as_anid;
uint32 as_af;
// AttributeIndices for attributes of CSSM_DL_DB_SCHEMA_INDEXES relation.
uint32 ix_rid;
uint32 ix_iid;
uint32 ix_aid;
uint32 ix_it;
uint32 ix_idl;
protected:
// Coders for some standard attributes
ConstAttributeCoder mTrueCoder;
ConstAttributeCoder mFalseCoder;
ConstAttributeCoder mCertEncodingBERCoder;
GuidAttributeCoder mSdCSPDLGuidCoder;
CertificateAttributeCoder mCertificateCoder;
ZeroAttributeCoder mZeroCoder;
ConstAttributeCoder mPublicKeyClassCoder;
ConstAttributeCoder mPrivateKeyClassCoder;
ConstAttributeCoder mSessionKeyClassCoder;
KeyDataAttributeCoder mKeyDataCoder;
LinkedRecordAttributeCoder mPublicKeyHashCoder;
DataAttributeCoder mDataAttributeCoder;
DescriptionAttributeCoder mDescriptionCoder;
};
} // end namespace Tokend
#endif /* !_TOKEND_SCHEMA_H_ */
--- NEW FILE SelectionPredicate.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* SelectionPredicate.cpp
* TokendMuscle
*/
#include "SelectionPredicate.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "DbValue.h"
#include <Security/cssmerr.h>
namespace Tokend
{
SelectionPredicate::SelectionPredicate(const MetaRecord &inMetaRecord,
const CSSM_SELECTION_PREDICATE &inPredicate)
: mMetaAttribute(inMetaRecord.metaAttribute(inPredicate.Attribute.Info)),
mDbOperator(inPredicate.DbOperator)
{
// Make sure that the caller specified the attribute values in the correct
// format.
if (inPredicate.Attribute.Info.AttributeFormat
!= mMetaAttribute.attributeFormat())
CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
// @@@ See ISSUES
if (inPredicate.Attribute.NumberOfValues != 1)
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
mData = inPredicate.Attribute.Value[0];
mValue = mMetaAttribute.createValue(mData);
}
SelectionPredicate::~SelectionPredicate()
{
delete mValue;
}
bool SelectionPredicate::evaluate(TokenContext *tokenContext,
Record& record) const
{
return mMetaAttribute.evaluate(tokenContext, mValue, record, mDbOperator);
}
} // end namespace Tokend
--- NEW FILE SelectionPredicate.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* SelectionPredicate.h
* TokendMuscle
*/
#ifndef _TOKEND_SELECTIONPREDICATE_H_
#define _TOKEND_SELECTIONPREDICATE_H_
#include <security_cdsa_utilities/cssmdata.h>
namespace Tokend
{
class DbValue;
class MetaAttribute;
class MetaRecord;
class Record;
class TokenContext;
class SelectionPredicate
{
NOCOPY(SelectionPredicate)
public:
SelectionPredicate(const MetaRecord &inMetaRecord,
const CSSM_SELECTION_PREDICATE &inPredicate);
~SelectionPredicate();
bool evaluate(TokenContext *tokenContext, Record& record) const;
private:
const MetaAttribute &mMetaAttribute;
CSSM_DB_OPERATOR mDbOperator;
CssmDataContainer mData;
DbValue *mValue;
};
} // end namespace Tokend
#endif /* !_TOKEND_SELECTIONPREDICATE_H_ */
--- NEW FILE Token.cpp ---
/*
* Copyright (c) 2004,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@
*/
/*
* Token.cpp
* TokendMuscle
*/
#include "Token.h"
#include "Cursor.h"
#include "KeyHandle.h"
#include "RecordHandle.h"
#include "Schema.h"
#include <memory>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_utilities/unix++.h>
#include <security_utilities/logging.h>
//
// SPI wrapper macros
//
#define BEGIN try {
#define END(SS) \
return CSSM_OK; \
} catch (const CommonError &err) { \
return CssmError::cssmError(err, CSSM_##SS##_BASE_ERROR); \
} catch (...) { \
return CSSM_ERRCODE_INTERNAL_ERROR; \
}
//
// Singleton
//
Tokend::Token *token;
namespace Tokend
{
Token::Token() : mSchema(NULL), mTokenContext(NULL)
{
}
Token::~Token()
{
}
//
// Initial: Your first chance to do anything with the tokend framework
// initialized.
//
CSSM_RETURN Token::_initial()
{
BEGIN
token->initial();
secdebug("tokend", "using reader %s",
token->startupReaderInfo()->szReader);
END(CSSM)
}
//
// Probe:
// (1) See if we support this token. Return zero if not.
// Return a score if we do - the lower, the better. 1 beats everyone else.
// (2) Generate a unique id string for the token. This doesn't have to be
// human readable. If you REALLY can't make one up, leave tokenUid alone.
// But do try.
//
CSSM_RETURN Token::_probe(SecTokendProbeFlags flags, uint32 *score,
char tokenUid[TOKEND_MAX_UID])
{
BEGIN
*score = token->probe(flags, tokenUid);
secdebug("tokend", "flags=%d returning score=%d uid='%s'",
flags, *score, tokenUid);
END(CSSM)
}
//
// Establish:
// Okay, you're the one. The token is yours. Here's your GUID and subservice ID
// (in case you care); it'll get automatically inserted into your MDS unless
// you override it. If you can make up a nice, user-friendly print name for
// your token, return it in printName. If you can't, leave it alone and
// securityd will make something up for you.
//
CSSM_RETURN Token::_establish(const CSSM_GUID *guid, uint32 subserviceID,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
BEGIN
secdebug("tokend", "establish(%s,%d,0x%X)",
Guid::required(guid).toString().c_str(), subserviceID, flags);
token->establish(guid, subserviceID, flags, cacheDirectory, workDirectory,
mdsDirectory, printName);
// if printName is left alone, securityd will make one up
// if mdsDirectory is left alone, all MDS resources in the Resource bundle
// will be loaded
END(CSSM)
}
//
// Terminate() is called by security when it wants you to go away.
// This function does not (currently) return anything, so the CSSM_RETURN is
// effectively ignored. (It's still here for consistency's sake.)
//
CSSM_RETURN Token::_terminate(uint32 reason, uint32 options)
{
BEGIN
secdebug("tokend", "terminate(%d,0x%d)", reason, options);
token->terminate(reason, options);
END(CSSM)
}
CSSM_RETURN Token::_findFirst(const CSSM_QUERY *query,
TOKEND_RETURN_DATA *data, CSSM_HANDLE *hSearch)
{
BEGIN
std::auto_ptr<Cursor> curs(token->createCursor(query));
TokenContext *tokenContext = token->tokenContext();
std::auto_ptr<RecordHandle> rh(curs->next(tokenContext));
if (!rh.get())
{
#if 1
data->record = 0;
data->keyhandle = 0;
return 0;
#else
return CSSMERR_DL_ENDOFDATA;
#endif
}
rh->get(tokenContext, *data);
// Release the RecordHandle until the caller kills the handle we returned.
rh.release();
// We didn't throw so return a search handle and keep the Cursor around.
*hSearch = curs->handle();
curs.release();
END(DL)
}
CSSM_RETURN Token::_findNext(CSSM_HANDLE hSearch, TOKEND_RETURN_DATA *data)
{
BEGIN
Cursor& curs = Security::HandleObject::find<Cursor>(hSearch,
CSSMERR_DL_RECORD_NOT_FOUND);
TokenContext *tokenContext = token->tokenContext();
std::auto_ptr<RecordHandle> rh(curs.next(tokenContext));
if (!rh.get())
{
secdebug("tokend", "findNext(%ld) returning: CSSMERR_DL_ENDOFDATA",
hSearch);
#if 1
data->record = 0;
data->keyhandle = 0;
return 0;
#else
return CSSMERR_DL_ENDOFDATA;
#endif
}
rh->get(tokenContext, *data);
rh.release();
END(DL)
}
CSSM_RETURN Token::_findRecordHandle(CSSM_HANDLE hRecord,
TOKEND_RETURN_DATA *data)
{
BEGIN
secdebug("tokend", "findRecordHandle(%ld)", hRecord);
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.get(token->tokenContext(), *data);
END(DL)
}
CSSM_RETURN Token::_insertRecord(CSSM_DB_RECORDTYPE recordType,
const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, const CSSM_DATA *data,
CSSM_HANDLE *hRecord)
{
BEGIN
secdebug("tokend", "insertRecord");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(DL)
}
CSSM_RETURN Token::_modifyRecord(CSSM_DB_RECORDTYPE recordType,
CSSM_HANDLE *hRecord, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
const CSSM_DATA *data, CSSM_DB_MODIFY_MODE modifyMode)
{
BEGIN
secdebug("tokend", "modifyRecord");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(DL)
}
CSSM_RETURN Token::_deleteRecord(CSSM_HANDLE hRecord)
{
BEGIN
secdebug("tokend", "deleteRecord");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(DL)
}
CSSM_RETURN Token::_releaseSearch(CSSM_HANDLE hSearch)
{
BEGIN
secdebug("tokend", "releaseSearch(%ld)", hSearch);
Security::HandleObject::findAndKill<Cursor>(hSearch,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
END(DL)
}
CSSM_RETURN Token::_releaseRecord(CSSM_HANDLE hRecord)
{
BEGIN
secdebug("tokend", "releaseRecord(%ld)", hRecord);
Security::HandleObject::findAndKill<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
END(DL)
}
CSSM_RETURN Token::_freeRetrievedData(TOKEND_RETURN_DATA *data)
{
BEGIN
secdebug("tokend", "freeRetrievedData");
// Since we return pointers to our cached interal data this is also a noop
END(DL)
}
CSSM_RETURN Token::_releaseKey(CSSM_HANDLE hKey)
{
BEGIN
secdebug("tokend", "releaseKey(%ld)", hKey);
Security::HandleObject::findAndKill<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
END(CSP)
}
CSSM_RETURN Token::_getKeySize(CSSM_HANDLE hKey, CSSM_KEY_SIZE *size)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.getKeySize(Required(size));
END(CSP)
}
CSSM_RETURN Token::_getOutputSize(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, uint32 inputSize, CSSM_BOOL encrypting,
uint32 *outputSize)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
Required(outputSize) = key.getOutputSize(Context::required(context),
inputSize, encrypting);
END(CSP)
}
CSSM_RETURN Token::_generateSignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
CSSM_DATA *signature)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.generateSignature(Context::required(context), signOnly,
CssmData::required(input), CssmData::required(signature));
END(CSP)
}
CSSM_RETURN Token::_verifySignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
const CSSM_DATA *signature)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.verifySignature(Context::required(context), signOnly,
CssmData::required(input), CssmData::required(signature));
END(CSP)
}
CSSM_RETURN Token::_generateMac(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *input, CSSM_DATA *output)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.generateMac(Context::required(context), CssmData::required(input),
CssmData::required(output));
END(CSP)
}
CSSM_RETURN Token::_verifyMac(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *input, const CSSM_DATA *compare)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.verifyMac(Context::required(context), CssmData::required(input),
CssmData::required(compare));
END(CSP)
}
CSSM_RETURN Token::_encrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *clear, CSSM_DATA *cipher)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.encrypt(Context::required(context), CssmData::required(clear),
CssmData::required(cipher));
END(CSP)
}
CSSM_RETURN Token::_decrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *cipher, CSSM_DATA *clear)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.decrypt(Context::required(context), CssmData::required(cipher),
CssmData::required(clear));
END(CSP)
}
CSSM_RETURN Token::_generateKey(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attrs, CSSM_HANDLE *hKey, CSSM_KEY *header)
{
BEGIN
secdebug("tokend", "generateKey");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(CSP)
}
CSSM_RETURN Token::_generateKeyPair(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner,
CSSM_KEYUSE pubUsage, CSSM_KEYATTR_FLAGS pubAttrs,
CSSM_KEYUSE privUsage, CSSM_KEYATTR_FLAGS privAttrs,
CSSM_HANDLE *hPubKey, CSSM_KEY *pubHeader,
CSSM_HANDLE *hPrivKey, CSSM_KEY *privHeader)
{
BEGIN
secdebug("tokend", "generateKeyPair");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(CSP)
}
CSSM_RETURN Token::_wrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
CSSM_HANDLE hSubjectKey, const CSSM_KEY *subjectKey,
const CSSM_DATA *descriptiveData, CSSM_KEY *wrappedKey)
{
BEGIN
KeyHandle *subjectKeyHandle = hSubjectKey
? &Security::HandleObject::find<KeyHandle>(hSubjectKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE) : NULL;
KeyHandle *wrappingKeyHandle = hWrappingKey
? &Security::HandleObject::find<KeyHandle>(hWrappingKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE) : NULL;
if (subjectKeyHandle)
{
subjectKeyHandle->wrapUsingKey(Context::required(context),
AccessCredentials::optional(cred),
wrappingKeyHandle, CssmKey::optional(wrappingKey),
CssmData::optional(descriptiveData),
CssmKey::required(wrappedKey));
}
else if (wrappingKeyHandle)
{
wrappingKeyHandle->wrapKey(Context::required(context),
CssmKey::required(subjectKey),
CssmData::optional(descriptiveData),
CssmKey::required(wrappedKey));
}
else
{
secdebug("tokend",
"wrapKey without a reference subject or wrapping key not supported"
);
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
END(CSP)
}
CSSM_RETURN Token::_unwrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access,
CSSM_HANDLE hPublicKey, const CSSM_KEY *publicKey,
const CSSM_KEY *wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CSSM_DATA *descriptiveData,
CSSM_HANDLE *hUnwrappedKey, CSSM_KEY *unwrappedKey)
{
BEGIN
if (hWrappingKey)
{
KeyHandle &unwrappingKey =
Security::HandleObject::find<KeyHandle>(hWrappingKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
if (hPublicKey)
{
secdebug("tokend", "unwrapKey with a public key not supported");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
unwrappingKey.unwrapKey(Context::required(context),
AccessCredentials::optional(cred),
AclEntryPrototype::optional(access), CssmKey::required(wrappedKey),
usage, attributes, CssmData::optional(descriptiveData),
*hUnwrappedKey, CssmKey::required(unwrappedKey));
}
else
{
secdebug("tokend",
"unwrapKey without a wrapping key not supported (import)");
/* There is no key doing the unwrap so this is basically an import. */
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
END(CSP)
}
CSSM_RETURN Token::_deriveKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hSourceKey, const CSSM_KEY *sourceKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access, CSSM_DATA *parameters,
CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attributes,
CSSM_HANDLE *hKey, CSSM_KEY *key)
{
BEGIN
secdebug("tokend", "deriveKey");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(CSP)
}
CSSM_RETURN Token::_getObjectOwner(CSSM_HANDLE hRecord,
CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "getObjectOwner");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.getOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_getObjectAcl(CSSM_HANDLE hRecord,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries)
{
BEGIN
secdebug("tokend", "getObjectAcl");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.getAcl(tag, Required(count), AclEntryInfo::overlayVar(*entries));
END(DL)
}
CSSM_RETURN Token::_getDatabaseOwner(CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
token->getOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_getDatabaseAcl(const char *tag, uint32 *count,
CSSM_ACL_ENTRY_INFO **entries)
{
BEGIN
token->getAcl(tag, *count, AclEntryInfo::overlayVar(*entries));
END(DL)
}
CSSM_RETURN Token::_getKeyOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.getOwner(AclOwnerPrototype::required(owner));
END(CSP)
}
CSSM_RETURN Token::_getKeyAcl(CSSM_HANDLE hKey,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.getAcl(tag, Required(count), AclEntryInfo::overlayVar(*entries));
END(CSP)
}
CSSM_RETURN Token::_freeOwnerData(CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
// @@@ Do something here based on how we return data above.
END(CSP)
}
CSSM_RETURN Token::_freeAclData(uint32 count, CSSM_ACL_ENTRY_INFO *entries)
{
BEGIN
#if 0
AutoAclEntryInfoList aclList(&Allocator::standard());
// Invoke braindead overloaded operators since there are no setters on
// AutoAclEntryInfoList
*static_cast<uint32 *>(aclList) = count;
*static_cast<CSSM_ACL_ENTRY_INFO_PTR *>(aclList) = entries;
#endif
END(CSP)
}
CSSM_RETURN Token::_authenticateDatabase(CSSM_DB_ACCESS_TYPE mode,
const CSSM_ACCESS_CREDENTIALS *cred)
{
BEGIN
secdebug("tokend", "authenticateDatabase");
token->authenticate(mode, AccessCredentials::overlay(cred));
END(DL)
}
CSSM_RETURN Token::_changeDatabaseOwner(const CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "changeDatabaseOwner");
token->changeOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_changeDatabaseAcl(const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_EDIT *edit)
{
BEGIN
secdebug("tokend", "changeDatabaseAcl");
token->changeAcl(AccessCredentials::required(cred),
AclEdit::required(edit));
END(DL)
}
CSSM_RETURN Token::_changeObjectOwner(CSSM_HANDLE hRecord,
const CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "changeObjectOwner");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.changeOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_changeObjectAcl(CSSM_HANDLE hRecord,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit)
{
BEGIN
secdebug("tokend", "changeObjectAcl");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.changeAcl(AccessCredentials::required(cred), AclEdit::required(edit));
END(DL)
}
CSSM_RETURN Token::_changeKeyOwner(CSSM_HANDLE hKey,
const CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "changeKeyOwner");
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.changeOwner(AclOwnerPrototype::required(owner));
END(CSP)
}
CSSM_RETURN Token::_changeKeyAcl(CSSM_HANDLE hKey,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit)
{
BEGIN
secdebug("tokend", "changeKeyAcl");
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.changeAcl(AccessCredentials::required(cred), AclEdit::required(edit));
END(CSP)
}
CSSM_RETURN Token::_generateRandom(const CSSM_CONTEXT *context,
CSSM_DATA *result)
{
BEGIN
secdebug("tokend", "generateRandom");
token->generateRandom(Context::required(context),
CssmData::required(result));
END(CSP)
}
CSSM_RETURN Token::_getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS *result)
{
BEGIN
secdebug("tokend", "getStatistics");
token->getStatistics(Required(result));
END(CSP)
}
CSSM_RETURN Token::_getTime(CSSM_ALGORITHMS algorithm, CSSM_DATA *result)
{
BEGIN
secdebug("tokend", "getTime");
token->getTime(algorithm, CssmData::required(result));
END(CSP)
}
CSSM_RETURN Token::_getCounter(CSSM_DATA *result)
{
BEGIN
secdebug("tokend", "getCounter");
token->getCounter(CssmData::required(result));
END(CSP)
}
CSSM_RETURN Token::_selfVerify()
{
BEGIN
secdebug("tokend", "selfVerify");
token->selfVerify();
END(CSP)
}
CSSM_RETURN Token::_cspPassThrough(uint32 id, const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_KEY *key, const CSSM_DATA *input,
CSSM_DATA *output)
{
BEGIN
secdebug("tokend", "cspPassThrough");
CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID);
END(CSP)
}
CSSM_RETURN Token::_dlPassThrough(uint32 id, const CSSM_DATA *input,
CSSM_DATA *output)
{
BEGIN
secdebug("tokend", "dlPassThrough");
CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID);
END(DL)
}
CSSM_RETURN Token::_isLocked(uint32 *locked)
{
BEGIN
secdebug("tokend", "_isLocked");
Required(locked) = token->isLocked();
secdebug("tokend", "_isLocked: ", *locked);
END(DL)
}
//
// Callback vector into SecTokendMain
//
const SecTokendCallbacks Token::mCallbacks = {
kSecTokendCallbackVersion,
kSecTokendCallbacksDefault,
_initial, _probe, _establish, _terminate,
_findFirst, _findNext, _findRecordHandle,
_insertRecord, _modifyRecord, _deleteRecord,
_releaseSearch, _releaseRecord,
_freeRetrievedData,
_releaseKey, _getKeySize, _getOutputSize,
_generateSignature, _verifySignature,
_generateMac, _verifyMac,
_encrypt, _decrypt,
_generateKey, _generateKeyPair,
_wrapKey, _unwrapKey, _deriveKey,
_getDatabaseOwner, _getDatabaseAcl,
_getObjectOwner, _getObjectAcl,
_getKeyOwner, _getKeyAcl,
_freeOwnerData, _freeAclData,
_authenticateDatabase,
_changeDatabaseOwner, _changeDatabaseAcl,
_changeObjectOwner, _changeObjectAcl,
_changeKeyOwner, _changeKeyAcl,
_generateRandom, _getStatistics,
_getTime, _getCounter,
_selfVerify,
_cspPassThrough, _dlPassThrough,
_isLocked
};
const SecTokendCallbacks *Token::callbacks()
{
return &mCallbacks;
}
SecTokendSupport *Token::support()
{
return this;
}
void Token::initial()
{
}
void Token::terminate(uint32 reason, uint32 options)
{
}
void Token::establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
secdebug("establish", "cacheDirectory %s", cacheDirectory);
mGuid = *guid;
mSubserviceId = subserviceId;
mCacheDirectory = cacheDirectory;
}
bool Token::cachedObject(CSSM_DB_RECORDTYPE relationId,
const std::string &name, CssmData &object) const
{
try
{
UnixPlusPlus::AutoFileDesc fd(cachedObjectPath(relationId, name));
object.Length = fd.fileSize();
object.Data = reinterpret_cast<uint8 *>(malloc(object.Length));
object.Length = fd.readAll(object.Data, object.Length);
}
catch (const UnixError &error)
{
return false;
}
return true;
}
void Token::cacheObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
const CssmData &object) const
{
std::string path(cachedObjectPath(relationId, name));
try
{
UnixPlusPlus::AutoFileDesc fd(path, O_WRONLY|O_CREAT|O_TRUNC);
fd.writeAll(object.Data, object.Length);
}
catch (const UnixError &e)
{
Syslog::error("error writing cache file: %s: %s\n", path.c_str(),
strerror(e.unixError()));
::unlink(path.c_str());
}
}
std::string Token::cachedObjectPath(CSSM_DB_RECORDTYPE relationId,
const std::string &name) const
{
char buffer[9];
sprintf(buffer, "%X", relationId);
return mCacheDirectory + "/" + buffer + "-" + name;
}
Cursor *Token::createCursor(const CSSM_QUERY *inQuery)
{
if (!inQuery || inQuery->RecordType == CSSM_DL_DB_RECORD_ANY
|| inQuery->RecordType == CSSM_DL_DB_RECORD_ALL_KEYS)
{
return new MultiCursor(inQuery, *mSchema);
}
const Relation &relation = mSchema->findRelation(inQuery->RecordType);
return new LinearCursor(inQuery, relation);
}
//
// Authenticate to the token
//
void Token::authenticate(CSSM_DB_ACCESS_TYPE mode,
const AccessCredentials *cred)
{
int pinNum = pinFromAclTag(cred->EntryTag);
if (!pinNum || !cred)
pinNum = -1; // No PIN in tag.
if (mode == CSSM_DB_ACCESS_RESET)
{
// A mode of CSSM_DB_ACCESS_RESET is a request to deauthenticate
// the card completely.
secdebug("authenticate", "unverifying PIN%d", pinNum);
return unverifyPIN(pinNum);
}
else if (cred && pinNum > 0)
{ // tag="PINk"; unlock a PIN
if (cred->size() != 1) // just one, please
CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
const TypedList &sample = (*cred)[0];
switch (sample.type())
{
case CSSM_SAMPLE_TYPE_PASSWORD:
case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD:
case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD:
{
CssmData &pin = sample[1].data();
return verifyPIN(pinNum, pin.Data, pin.Length);
}
default:
break;
}
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
else
secdebug("authenticate", "ignoring non-PIN authentication request");
}
void Token::changeOwner(const AclOwnerPrototype &owner)
{
// Default changeOwner on a token always fails.
CssmError::throwMe(CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED);
}
void Token::changeAcl(const AccessCredentials &cred, const AclEdit &edit)
{
// We don't allow adding or deleting of acls currently
switch (edit.mode())
{
case CSSM_ACL_EDIT_MODE_DELETE:
CssmError::throwMe(CSSM_ERRCODE_ACL_DELETE_FAILED);
case CSSM_ACL_EDIT_MODE_REPLACE:
break;
case CSSM_ACL_EDIT_MODE_ADD:
CssmError::throwMe(CSSM_ERRCODE_ACL_ADD_FAILED);
default:
CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_EDIT_MODE);
}
#if 0
// edit.handle() is the offset in mAclEntries of the acl we are replacing
uint32 ix = edit.handle();
if (ix >= mAclEntries.size())
CssmError::throwMe(CSSM_ERRCODE_ACL_REPLACE_FAILED);
// Now we have the actual AclEntryPrototype being changed
const AclEntryPrototype &oldProto = mAclEntries.at(ix).proto();
#endif
// Now get the new AclEntryPrototype for this entry.
const AclEntryInput *newEntry = edit.newEntry();
if (!newEntry)
CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
const AclEntryPrototype &newProto = newEntry->proto();
unsigned int pinNum = pinFromAclTag(newProto.EntryTag);
if (!pinNum)
CssmError::throwMe(CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED);
const TypedList &subject = newProto.subject();
switch (subject.type())
{
case CSSM_ACL_SUBJECT_TYPE_PASSWORD:
case CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD:
case CSSM_ACL_SUBJECT_TYPE_PROTECTED_PASSWORD:
break;
default:
CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
}
const CssmData &newPin = subject[1].data();
if (cred.size() != 1)
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
const TypedList &value = cred[0].value();
switch (value.type())
{
case CSSM_SAMPLE_TYPE_PASSWORD:
case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD:
case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD:
break;
default:
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
const CssmData &oldPin = value[1].data();
secdebug("tokend", "CHANGE PIN%d from \"%.*s\" to \"%.*s\"",
pinNum, static_cast<int>(oldPin.Length), oldPin.Data,
static_cast<int>(newPin.Length), newPin.Data);
changePIN(pinNum, oldPin.Data, oldPin.Length, newPin.Data, newPin.Length);
}
void Token::generateRandom(const Context &context, CssmData &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::getTime(CSSM_ALGORITHMS algorithm, CssmData &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::getCounter(CssmData &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::selfVerify()
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength)
{
// Default changePIN on a token always fails.
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
uint32_t Token::pinStatus(int pinNum)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength)
{
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
void Token::unverifyPIN(int pinNum)
{
}
bool Token::isLocked()
{
// Check pin1 by default. Subclasses may override.
return pinStatus(1) != 0x9000;
}
//
// ISO7816Token
//
ISO7816Token::ISO7816Token()
{
mPrintName[0]=0;
}
ISO7816Token::~ISO7816Token()
{
}
uint32 ISO7816Token::probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID])
{
const SCARD_READERSTATE &readerState = *(*startupReaderInfo)();
connect(mSession, readerState.szReader);
return 0;
}
void ISO7816Token::establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
secdebug("establish", "cacheDirectory %s, workDirectory: %s, name: %s",
cacheDirectory, workDirectory, mPrintName);
if (mPrintName[0])
::strlcpy(printName, mPrintName, PATH_MAX);
Token::establish(guid, subserviceId, flags, cacheDirectory,
workDirectory, mdsDirectory, printName);
if (!isConnected())
{
const SCARD_READERSTATE &readerState = *(*startupReaderInfo)();
connect(mSession, readerState.szReader);
}
}
uint16_t ISO7816Token::transmitAPDU(uint8_t cla, uint8_t ins, uint8_t p1,
uint8_t p2, size_t dataSize, const uint8_t *data,
size_t outputLength, std::vector<uint8_t> *output)
{
std::vector<uint8_t> apdu;
uint32_t lc = data ? dataSize : 0;
// Worst case we need this much
apdu.reserve(10 + lc);
apdu.push_back(cla);
apdu.push_back(ins);
apdu.push_back(p1);
apdu.push_back(p2);
if (lc > 0)
{
if (lc < 0x100)
{
// Normal length Lc
apdu.push_back(lc);
}
else if (lc < 0x10000)
{
// Extended length Lc
apdu.push_back(0);
apdu.push_back(lc >> 8);
apdu.push_back(lc);
}
else
{
// Lc too big.
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
}
apdu.insert(apdu.end(), data, data + dataSize);
}
if (output && outputLength > 0)
{
if (outputLength < 0x100)
{
// Normal length Le
apdu.push_back(outputLength);
}
else if (outputLength < 0x10000)
{
// Extended length Le
apdu.push_back(0);
apdu.push_back(outputLength >> 8);
apdu.push_back(outputLength);
}
else
{
// Le too big
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
}
// Append the response to what's already in output.
size_t oldSize = output->size();
// Make enough room for the data we are requesting plus the sw
output->resize(oldSize + outputLength + 2);
uint8_t *response = &output->at(oldSize);
size_t responseLength = outputLength + 2;
transmit(&apdu[0], apdu.size(), response, responseLength);
if (responseLength < 2)
{
output->resize(oldSize + responseLength);
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
}
uint16_t sw = (response[responseLength - 2] << 8)
+ response[responseLength - 1];
// Remove the sw from the output.
output->resize(oldSize + responseLength - 2);
return sw;
}
else
{
uint8_t response[2];
size_t responseLength = sizeof(response);
transmit(&apdu[0], apdu.size(), response, responseLength);
if (responseLength < 2)
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
return (response[responseLength - 2] << 8)
+ response[responseLength - 1];
}
}
void ISO7816Token::name(const char *printName)
{
// Set the printName
::strlcpy(mPrintName,printName,min(1+strlen(printName),size_t(PATH_MAX)));
}
} // end namespace Tokend
--- NEW FILE Token.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Token.h
* TokendMuscle
*/
#ifndef _TOKEND_TOKEN_H_
#define _TOKEND_TOKEN_H_
#include <SecurityTokend/SecTokend.h>
#include <security_utilities/osxcode.h>
#include <security_cdsa_utilities/context.h>
#include <security_cdsa_utilities/cssmpods.h>
#include <security_cdsa_utilities/cssmbridge.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <security_utilities/debugging.h>
#include <security_utilities/pcsc++.h>
#include <string>
#include "TokenContext.h"
namespace Tokend
{
class Cursor;
class Schema;
class TokenContext;
//
// "The" token
//
class Token : public SecTokendSupport
{
NOCOPY(Token)
public:
Token();
virtual ~Token();
bool cachedObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
CssmData &data) const;
void cacheObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
const CssmData &object) const;
virtual const SecTokendCallbacks *callbacks();
virtual SecTokendSupport *support();
virtual void initial();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]) = 0;
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
virtual void terminate(uint32 reason, uint32 options);
virtual void authenticate(CSSM_DB_ACCESS_TYPE mode,
const AccessCredentials *cred);
virtual void getOwner(AclOwnerPrototype &owner) = 0;
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&acls) = 0;
virtual Cursor *createCursor(const CSSM_QUERY *inQuery);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
virtual void generateRandom(const Context &context, CssmData &result);
virtual void getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS &result);
virtual void getTime(CSSM_ALGORITHMS algorithm, CssmData &result);
virtual void getCounter(CssmData &result);
virtual void selfVerify();
virtual void changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength);
virtual uint32_t pinStatus(int pinNum);
virtual void verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength);
virtual void unverifyPIN(int pinNum);
virtual bool isLocked();
TokenContext *tokenContext() { return mTokenContext; }
protected:
std::string cachedObjectPath(CSSM_DB_RECORDTYPE relationId,
const std::string &name) const;
static CSSM_RETURN _initial();
static CSSM_RETURN _probe(SecTokendProbeFlags flags, uint32 *score,
char tokenUid[TOKEND_MAX_UID]);
static CSSM_RETURN _establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
static CSSM_RETURN _terminate(uint32 reason, uint32 options);
static CSSM_RETURN _findFirst(const CSSM_QUERY *query,
TOKEND_RETURN_DATA *data, CSSM_HANDLE *hSearch);
static CSSM_RETURN _findNext(CSSM_HANDLE hSearch,
TOKEND_RETURN_DATA *data);
static CSSM_RETURN _findRecordHandle(CSSM_HANDLE hRecord,
TOKEND_RETURN_DATA *data);
static CSSM_RETURN _insertRecord(CSSM_DB_RECORDTYPE recordType,
const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, const CSSM_DATA *data,
CSSM_HANDLE *hRecord);
static CSSM_RETURN _modifyRecord(CSSM_DB_RECORDTYPE recordType,
CSSM_HANDLE *hRecord, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
const CSSM_DATA *data, CSSM_DB_MODIFY_MODE modifyMode);
static CSSM_RETURN _deleteRecord(CSSM_HANDLE hRecord);
static CSSM_RETURN _releaseSearch(CSSM_HANDLE hSearch);
static CSSM_RETURN _releaseRecord(CSSM_HANDLE hRecord);
static CSSM_RETURN _freeRetrievedData(TOKEND_RETURN_DATA *data);
static CSSM_RETURN _releaseKey(CSSM_HANDLE hKey);
static CSSM_RETURN _getKeySize(CSSM_HANDLE hKey, CSSM_KEY_SIZE *size);
static CSSM_RETURN _getOutputSize(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, uint32 inputSize, CSSM_BOOL encrypting,
uint32 *outputSize);
static CSSM_RETURN _generateSignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
CSSM_DATA *signature);
static CSSM_RETURN _verifySignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
const CSSM_DATA *signature);
static CSSM_RETURN _generateMac(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_DATA *input, CSSM_DATA *mac);
static CSSM_RETURN _verifyMac(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_DATA *input, const CSSM_DATA *mac);
static CSSM_RETURN _encrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *clear, CSSM_DATA *cipher);
static CSSM_RETURN _decrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *cipher, CSSM_DATA *clear);
static CSSM_RETURN _generateKey(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attrs, CSSM_HANDLE *hKey, CSSM_KEY *header);
static CSSM_RETURN _generateKeyPair(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner,
CSSM_KEYUSE pubUsage, CSSM_KEYATTR_FLAGS pubAttrs,
CSSM_KEYUSE privUsage, CSSM_KEYATTR_FLAGS privAttrs,
CSSM_HANDLE *hPubKey, CSSM_KEY *pubHeader,
CSSM_HANDLE *hPrivKey, CSSM_KEY *privHeader);
static CSSM_RETURN _wrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred, CSSM_HANDLE hSubjectKey,
const CSSM_KEY *subjectKey, const CSSM_DATA *descriptiveData,
CSSM_KEY *wrappedKey);
static CSSM_RETURN _unwrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access,
CSSM_HANDLE hPublicKey, const CSSM_KEY *publicKey,
const CSSM_KEY *wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CSSM_DATA *descriptiveData,
CSSM_HANDLE *hUnwrappedKey, CSSM_KEY *unwrappedKey);
static CSSM_RETURN _deriveKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hSourceKey, const CSSM_KEY *sourceKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access, CSSM_DATA *parameters,
CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attributes,
CSSM_HANDLE *hKey, CSSM_KEY *hKey);
static CSSM_RETURN _getObjectOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getObjectAcl(CSSM_HANDLE hKey,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _getDatabaseOwner(CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getDatabaseAcl(const char *tag, uint32 *count,
CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _getKeyOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getKeyAcl(CSSM_HANDLE hKey, const char *tag,
uint32 *count, CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _freeOwnerData(CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _freeAclData(uint32 count,
CSSM_ACL_ENTRY_INFO *entries);
static CSSM_RETURN _authenticateDatabase(CSSM_DB_ACCESS_TYPE mode,
const CSSM_ACCESS_CREDENTIALS *cred);
static CSSM_RETURN _changeDatabaseOwner(const CSSM_ACL_OWNER_PROTOTYPE *
owner);
static CSSM_RETURN _changeDatabaseAcl(const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _changeObjectOwner(CSSM_HANDLE hRecord,
const CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _changeObjectAcl(CSSM_HANDLE hRecord,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _changeKeyOwner(CSSM_HANDLE key,
const CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _changeKeyAcl(CSSM_HANDLE key,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _generateRandom(const CSSM_CONTEXT *context,
CSSM_DATA *result);
static CSSM_RETURN _getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS *result);
static CSSM_RETURN _getTime(CSSM_ALGORITHMS algorithm, CSSM_DATA *result);
static CSSM_RETURN _getCounter(CSSM_DATA *result);
static CSSM_RETURN _selfVerify();
static CSSM_RETURN _cspPassThrough(uint32 id, const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_KEY *key, const CSSM_DATA *input,
CSSM_DATA *output);
static CSSM_RETURN _dlPassThrough(uint32 id, const CSSM_DATA *input,
CSSM_DATA *output);
static CSSM_RETURN _isLocked(uint32 *locked);
private:
static const SecTokendCallbacks mCallbacks;
protected:
Schema *mSchema;
TokenContext *mTokenContext;
Guid mGuid;
uint32 mSubserviceId;
std::string mCacheDirectory;
};
class ISO7816Token : public Token, public TokenContext, public PCSC::Card
{
NOCOPY(ISO7816Token)
public:
ISO7816Token();
virtual ~ISO7816Token();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]);
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
uint16_t transmitAPDU(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2,
size_t dataSize = 0, const uint8_t *data = NULL,
size_t outputLength = 0, std::vector<uint8_t> *output = NULL);
protected:
PCSC::Session mSession;
char mPrintName[PATH_MAX];
virtual void name(const char *printName);
};
} // end namespace Tokend
//
// Singleton
//
extern Tokend::Token *token;
#endif /* !_TOKEND_TOKEN_H_ */
--- NEW FILE TokenContext.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* TokenContext.cpp
* TokendMuscle
*/
#include "TokenContext.h"
namespace Tokend
{
TokenContext::~TokenContext()
{
}
} // end namespace Tokend
--- NEW FILE TokenContext.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* TokenContext.h
* TokendMuscle
*/
#ifndef _TOKEND_TOKENCONTEXT_H_
#define _TOKEND_TOKENCONTEXT_H_
#include <security_utilities/utilities.h>
namespace Tokend
{
class TokenContext
{
NOCOPY(TokenContext)
public:
TokenContext() {}
virtual ~TokenContext() = 0;
};
} // end namespace Tokend
#endif /* !_TOKEND_TOKENCONTEXT_H_ */
14 years
esc/mac/Tokend-35209/Tokend.xcodeproj project.pbxproj, NONE, 1.1.2.2
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/Tokend.xcodeproj
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528/Tokend.xcodeproj
Added Files:
Tag: PKI_8_0_RTM_BRANCH
project.pbxproj
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE project.pbxproj ---
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 42;
objects = {
/* Begin PBXAggregateTarget section */
52B2601F0BC5A864007E00F1 /* world */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 52B260280BC5A864007E00F1 /* Build configuration list for PBXAggregateTarget "world" */;
buildPhases = (
);
dependencies = (
529252170BC6BEED00816597 /* PBXTargetDependency */,
);
name = world;
productName = world;
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
009F4D78111BACB400012078 /* coolkey.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D59111BACB400012078 /* coolkey.cpp */; };
009F4D79111BACB400012078 /* CoolKeyAttributeCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D5A111BACB400012078 /* CoolKeyAttributeCoder.cpp */; };
009F4D7A111BACB400012078 /* CoolKeyError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D5C111BACB400012078 /* CoolKeyError.cpp */; };
009F4D7B111BACB400012078 /* CoolKeyHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D5E111BACB400012078 /* CoolKeyHandle.cpp */; };
009F4D7C111BACB400012078 /* CoolKeyPK11.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D60111BACB400012078 /* CoolKeyPK11.cpp */; };
009F4D7D111BACB400012078 /* CoolKeyRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D62111BACB400012078 /* CoolKeyRecord.cpp */; };
009F4D7E111BACB400012078 /* CoolKeySchema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D64111BACB400012078 /* CoolKeySchema.cpp */; };
009F4D7F111BACB400012078 /* CoolKeyToken.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 009F4D66111BACB400012078 /* CoolKeyToken.cpp */; };
009F4D82111BACB400012078 /* coolkey_csp_capabilities.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 009F4D6C111BACB400012078 /* coolkey_csp_capabilities.mdsinfo */; };
009F4D83111BACB400012078 /* coolkey_csp_capabilities_common.mds in Resources */ = {isa = PBXBuildFile; fileRef = 009F4D6D111BACB400012078 /* coolkey_csp_capabilities_common.mds */; };
009F4D84111BACB400012078 /* coolkey_csp_primary.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 009F4D6E111BACB400012078 /* coolkey_csp_primary.mdsinfo */; };
009F4D85111BACB400012078 /* coolkey_dl_primary.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 009F4D6F111BACB400012078 /* coolkey_dl_primary.mdsinfo */; };
009F4D86111BACB400012078 /* coolkey_smartcard.mdsinfo in Resources */ = {isa = PBXBuildFile; fileRef = 009F4D70111BACB400012078 /* coolkey_smartcard.mdsinfo */; };
009F4DFF111BB1A700012078 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4CA8C4D606D6D19400F1BCC8 /* CoreFoundation.framework */; };
52B260320BC5A864007E00F1 /* Adornment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C1B9B6406DBF99F00014414 /* Adornment.cpp */; };
52B260330BC5A864007E00F1 /* Attribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9606DBF81800FA17D9 /* Attribute.cpp */; };
52B260340BC5A864007E00F1 /* AttributeCoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A8A06DBF81800FA17D9 /* AttributeCoder.cpp */; };
52B260350BC5A864007E00F1 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9806DBF81800FA17D9 /* Cursor.cpp */; };
52B260360BC5A864007E00F1 /* DbValue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9A06DBF81800FA17D9 /* DbValue.cpp */; };
52B260370BC5A864007E00F1 /* KeyHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C3C166E06F61D6F00FC8AAC /* KeyHandle.cpp */; };
52B260380BC5A864007E00F1 /* MetaAttribute.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9C06DBF81800FA17D9 /* MetaAttribute.cpp */; };
52B260390BC5A864007E00F1 /* MetaRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9E06DBF81800FA17D9 /* MetaRecord.cpp */; };
52B2603A0BC5A864007E00F1 /* Record.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134AA006DBF81800FA17D9 /* Record.cpp */; };
52B2603B0BC5A864007E00F1 /* RecordHandle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C55BAFC06DEABE500E4200A /* RecordHandle.cpp */; };
52B2603C0BC5A864007E00F1 /* Relation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A8E06DBF81800FA17D9 /* Relation.cpp */; };
52B2603D0BC5A864007E00F1 /* SCardError.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CC3947A0731A4DD00761DEE /* SCardError.cpp */; };
52B2603E0BC5A864007E00F1 /* Schema.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134AA206DBF81800FA17D9 /* Schema.cpp */; };
52B2603F0BC5A864007E00F1 /* SelectionPredicate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134AA406DBF81800FA17D9 /* SelectionPredicate.cpp */; };
52B260400BC5A864007E00F1 /* Token.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9006DBF81800FA17D9 /* Token.cpp */; };
52B260410BC5A864007E00F1 /* TokenContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C134A9206DBF81800FA17D9 /* TokenContext.cpp */; };
52B2604D0BC5A864007E00F1 /* Adornment.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C1B9B6306DBF99F00014414 /* Adornment.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B2604E0BC5A864007E00F1 /* Attribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9706DBF81800FA17D9 /* Attribute.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B2604F0BC5A864007E00F1 /* AttributeCoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A8B06DBF81800FA17D9 /* AttributeCoder.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260500BC5A864007E00F1 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9906DBF81800FA17D9 /* Cursor.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260510BC5A864007E00F1 /* DbValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9B06DBF81800FA17D9 /* DbValue.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260520BC5A864007E00F1 /* KeyHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C3C166D06F61D6F00FC8AAC /* KeyHandle.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260530BC5A864007E00F1 /* MetaAttribute.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9D06DBF81800FA17D9 /* MetaAttribute.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260540BC5A864007E00F1 /* MetaRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9F06DBF81800FA17D9 /* MetaRecord.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260550BC5A864007E00F1 /* Record.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134AA106DBF81800FA17D9 /* Record.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260560BC5A864007E00F1 /* RecordHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C55BAFB06DEABE500E4200A /* RecordHandle.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260570BC5A864007E00F1 /* Relation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A8F06DBF81800FA17D9 /* Relation.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260580BC5A864007E00F1 /* SCardError.h in Headers */ = {isa = PBXBuildFile; fileRef = 4CC394790731A4DD00761DEE /* SCardError.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B260590BC5A864007E00F1 /* Schema.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134AA306DBF81800FA17D9 /* Schema.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B2605A0BC5A864007E00F1 /* SelectionPredicate.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134AA506DBF81800FA17D9 /* SelectionPredicate.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B2605B0BC5A864007E00F1 /* Token.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9106DBF81800FA17D9 /* Token.h */; settings = {ATTRIBUTES = (Public, ); }; };
52B2605C0BC5A864007E00F1 /* TokenContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C134A9306DBF81800FA17D9 /* TokenContext.h */; settings = {ATTRIBUTES = (Public, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
00A5CAE9111A373900EBA8FC /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 52B2602D0BC5A864007E00F1;
remoteInfo = "libtokend (Upgraded)";
};
529252160BC6BEED00816597 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 52B2602D0BC5A864007E00F1;
remoteInfo = libtokend;
};
52B260DE0BC5A864007E00F1 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 52B2604B0BC5A864007E00F1;
remoteInfo = "tokend (Upgraded)";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
009F4D59111BACB400012078 /* coolkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = coolkey.cpp; sourceTree = "<group>"; };
009F4D5A111BACB400012078 /* CoolKeyAttributeCoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeyAttributeCoder.cpp; sourceTree = "<group>"; };
009F4D5B111BACB400012078 /* CoolKeyAttributeCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeyAttributeCoder.h; sourceTree = "<group>"; };
009F4D5C111BACB400012078 /* CoolKeyError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeyError.cpp; sourceTree = "<group>"; };
009F4D5D111BACB400012078 /* CoolKeyError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeyError.h; sourceTree = "<group>"; };
009F4D5E111BACB400012078 /* CoolKeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeyHandle.cpp; sourceTree = "<group>"; };
009F4D5F111BACB400012078 /* CoolKeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeyHandle.h; sourceTree = "<group>"; };
009F4D60111BACB400012078 /* CoolKeyPK11.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeyPK11.cpp; sourceTree = "<group>"; };
009F4D61111BACB400012078 /* CoolKeyPK11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeyPK11.h; sourceTree = "<group>"; };
009F4D62111BACB400012078 /* CoolKeyRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeyRecord.cpp; sourceTree = "<group>"; };
009F4D63111BACB400012078 /* CoolKeyRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeyRecord.h; sourceTree = "<group>"; };
009F4D64111BACB400012078 /* CoolKeySchema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeySchema.cpp; sourceTree = "<group>"; };
009F4D65111BACB400012078 /* CoolKeySchema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeySchema.h; sourceTree = "<group>"; };
009F4D66111BACB400012078 /* CoolKeyToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CoolKeyToken.cpp; sourceTree = "<group>"; };
009F4D67111BACB400012078 /* CoolKeyToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CoolKeyToken.h; sourceTree = "<group>"; };
009F4D68111BACB400012078 /* dlfcn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dlfcn.h; sourceTree = "<group>"; };
009F4D69111BACB400012078 /* dlfcn.h.orig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = dlfcn.h.orig; sourceTree = "<group>"; };
009F4D6C111BACB400012078 /* coolkey_csp_capabilities.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_csp_capabilities.mdsinfo; sourceTree = "<group>"; };
009F4D6D111BACB400012078 /* coolkey_csp_capabilities_common.mds */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_csp_capabilities_common.mds; sourceTree = "<group>"; };
009F4D6E111BACB400012078 /* coolkey_csp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_csp_primary.mdsinfo; sourceTree = "<group>"; };
009F4D6F111BACB400012078 /* coolkey_dl_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_dl_primary.mdsinfo; sourceTree = "<group>"; };
009F4D70111BACB400012078 /* coolkey_smartcard.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_smartcard.mdsinfo; sourceTree = "<group>"; };
009F4D73111BACB400012078 /* cryptoki.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cryptoki.h; sourceTree = "<group>"; };
009F4D74111BACB400012078 /* mypkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mypkcs11.h; sourceTree = "<group>"; };
009F4D75111BACB400012078 /* pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pkcs11.h; sourceTree = "<group>"; };
009F4D76111BACB400012078 /* pkcs11f.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pkcs11f.h; sourceTree = "<group>"; };
009F4D77111BACB400012078 /* pkcs11t.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pkcs11t.h; sourceTree = "<group>"; };
00A5CAAD111A358200EBA8FC /* coolkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = coolkey.cpp; path = CoolKey/coolkey.cpp; sourceTree = "<group>"; };
00A5CAAE111A358200EBA8FC /* CoolKeyAttributeCoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeyAttributeCoder.cpp; path = CoolKey/CoolKeyAttributeCoder.cpp; sourceTree = "<group>"; };
00A5CAAF111A358200EBA8FC /* CoolKeyAttributeCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeyAttributeCoder.h; path = CoolKey/CoolKeyAttributeCoder.h; sourceTree = "<group>"; };
00A5CAB0111A358200EBA8FC /* CoolKeyError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeyError.cpp; path = CoolKey/CoolKeyError.cpp; sourceTree = "<group>"; };
00A5CAB1111A358200EBA8FC /* CoolKeyError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeyError.h; path = CoolKey/CoolKeyError.h; sourceTree = "<group>"; };
00A5CAB2111A358200EBA8FC /* CoolKeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeyHandle.cpp; path = CoolKey/CoolKeyHandle.cpp; sourceTree = "<group>"; };
00A5CAB3111A358200EBA8FC /* CoolKeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeyHandle.h; path = CoolKey/CoolKeyHandle.h; sourceTree = "<group>"; };
00A5CAB4111A358200EBA8FC /* CoolKeyPK11.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeyPK11.cpp; path = CoolKey/CoolKeyPK11.cpp; sourceTree = "<group>"; };
00A5CAB5111A358200EBA8FC /* CoolKeyPK11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeyPK11.h; path = CoolKey/CoolKeyPK11.h; sourceTree = "<group>"; };
00A5CAB6111A358200EBA8FC /* CoolKeyRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeyRecord.cpp; path = CoolKey/CoolKeyRecord.cpp; sourceTree = "<group>"; };
00A5CAB7111A358200EBA8FC /* CoolKeyRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeyRecord.h; path = CoolKey/CoolKeyRecord.h; sourceTree = "<group>"; };
00A5CAB8111A358200EBA8FC /* CoolKeySchema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeySchema.cpp; path = CoolKey/CoolKeySchema.cpp; sourceTree = "<group>"; };
00A5CAB9111A358200EBA8FC /* CoolKeySchema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeySchema.h; path = CoolKey/CoolKeySchema.h; sourceTree = "<group>"; };
00A5CABA111A358200EBA8FC /* CoolKeyToken.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CoolKeyToken.cpp; path = CoolKey/CoolKeyToken.cpp; sourceTree = "<group>"; };
00A5CABB111A358200EBA8FC /* CoolKeyToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoolKeyToken.h; path = CoolKey/CoolKeyToken.h; sourceTree = "<group>"; };
00A5CABD111A358200EBA8FC /* Entries */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Entries; sourceTree = "<group>"; };
00A5CABE111A358200EBA8FC /* Repository */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Repository; sourceTree = "<group>"; };
00A5CABF111A358200EBA8FC /* Root */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Root; sourceTree = "<group>"; };
00A5CAC0111A358200EBA8FC /* Tag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Tag; sourceTree = "<group>"; };
00A5CAC1111A358200EBA8FC /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = CoolKey/Info.plist; sourceTree = "<group>"; };
00A5CAC3111A358200EBA8FC /* coolkey_csp_capabilities.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_csp_capabilities.mdsinfo; sourceTree = "<group>"; };
00A5CAC4111A358200EBA8FC /* coolkey_csp_capabilities_common.mds */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_csp_capabilities_common.mds; sourceTree = "<group>"; };
00A5CAC5111A358200EBA8FC /* coolkey_csp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_csp_primary.mdsinfo; sourceTree = "<group>"; };
00A5CAC6111A358200EBA8FC /* coolkey_dl_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_dl_primary.mdsinfo; sourceTree = "<group>"; };
00A5CAC7111A358200EBA8FC /* coolkey_smartcard.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = coolkey_smartcard.mdsinfo; sourceTree = "<group>"; };
00A5CAC9111A358200EBA8FC /* compile.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = compile.sh; sourceTree = "<group>"; };
00A5CACA111A358200EBA8FC /* cryptoki.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cryptoki.h; sourceTree = "<group>"; };
00A5CACB111A358200EBA8FC /* mypkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mypkcs11.h; sourceTree = "<group>"; };
00A5CACC111A358200EBA8FC /* pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pkcs11.h; sourceTree = "<group>"; };
00A5CACD111A358200EBA8FC /* pkcs11f.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pkcs11f.h; sourceTree = "<group>"; };
00A5CACE111A358200EBA8FC /* pkcs11t.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pkcs11t.h; sourceTree = "<group>"; };
00A5CAFE111A373900EBA8FC /* COOLKEY.tokend */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = COOLKEY.tokend; sourceTree = BUILT_PRODUCTS_DIR; };
4C134A8A06DBF81800FA17D9 /* AttributeCoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = AttributeCoder.cpp; sourceTree = "<group>"; };
4C134A8B06DBF81800FA17D9 /* AttributeCoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AttributeCoder.h; sourceTree = "<group>"; };
4C134A8E06DBF81800FA17D9 /* Relation.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Relation.cpp; sourceTree = "<group>"; };
4C134A8F06DBF81800FA17D9 /* Relation.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Relation.h; sourceTree = "<group>"; };
4C134A9006DBF81800FA17D9 /* Token.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Token.cpp; sourceTree = "<group>"; };
4C134A9106DBF81800FA17D9 /* Token.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Token.h; sourceTree = "<group>"; };
4C134A9206DBF81800FA17D9 /* TokenContext.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TokenContext.cpp; sourceTree = "<group>"; };
4C134A9306DBF81800FA17D9 /* TokenContext.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TokenContext.h; sourceTree = "<group>"; };
4C134A9606DBF81800FA17D9 /* Attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Attribute.cpp; sourceTree = "<group>"; };
4C134A9706DBF81800FA17D9 /* Attribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Attribute.h; sourceTree = "<group>"; };
4C134A9806DBF81800FA17D9 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = "<group>"; };
4C134A9906DBF81800FA17D9 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = "<group>"; };
4C134A9A06DBF81800FA17D9 /* DbValue.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = DbValue.cpp; sourceTree = "<group>"; };
4C134A9B06DBF81800FA17D9 /* DbValue.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = DbValue.h; sourceTree = "<group>"; };
4C134A9C06DBF81800FA17D9 /* MetaAttribute.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MetaAttribute.cpp; sourceTree = "<group>"; };
4C134A9D06DBF81800FA17D9 /* MetaAttribute.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MetaAttribute.h; sourceTree = "<group>"; };
4C134A9E06DBF81800FA17D9 /* MetaRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MetaRecord.cpp; sourceTree = "<group>"; };
4C134A9F06DBF81800FA17D9 /* MetaRecord.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MetaRecord.h; sourceTree = "<group>"; };
4C134AA006DBF81800FA17D9 /* Record.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Record.cpp; sourceTree = "<group>"; };
4C134AA106DBF81800FA17D9 /* Record.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Record.h; sourceTree = "<group>"; };
4C134AA206DBF81800FA17D9 /* Schema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = Schema.cpp; sourceTree = "<group>"; };
4C134AA306DBF81800FA17D9 /* Schema.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Schema.h; sourceTree = "<group>"; };
4C134AA406DBF81800FA17D9 /* SelectionPredicate.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionPredicate.cpp; sourceTree = "<group>"; };
4C134AA506DBF81800FA17D9 /* SelectionPredicate.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SelectionPredicate.h; sourceTree = "<group>"; };
4C134AA906DBF81800FA17D9 /* MscError.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscError.cpp; sourceTree = "<group>"; };
4C134AAA06DBF81800FA17D9 /* MscError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscError.h; sourceTree = "<group>"; };
4C134AAB06DBF81800FA17D9 /* MscACL.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscACL.cpp; sourceTree = "<group>"; };
4C134AAC06DBF81800FA17D9 /* MscACL.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscACL.h; sourceTree = "<group>"; };
4C134AAF06DBF81800FA17D9 /* MscKey.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscKey.cpp; sourceTree = "<group>"; };
4C134AB006DBF81800FA17D9 /* MscKey.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscKey.h; sourceTree = "<group>"; };
4C134AB106DBF81800FA17D9 /* MscObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscObject.cpp; sourceTree = "<group>"; };
4C134AB206DBF81800FA17D9 /* MscObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscObject.h; sourceTree = "<group>"; };
4C134AB306DBF81800FA17D9 /* MscPIN.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscPIN.cpp; sourceTree = "<group>"; };
4C134AB406DBF81800FA17D9 /* MscPIN.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscPIN.h; sourceTree = "<group>"; };
4C134AB506DBF81800FA17D9 /* MscToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscToken.cpp; sourceTree = "<group>"; };
4C134AB606DBF81800FA17D9 /* MscToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscToken.h; sourceTree = "<group>"; };
4C134AB706DBF81800FA17D9 /* MscTokenConnection.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscTokenConnection.cpp; sourceTree = "<group>"; };
4C134AB806DBF81800FA17D9 /* MscTokenConnection.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscTokenConnection.h; sourceTree = "<group>"; };
4C134AB906DBF81800FA17D9 /* MscWrappers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MscWrappers.cpp; sourceTree = "<group>"; };
4C134ABA06DBF81800FA17D9 /* MscWrappers.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MscWrappers.h; sourceTree = "<group>"; };
4C1B9B5B06DBF96E00014414 /* MuscleCardAttributeCoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MuscleCardAttributeCoder.h; sourceTree = "<group>"; };
4C1B9B5C06DBF96E00014414 /* MuscleCardAttributeCoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MuscleCardAttributeCoder.cpp; sourceTree = "<group>"; };
4C1B9B6306DBF99F00014414 /* Adornment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Adornment.h; sourceTree = "<group>"; };
4C1B9B6406DBF99F00014414 /* Adornment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Adornment.cpp; sourceTree = "<group>"; };
4C1B9B8806DBFEE200014414 /* MuscleCardSchema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MuscleCardSchema.h; sourceTree = "<group>"; };
4C1B9B8906DBFEE200014414 /* MuscleCardSchema.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MuscleCardSchema.cpp; sourceTree = "<group>"; };
4C253C0D06F66A6100B5CED6 /* MuscleCardKeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MuscleCardKeyHandle.h; sourceTree = "<group>"; };
4C253C0E06F66A6100B5CED6 /* MuscleCardKeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MuscleCardKeyHandle.cpp; sourceTree = "<group>"; };
4C3C166D06F61D6F00FC8AAC /* KeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyHandle.h; sourceTree = "<group>"; };
4C3C166E06F61D6F00FC8AAC /* KeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = KeyHandle.cpp; sourceTree = "<group>"; };
4C3FACAC06DBF84400D18D5F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4C3FACAD06DBF84400D18D5F /* musclecard.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = musclecard.cpp; sourceTree = "<group>"; };
4C3FACAE06DBF84400D18D5F /* MuscleCardToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = MuscleCardToken.cpp; sourceTree = "<group>"; };
4C3FACAF06DBF84400D18D5F /* MuscleCardToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MuscleCardToken.h; sourceTree = "<group>"; };
4C55BAFB06DEABE500E4200A /* RecordHandle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RecordHandle.h; sourceTree = "<group>"; };
4C55BAFC06DEABE500E4200A /* RecordHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RecordHandle.cpp; sourceTree = "<group>"; };
4C5C1CE8073065EA00AECB7F /* belpic_csp_capabilities.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = belpic_csp_capabilities.mdsinfo; path = BELPIC/mds/belpic_csp_capabilities.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1CE9073065EA00AECB7F /* belpic_csp_capabilities_common.mds */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = belpic_csp_capabilities_common.mds; path = BELPIC/mds/belpic_csp_capabilities_common.mds; sourceTree = SOURCE_ROOT; };
4C5C1CEA073065EA00AECB7F /* belpic_csp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = belpic_csp_primary.mdsinfo; path = BELPIC/mds/belpic_csp_primary.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1CEB073065EA00AECB7F /* belpic_dl_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = belpic_dl_primary.mdsinfo; path = BELPIC/mds/belpic_dl_primary.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1CEC073065EA00AECB7F /* belpic_smartcard.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = belpic_smartcard.mdsinfo; path = BELPIC/mds/belpic_smartcard.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1D300730664E00AECB7F /* musclecard_csp_capabilities.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = musclecard_csp_capabilities.mdsinfo; path = MuscleCard/mds/musclecard_csp_capabilities.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1D310730664E00AECB7F /* musclecard_csp_capabilities_common.mds */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = musclecard_csp_capabilities_common.mds; path = MuscleCard/mds/musclecard_csp_capabilities_common.mds; sourceTree = SOURCE_ROOT; };
4C5C1D320730664E00AECB7F /* musclecard_csp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = musclecard_csp_primary.mdsinfo; path = MuscleCard/mds/musclecard_csp_primary.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1D330730664E00AECB7F /* musclecard_dl_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = musclecard_dl_primary.mdsinfo; path = MuscleCard/mds/musclecard_dl_primary.mdsinfo; sourceTree = SOURCE_ROOT; };
4C5C1D340730664E00AECB7F /* musclecard_smartcard.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; name = musclecard_smartcard.mdsinfo; path = MuscleCard/mds/musclecard_smartcard.mdsinfo; sourceTree = SOURCE_ROOT; };
4C63F7A506DC052A00CB6F22 /* TokenRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = TokenRecord.cpp; sourceTree = "<group>"; };
4C63F7A606DC052A00CB6F22 /* TokenRecord.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = TokenRecord.h; sourceTree = "<group>"; };
4C86D3A0070B4122006A0C7F /* belpic.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = belpic.cpp; sourceTree = "<group>"; };
4C86D3A3070B4122006A0C7F /* BELPICError.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICError.cpp; sourceTree = "<group>"; };
4C86D3A4070B4122006A0C7F /* BELPICError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICError.h; sourceTree = "<group>"; };
4C86D3A5070B4122006A0C7F /* BELPICKeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICKeyHandle.cpp; sourceTree = "<group>"; };
4C86D3A6070B4122006A0C7F /* BELPICKeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICKeyHandle.h; sourceTree = "<group>"; };
4C86D3A7070B4122006A0C7F /* BELPICRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICRecord.cpp; sourceTree = "<group>"; };
4C86D3A8070B4122006A0C7F /* BELPICRecord.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICRecord.h; sourceTree = "<group>"; };
4C86D3A9070B4122006A0C7F /* BELPICSchema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICSchema.cpp; sourceTree = "<group>"; };
4C86D3AA070B4122006A0C7F /* BELPICSchema.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICSchema.h; sourceTree = "<group>"; };
4C86D3AB070B4122006A0C7F /* BELPICToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = BELPICToken.cpp; sourceTree = "<group>"; };
4C86D3AC070B4122006A0C7F /* BELPICToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = BELPICToken.h; sourceTree = "<group>"; };
4C86D3AD070B4122006A0C7F /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4CA858F10654413F0083DED3 /* SecurityTokend.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = SecurityTokend.framework; sourceTree = BUILT_PRODUCTS_DIR; };
4CA8C4D606D6D19400F1BCC8 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
4CBF5CBE0704E76200EEADC2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.1.dylib; sourceTree = "<absolute>"; };
4CC394790731A4DD00761DEE /* SCardError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SCardError.h; sourceTree = "<group>"; };
4CC3947A0731A4DD00761DEE /* SCardError.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SCardError.cpp; sourceTree = "<group>"; };
4CE2E6A406DC06AB00E21469 /* KeyRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = KeyRecord.cpp; sourceTree = "<group>"; };
4CE2E6A506DC06AB00E21469 /* KeyRecord.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = KeyRecord.h; sourceTree = "<group>"; };
523C07E70B7B940D00067DEA /* PIVDefines.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVDefines.h; path = PIV/PIVDefines.h; sourceTree = "<group>"; };
523F79EC06D5AC27004256A0 /* security_cdsa_client.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = security_cdsa_client.framework; sourceTree = BUILT_PRODUCTS_DIR; };
523F79ED06D5AC27004256A0 /* security_cdsa_utilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = security_cdsa_utilities.framework; sourceTree = BUILT_PRODUCTS_DIR; };
523F79EE06D5AC27004256A0 /* security_utilities.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = security_utilities.framework; sourceTree = BUILT_PRODUCTS_DIR; };
5280677F0B78E98600D02C3A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.plist.xml; name = Info.plist; path = PIV/Info.plist; sourceTree = "<group>"; };
528067810B78E98600D02C3A /* piv_csp_capabilities.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_csp_capabilities.mdsinfo; sourceTree = "<group>"; };
528067820B78E98600D02C3A /* piv_csp_capabilities_common.mds */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_csp_capabilities_common.mds; sourceTree = "<group>"; };
528067830B78E98600D02C3A /* piv_csp_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_csp_primary.mdsinfo; sourceTree = "<group>"; };
528067840B78E98600D02C3A /* piv_dl_primary.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_dl_primary.mdsinfo; sourceTree = "<group>"; };
528067850B78E98600D02C3A /* piv_smartcard.mdsinfo */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text.xml; path = piv_smartcard.mdsinfo; sourceTree = "<group>"; };
528067860B78E98600D02C3A /* piv.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = piv.cpp; path = PIV/piv.cpp; sourceTree = "<group>"; };
528067870B78E98600D02C3A /* PIVAttributeCoder.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVAttributeCoder.cpp; path = PIV/PIVAttributeCoder.cpp; sourceTree = "<group>"; };
528067880B78E98600D02C3A /* PIVAttributeCoder.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVAttributeCoder.h; path = PIV/PIVAttributeCoder.h; sourceTree = "<group>"; };
528067890B78E98600D02C3A /* PIVError.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVError.cpp; path = PIV/PIVError.cpp; sourceTree = "<group>"; };
5280678A0B78E98600D02C3A /* PIVError.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVError.h; path = PIV/PIVError.h; sourceTree = "<group>"; };
5280678B0B78E98600D02C3A /* PIVKeyHandle.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVKeyHandle.cpp; path = PIV/PIVKeyHandle.cpp; sourceTree = "<group>"; };
5280678C0B78E98600D02C3A /* PIVKeyHandle.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVKeyHandle.h; path = PIV/PIVKeyHandle.h; sourceTree = "<group>"; };
5280678D0B78E98600D02C3A /* PIVRecord.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVRecord.cpp; path = PIV/PIVRecord.cpp; sourceTree = "<group>"; };
5280678E0B78E98600D02C3A /* PIVRecord.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVRecord.h; path = PIV/PIVRecord.h; sourceTree = "<group>"; };
5280678F0B78E98600D02C3A /* PIVSchema.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVSchema.cpp; path = PIV/PIVSchema.cpp; sourceTree = "<group>"; };
528067900B78E98600D02C3A /* PIVSchema.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVSchema.h; path = PIV/PIVSchema.h; sourceTree = "<group>"; };
528067910B78E98600D02C3A /* PIVToken.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVToken.cpp; path = PIV/PIVToken.cpp; sourceTree = "<group>"; };
528067920B78E98600D02C3A /* PIVToken.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVToken.h; path = PIV/PIVToken.h; sourceTree = "<group>"; };
529D9A7B0B867FA900DBFA4B /* PIVCCC.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = PIVCCC.cpp; path = PIV/PIVCCC.cpp; sourceTree = "<group>"; };
529D9A7C0B867FA900DBFA4B /* PIVCCC.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = PIVCCC.h; path = PIV/PIVCCC.h; sourceTree = "<group>"; };
52B2604A0BC5A864007E00F1 /* libtokend.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libtokend.a; sourceTree = BUILT_PRODUCTS_DIR; };
52B260620BC5A864007E00F1 /* Info-tokend__Upgraded_.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Info-tokend__Upgraded_.plist"; sourceTree = "<group>"; };
52B260630BC5A864007E00F1 /* tokend.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = tokend.framework; sourceTree = BUILT_PRODUCTS_DIR; };
52CA8342067E8175005A1EBA /* PCSC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = PCSC.framework; path = /System/Library/Frameworks/PCSC.framework; sourceTree = "<absolute>"; };
52CA8343067E8175005A1EBA /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Security.framework; sourceTree = BUILT_PRODUCTS_DIR; };
52DE698106E93B870024EA03 /* PKCS11Object.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PKCS11Object.h; sourceTree = "<group>"; };
52DE698206E93B870024EA03 /* PKCS11Object.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PKCS11Object.cpp; sourceTree = "<group>"; };
52E66B8E0E92E78700CDE046 /* byte_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = byte_string.h; path = PIV/byte_string.h; sourceTree = "<group>"; };
52E66B8F0E92E78700CDE046 /* Padding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Padding.cpp; path = PIV/Padding.cpp; sourceTree = "<group>"; };
52E66B900E92E78700CDE046 /* Padding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Padding.h; path = PIV/Padding.h; sourceTree = "<group>"; };
52E66B910E92E78700CDE046 /* PIVUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PIVUtilities.h; path = PIV/PIVUtilities.h; sourceTree = "<group>"; };
52E66B920E92E78700CDE046 /* SecureBufferAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecureBufferAllocator.h; path = PIV/SecureBufferAllocator.h; sourceTree = "<group>"; };
52E66B930E92E78700CDE046 /* SecureBufferAllocator.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = SecureBufferAllocator.inc; path = PIV/SecureBufferAllocator.inc; sourceTree = "<group>"; };
52E66B940E92E78700CDE046 /* TLV.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TLV.cpp; path = PIV/TLV.cpp; sourceTree = "<group>"; };
52E66B950E92E78700CDE046 /* TLV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TLV.h; path = PIV/TLV.h; sourceTree = "<group>"; };
52E66B960E92E78700CDE046 /* TLV.inc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.pascal; name = TLV.inc; path = PIV/TLV.inc; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
00A5CAF8111A373900EBA8FC /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
009F4DFF111BB1A700012078 /* CoreFoundation.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
009F4D58111BACB400012078 /* CoolKey */ = {
isa = PBXGroup;
children = (
009F4D59111BACB400012078 /* coolkey.cpp */,
009F4D5A111BACB400012078 /* CoolKeyAttributeCoder.cpp */,
009F4D5B111BACB400012078 /* CoolKeyAttributeCoder.h */,
009F4D5C111BACB400012078 /* CoolKeyError.cpp */,
009F4D5D111BACB400012078 /* CoolKeyError.h */,
009F4D5E111BACB400012078 /* CoolKeyHandle.cpp */,
009F4D5F111BACB400012078 /* CoolKeyHandle.h */,
009F4D60111BACB400012078 /* CoolKeyPK11.cpp */,
009F4D61111BACB400012078 /* CoolKeyPK11.h */,
009F4D62111BACB400012078 /* CoolKeyRecord.cpp */,
009F4D63111BACB400012078 /* CoolKeyRecord.h */,
009F4D64111BACB400012078 /* CoolKeySchema.cpp */,
009F4D65111BACB400012078 /* CoolKeySchema.h */,
009F4D66111BACB400012078 /* CoolKeyToken.cpp */,
009F4D67111BACB400012078 /* CoolKeyToken.h */,
009F4D68111BACB400012078 /* dlfcn.h */,
009F4D69111BACB400012078 /* dlfcn.h.orig */,
009F4D6B111BACB400012078 /* mds */,
009F4D71111BACB400012078 /* pkcs11 */,
);
path = CoolKey;
sourceTree = "<group>";
};
009F4D6B111BACB400012078 /* mds */ = {
isa = PBXGroup;
children = (
009F4D6C111BACB400012078 /* coolkey_csp_capabilities.mdsinfo */,
009F4D6D111BACB400012078 /* coolkey_csp_capabilities_common.mds */,
009F4D6E111BACB400012078 /* coolkey_csp_primary.mdsinfo */,
009F4D6F111BACB400012078 /* coolkey_dl_primary.mdsinfo */,
009F4D70111BACB400012078 /* coolkey_smartcard.mdsinfo */,
);
path = mds;
sourceTree = "<group>";
};
009F4D71111BACB400012078 /* pkcs11 */ = {
isa = PBXGroup;
children = (
009F4D73111BACB400012078 /* cryptoki.h */,
009F4D74111BACB400012078 /* mypkcs11.h */,
009F4D75111BACB400012078 /* pkcs11.h */,
009F4D76111BACB400012078 /* pkcs11f.h */,
009F4D77111BACB400012078 /* pkcs11t.h */,
);
path = pkcs11;
sourceTree = "<group>";
};
00A5CAAC111A356200EBA8FC /* Tokend-35209 */ = {
isa = PBXGroup;
children = (
00A5CAAD111A358200EBA8FC /* coolkey.cpp */,
00A5CAAE111A358200EBA8FC /* CoolKeyAttributeCoder.cpp */,
00A5CAAF111A358200EBA8FC /* CoolKeyAttributeCoder.h */,
00A5CAB0111A358200EBA8FC /* CoolKeyError.cpp */,
00A5CAB1111A358200EBA8FC /* CoolKeyError.h */,
00A5CAB2111A358200EBA8FC /* CoolKeyHandle.cpp */,
00A5CAB3111A358200EBA8FC /* CoolKeyHandle.h */,
00A5CAB4111A358200EBA8FC /* CoolKeyPK11.cpp */,
00A5CAB5111A358200EBA8FC /* CoolKeyPK11.h */,
00A5CAB6111A358200EBA8FC /* CoolKeyRecord.cpp */,
00A5CAB7111A358200EBA8FC /* CoolKeyRecord.h */,
00A5CAB8111A358200EBA8FC /* CoolKeySchema.cpp */,
00A5CAB9111A358200EBA8FC /* CoolKeySchema.h */,
00A5CABA111A358200EBA8FC /* CoolKeyToken.cpp */,
00A5CABB111A358200EBA8FC /* CoolKeyToken.h */,
00A5CABC111A358200EBA8FC /* CVS */,
00A5CAC1111A358200EBA8FC /* Info.plist */,
00A5CAC2111A358200EBA8FC /* mds */,
00A5CAC8111A358200EBA8FC /* pkcs11 */,
);
name = "Tokend-35209";
sourceTree = "<group>";
};
00A5CABC111A358200EBA8FC /* CVS */ = {
isa = PBXGroup;
children = (
00A5CABD111A358200EBA8FC /* Entries */,
00A5CABE111A358200EBA8FC /* Repository */,
00A5CABF111A358200EBA8FC /* Root */,
00A5CAC0111A358200EBA8FC /* Tag */,
);
name = CVS;
path = CoolKey/CVS;
sourceTree = "<group>";
};
00A5CAC2111A358200EBA8FC /* mds */ = {
isa = PBXGroup;
children = (
00A5CAC3111A358200EBA8FC /* coolkey_csp_capabilities.mdsinfo */,
00A5CAC4111A358200EBA8FC /* coolkey_csp_capabilities_common.mds */,
00A5CAC5111A358200EBA8FC /* coolkey_csp_primary.mdsinfo */,
00A5CAC6111A358200EBA8FC /* coolkey_dl_primary.mdsinfo */,
00A5CAC7111A358200EBA8FC /* coolkey_smartcard.mdsinfo */,
);
name = mds;
path = CoolKey/mds;
sourceTree = "<group>";
};
00A5CAC8111A358200EBA8FC /* pkcs11 */ = {
isa = PBXGroup;
children = (
00A5CAC9111A358200EBA8FC /* compile.sh */,
00A5CACA111A358200EBA8FC /* cryptoki.h */,
00A5CACB111A358200EBA8FC /* mypkcs11.h */,
00A5CACC111A358200EBA8FC /* pkcs11.h */,
00A5CACD111A358200EBA8FC /* pkcs11f.h */,
00A5CACE111A358200EBA8FC /* pkcs11t.h */,
);
name = pkcs11;
path = CoolKey/pkcs11;
sourceTree = "<group>";
};
08FB7794FE84155DC02AAC07 /* TokendMuscle */ = {
isa = PBXGroup;
children = (
009F4D58111BACB400012078 /* CoolKey */,
00A5CAAC111A356200EBA8FC /* Tokend-35209 */,
5280675F0B78E86F00D02C3A /* PIV */,
4C86D39F070B4122006A0C7F /* BELPIC */,
4C3FACA806DBF84400D18D5F /* MuscleCard */,
4C134A8706DBF81800FA17D9 /* Tokend */,
4CA858F0065441220083DED3 /* External Frameworks */,
4C415098073061D6004C9490 /* External Libraries */,
1AB674ADFE9D54B511CA2CBB /* Products */,
52B260620BC5A864007E00F1 /* Info-tokend__Upgraded_.plist */,
);
name = TokendMuscle;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
52B2604A0BC5A864007E00F1 /* libtokend.a */,
52B260630BC5A864007E00F1 /* tokend.framework */,
00A5CAFE111A373900EBA8FC /* COOLKEY.tokend */,
);
name = Products;
sourceTree = "<group>";
};
4C134A8706DBF81800FA17D9 /* Tokend */ = {
isa = PBXGroup;
children = (
4C1B9B6406DBF99F00014414 /* Adornment.cpp */,
4C1B9B6306DBF99F00014414 /* Adornment.h */,
4C134A9606DBF81800FA17D9 /* Attribute.cpp */,
4C134A9706DBF81800FA17D9 /* Attribute.h */,
4C134A8A06DBF81800FA17D9 /* AttributeCoder.cpp */,
4C134A8B06DBF81800FA17D9 /* AttributeCoder.h */,
4C134A9806DBF81800FA17D9 /* Cursor.cpp */,
4C134A9906DBF81800FA17D9 /* Cursor.h */,
4C134A9A06DBF81800FA17D9 /* DbValue.cpp */,
4C134A9B06DBF81800FA17D9 /* DbValue.h */,
4C3C166E06F61D6F00FC8AAC /* KeyHandle.cpp */,
4C3C166D06F61D6F00FC8AAC /* KeyHandle.h */,
4C134A9C06DBF81800FA17D9 /* MetaAttribute.cpp */,
4C134A9D06DBF81800FA17D9 /* MetaAttribute.h */,
4C134A9E06DBF81800FA17D9 /* MetaRecord.cpp */,
4C134A9F06DBF81800FA17D9 /* MetaRecord.h */,
52DE698206E93B870024EA03 /* PKCS11Object.cpp */,
52DE698106E93B870024EA03 /* PKCS11Object.h */,
4C134AA006DBF81800FA17D9 /* Record.cpp */,
4C134AA106DBF81800FA17D9 /* Record.h */,
4C55BAFC06DEABE500E4200A /* RecordHandle.cpp */,
4C55BAFB06DEABE500E4200A /* RecordHandle.h */,
4C134A8E06DBF81800FA17D9 /* Relation.cpp */,
4C134A8F06DBF81800FA17D9 /* Relation.h */,
4CC3947A0731A4DD00761DEE /* SCardError.cpp */,
4CC394790731A4DD00761DEE /* SCardError.h */,
4C134AA206DBF81800FA17D9 /* Schema.cpp */,
4C134AA306DBF81800FA17D9 /* Schema.h */,
4C134AA406DBF81800FA17D9 /* SelectionPredicate.cpp */,
4C134AA506DBF81800FA17D9 /* SelectionPredicate.h */,
4C134A9006DBF81800FA17D9 /* Token.cpp */,
4C134A9106DBF81800FA17D9 /* Token.h */,
4C134A9206DBF81800FA17D9 /* TokenContext.cpp */,
4C134A9306DBF81800FA17D9 /* TokenContext.h */,
);
path = Tokend;
sourceTree = "<group>";
};
4C134AA606DBF81800FA17D9 /* Msc */ = {
isa = PBXGroup;
children = (
4C134AAB06DBF81800FA17D9 /* MscACL.cpp */,
4C134AAC06DBF81800FA17D9 /* MscACL.h */,
4C134AA906DBF81800FA17D9 /* MscError.cpp */,
4C134AAA06DBF81800FA17D9 /* MscError.h */,
4C134AAF06DBF81800FA17D9 /* MscKey.cpp */,
4C134AB006DBF81800FA17D9 /* MscKey.h */,
4C134AB106DBF81800FA17D9 /* MscObject.cpp */,
4C134AB206DBF81800FA17D9 /* MscObject.h */,
4C134AB306DBF81800FA17D9 /* MscPIN.cpp */,
4C134AB406DBF81800FA17D9 /* MscPIN.h */,
4C134AB506DBF81800FA17D9 /* MscToken.cpp */,
4C134AB606DBF81800FA17D9 /* MscToken.h */,
4C134AB706DBF81800FA17D9 /* MscTokenConnection.cpp */,
4C134AB806DBF81800FA17D9 /* MscTokenConnection.h */,
4C134AB906DBF81800FA17D9 /* MscWrappers.cpp */,
4C134ABA06DBF81800FA17D9 /* MscWrappers.h */,
);
path = Msc;
sourceTree = "<group>";
};
4C3FACA806DBF84400D18D5F /* MuscleCard */ = {
isa = PBXGroup;
children = (
4C134AA606DBF81800FA17D9 /* Msc */,
4C5C1D280730664E00AECB7F /* mds */,
4C3FACAC06DBF84400D18D5F /* Info.plist */,
4CE2E6A406DC06AB00E21469 /* KeyRecord.cpp */,
4CE2E6A506DC06AB00E21469 /* KeyRecord.h */,
4C3FACAD06DBF84400D18D5F /* musclecard.cpp */,
4C1B9B5C06DBF96E00014414 /* MuscleCardAttributeCoder.cpp */,
4C1B9B5B06DBF96E00014414 /* MuscleCardAttributeCoder.h */,
4C253C0E06F66A6100B5CED6 /* MuscleCardKeyHandle.cpp */,
4C253C0D06F66A6100B5CED6 /* MuscleCardKeyHandle.h */,
4C1B9B8906DBFEE200014414 /* MuscleCardSchema.cpp */,
4C1B9B8806DBFEE200014414 /* MuscleCardSchema.h */,
4C3FACAE06DBF84400D18D5F /* MuscleCardToken.cpp */,
4C3FACAF06DBF84400D18D5F /* MuscleCardToken.h */,
4C63F7A506DC052A00CB6F22 /* TokenRecord.cpp */,
4C63F7A606DC052A00CB6F22 /* TokenRecord.h */,
);
path = MuscleCard;
sourceTree = "<group>";
};
4C415098073061D6004C9490 /* External Libraries */ = {
isa = PBXGroup;
children = (
4CBF5CBE0704E76200EEADC2 /* libz.dylib */,
);
name = "External Libraries";
sourceTree = "<group>";
};
4C5C1CE0073065EA00AECB7F /* mds */ = {
isa = PBXGroup;
children = (
4C5C1CE8073065EA00AECB7F /* belpic_csp_capabilities.mdsinfo */,
4C5C1CE9073065EA00AECB7F /* belpic_csp_capabilities_common.mds */,
4C5C1CEA073065EA00AECB7F /* belpic_csp_primary.mdsinfo */,
4C5C1CEB073065EA00AECB7F /* belpic_dl_primary.mdsinfo */,
4C5C1CEC073065EA00AECB7F /* belpic_smartcard.mdsinfo */,
);
name = mds;
path = BELPIC/mds;
sourceTree = SOURCE_ROOT;
};
4C5C1D280730664E00AECB7F /* mds */ = {
isa = PBXGroup;
children = (
4C5C1D300730664E00AECB7F /* musclecard_csp_capabilities.mdsinfo */,
4C5C1D310730664E00AECB7F /* musclecard_csp_capabilities_common.mds */,
4C5C1D320730664E00AECB7F /* musclecard_csp_primary.mdsinfo */,
4C5C1D330730664E00AECB7F /* musclecard_dl_primary.mdsinfo */,
4C5C1D340730664E00AECB7F /* musclecard_smartcard.mdsinfo */,
);
name = mds;
path = MuscleCard/mds;
sourceTree = SOURCE_ROOT;
};
4C86D39F070B4122006A0C7F /* BELPIC */ = {
isa = PBXGroup;
children = (
4C5C1CE0073065EA00AECB7F /* mds */,
4C86D3A0070B4122006A0C7F /* belpic.cpp */,
4C86D3A3070B4122006A0C7F /* BELPICError.cpp */,
4C86D3A4070B4122006A0C7F /* BELPICError.h */,
4C86D3A5070B4122006A0C7F /* BELPICKeyHandle.cpp */,
4C86D3A6070B4122006A0C7F /* BELPICKeyHandle.h */,
4C86D3A7070B4122006A0C7F /* BELPICRecord.cpp */,
4C86D3A8070B4122006A0C7F /* BELPICRecord.h */,
4C86D3A9070B4122006A0C7F /* BELPICSchema.cpp */,
4C86D3AA070B4122006A0C7F /* BELPICSchema.h */,
4C86D3AB070B4122006A0C7F /* BELPICToken.cpp */,
4C86D3AC070B4122006A0C7F /* BELPICToken.h */,
4C86D3AD070B4122006A0C7F /* Info.plist */,
);
path = BELPIC;
sourceTree = "<group>";
};
4CA858F0065441220083DED3 /* External Frameworks */ = {
isa = PBXGroup;
children = (
4CA8C4D606D6D19400F1BCC8 /* CoreFoundation.framework */,
523F79EC06D5AC27004256A0 /* security_cdsa_client.framework */,
523F79ED06D5AC27004256A0 /* security_cdsa_utilities.framework */,
523F79EE06D5AC27004256A0 /* security_utilities.framework */,
52CA8342067E8175005A1EBA /* PCSC.framework */,
52CA8343067E8175005A1EBA /* Security.framework */,
4CA858F10654413F0083DED3 /* SecurityTokend.framework */,
);
name = "External Frameworks";
sourceTree = "<group>";
};
5280675F0B78E86F00D02C3A /* PIV */ = {
isa = PBXGroup;
children = (
52E66B8E0E92E78700CDE046 /* byte_string.h */,
52E66B8F0E92E78700CDE046 /* Padding.cpp */,
52E66B900E92E78700CDE046 /* Padding.h */,
52E66B910E92E78700CDE046 /* PIVUtilities.h */,
52E66B920E92E78700CDE046 /* SecureBufferAllocator.h */,
52E66B930E92E78700CDE046 /* SecureBufferAllocator.inc */,
52E66B940E92E78700CDE046 /* TLV.cpp */,
52E66B950E92E78700CDE046 /* TLV.h */,
52E66B960E92E78700CDE046 /* TLV.inc */,
528067800B78E98600D02C3A /* mds */,
529D9A7B0B867FA900DBFA4B /* PIVCCC.cpp */,
529D9A7C0B867FA900DBFA4B /* PIVCCC.h */,
523C07E70B7B940D00067DEA /* PIVDefines.h */,
5280677F0B78E98600D02C3A /* Info.plist */,
528067860B78E98600D02C3A /* piv.cpp */,
528067870B78E98600D02C3A /* PIVAttributeCoder.cpp */,
528067880B78E98600D02C3A /* PIVAttributeCoder.h */,
528067890B78E98600D02C3A /* PIVError.cpp */,
5280678A0B78E98600D02C3A /* PIVError.h */,
5280678B0B78E98600D02C3A /* PIVKeyHandle.cpp */,
5280678C0B78E98600D02C3A /* PIVKeyHandle.h */,
5280678D0B78E98600D02C3A /* PIVRecord.cpp */,
5280678E0B78E98600D02C3A /* PIVRecord.h */,
5280678F0B78E98600D02C3A /* PIVSchema.cpp */,
528067900B78E98600D02C3A /* PIVSchema.h */,
528067910B78E98600D02C3A /* PIVToken.cpp */,
528067920B78E98600D02C3A /* PIVToken.h */,
);
name = PIV;
sourceTree = "<group>";
};
528067800B78E98600D02C3A /* mds */ = {
isa = PBXGroup;
children = (
528067810B78E98600D02C3A /* piv_csp_capabilities.mdsinfo */,
528067820B78E98600D02C3A /* piv_csp_capabilities_common.mds */,
528067830B78E98600D02C3A /* piv_csp_primary.mdsinfo */,
528067840B78E98600D02C3A /* piv_dl_primary.mdsinfo */,
528067850B78E98600D02C3A /* piv_smartcard.mdsinfo */,
);
name = mds;
path = PIV/mds;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
52B2604C0BC5A864007E00F1 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
52B2604D0BC5A864007E00F1 /* Adornment.h in Headers */,
52B2604E0BC5A864007E00F1 /* Attribute.h in Headers */,
52B2604F0BC5A864007E00F1 /* AttributeCoder.h in Headers */,
52B260500BC5A864007E00F1 /* Cursor.h in Headers */,
52B260510BC5A864007E00F1 /* DbValue.h in Headers */,
52B260520BC5A864007E00F1 /* KeyHandle.h in Headers */,
52B260530BC5A864007E00F1 /* MetaAttribute.h in Headers */,
52B260540BC5A864007E00F1 /* MetaRecord.h in Headers */,
52B260550BC5A864007E00F1 /* Record.h in Headers */,
52B260560BC5A864007E00F1 /* RecordHandle.h in Headers */,
52B260570BC5A864007E00F1 /* Relation.h in Headers */,
52B260580BC5A864007E00F1 /* SCardError.h in Headers */,
52B260590BC5A864007E00F1 /* Schema.h in Headers */,
52B2605A0BC5A864007E00F1 /* SelectionPredicate.h in Headers */,
52B2605B0BC5A864007E00F1 /* Token.h in Headers */,
52B2605C0BC5A864007E00F1 /* TokenContext.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
00A5CAE7111A373900EBA8FC /* COOLKEY */ = {
isa = PBXNativeTarget;
buildConfigurationList = 00A5CAFB111A373900EBA8FC /* Build configuration list for PBXNativeTarget "COOLKEY" */;
buildPhases = (
00A5CAEA111A373900EBA8FC /* Resources */,
00A5CAF0111A373900EBA8FC /* Sources */,
00A5CAF8111A373900EBA8FC /* Frameworks */,
);
buildRules = (
);
dependencies = (
00A5CAE8111A373900EBA8FC /* PBXTargetDependency */,
);
name = COOLKEY;
productName = "Common Access Card";
productReference = 00A5CAFE111A373900EBA8FC /* COOLKEY.tokend */;
productType = "com.apple.product-type.application";
};
52B2602D0BC5A864007E00F1 /* libtokend */ = {
isa = PBXNativeTarget;
buildConfigurationList = 52B260450BC5A864007E00F1 /* Build configuration list for PBXNativeTarget "libtokend" */;
buildPhases = (
52B260310BC5A864007E00F1 /* Sources */,
52B260430BC5A864007E00F1 /* ShellScript */,
52B260440BC5A864007E00F1 /* ShellScript */,
);
buildRules = (
);
dependencies = (
52B260DF0BC5A864007E00F1 /* PBXTargetDependency */,
);
name = libtokend;
productName = libtokend;
productReference = 52B2604A0BC5A864007E00F1 /* libtokend.a */;
productType = "com.apple.product-type.library.static";
};
52B2604B0BC5A864007E00F1 /* tokend */ = {
isa = PBXNativeTarget;
buildConfigurationList = 52B2605D0BC5A864007E00F1 /* Build configuration list for PBXNativeTarget "tokend" */;
buildPhases = (
52B2604C0BC5A864007E00F1 /* Headers */,
);
buildRules = (
);
dependencies = (
);
name = tokend;
productName = tokend;
productReference = 52B260630BC5A864007E00F1 /* tokend.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
buildConfigurationList = C27AD2220987FCDC001272E0 /* Build configuration list for PBXProject "Tokend" */;
compatibilityVersion = "Xcode 2.4";
hasScannedForEncodings = 1;
mainGroup = 08FB7794FE84155DC02AAC07 /* TokendMuscle */;
projectDirPath = "";
projectRoot = "";
targets = (
00A5CAE7111A373900EBA8FC /* COOLKEY */,
52B2601F0BC5A864007E00F1 /* world */,
52B2602D0BC5A864007E00F1 /* libtokend */,
52B2604B0BC5A864007E00F1 /* tokend */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
00A5CAEA111A373900EBA8FC /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
009F4D82111BACB400012078 /* coolkey_csp_capabilities.mdsinfo in Resources */,
009F4D83111BACB400012078 /* coolkey_csp_capabilities_common.mds in Resources */,
009F4D84111BACB400012078 /* coolkey_csp_primary.mdsinfo in Resources */,
009F4D85111BACB400012078 /* coolkey_dl_primary.mdsinfo in Resources */,
009F4D86111BACB400012078 /* coolkey_smartcard.mdsinfo in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
52B260430BC5A864007E00F1 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "for variant in ${BUILD_VARIANTS}\ndo\n\tpostfix=`echo _${variant} | sed 's/_normal//'`\n\tfrmwk=\"${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.framework\"\n\tversa=\"${frmwk}/Versions/A\"\n\tcp \"${BUILT_PRODUCTS_DIR}/lib${PRODUCT_NAME}${postfix}.a\" \"${versa}/${PRODUCT_NAME}${postfix}\"\n\tln -fs \"${versa}/${PRODUCT_NAME}${postfix}\" ${frmwk}/${PRODUCT_NAME}${postfix}\n\tnmedit -p \"${versa}/${PRODUCT_NAME}${postfix}\"\n\tranlib \"${versa}/${PRODUCT_NAME}${postfix}\"\ndone";
showEnvVarsInLog = 0;
};
52B260440BC5A864007E00F1 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
shellScript = "for variant in ${BUILD_VARIANTS}\ndo\n\tpostfix=`echo _${variant} | sed 's/_normal//'`\n\tcp -p \"${SYMROOT}/${PRODUCT_NAME}${postfix}\" \"${DSTROOT}/usr/local/SecurityPieces/Frameworks/${PRODUCT_NAME}.framework/Versions/A\"\n\tranlib \"${DSTROOT}/usr/local/SecurityPieces/Frameworks/${PRODUCT_NAME}.framework/Versions/A/${PRODUCT_NAME}${postfix}\"\n\tln -fs \"Versions/Current/${PRODUCT_NAME}${postfix}\" \"${DSTROOT}/usr/local/SecurityPieces/Frameworks/${PRODUCT_NAME}.framework\"\ndone";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
00A5CAF0111A373900EBA8FC /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
009F4D78111BACB400012078 /* coolkey.cpp in Sources */,
009F4D79111BACB400012078 /* CoolKeyAttributeCoder.cpp in Sources */,
009F4D7A111BACB400012078 /* CoolKeyError.cpp in Sources */,
009F4D7B111BACB400012078 /* CoolKeyHandle.cpp in Sources */,
009F4D7C111BACB400012078 /* CoolKeyPK11.cpp in Sources */,
009F4D7D111BACB400012078 /* CoolKeyRecord.cpp in Sources */,
009F4D7E111BACB400012078 /* CoolKeySchema.cpp in Sources */,
009F4D7F111BACB400012078 /* CoolKeyToken.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
52B260310BC5A864007E00F1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
52B260320BC5A864007E00F1 /* Adornment.cpp in Sources */,
52B260330BC5A864007E00F1 /* Attribute.cpp in Sources */,
52B260340BC5A864007E00F1 /* AttributeCoder.cpp in Sources */,
52B260350BC5A864007E00F1 /* Cursor.cpp in Sources */,
52B260360BC5A864007E00F1 /* DbValue.cpp in Sources */,
52B260370BC5A864007E00F1 /* KeyHandle.cpp in Sources */,
52B260380BC5A864007E00F1 /* MetaAttribute.cpp in Sources */,
52B260390BC5A864007E00F1 /* MetaRecord.cpp in Sources */,
52B2603A0BC5A864007E00F1 /* Record.cpp in Sources */,
52B2603B0BC5A864007E00F1 /* RecordHandle.cpp in Sources */,
52B2603C0BC5A864007E00F1 /* Relation.cpp in Sources */,
52B2603D0BC5A864007E00F1 /* SCardError.cpp in Sources */,
52B2603E0BC5A864007E00F1 /* Schema.cpp in Sources */,
52B2603F0BC5A864007E00F1 /* SelectionPredicate.cpp in Sources */,
52B260400BC5A864007E00F1 /* Token.cpp in Sources */,
52B260410BC5A864007E00F1 /* TokenContext.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
00A5CAE8111A373900EBA8FC /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 52B2602D0BC5A864007E00F1 /* libtokend */;
targetProxy = 00A5CAE9111A373900EBA8FC /* PBXContainerItemProxy */;
};
529252170BC6BEED00816597 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 52B2602D0BC5A864007E00F1 /* libtokend */;
targetProxy = 529252160BC6BEED00816597 /* PBXContainerItemProxy */;
};
52B260DF0BC5A864007E00F1 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 52B2604B0BC5A864007E00F1 /* tokend */;
targetProxy = 52B260DE0BC5A864007E00F1 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
00A5CAFC111A373900EBA8FC /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1)";
ARCHS_STANDARD_32_BIT_PRE_XCODE_3_1 = "ppc i386";
BUILD_VARIANTS = debug;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 35209;
FRAMEWORK_SEARCH_PATHS = (
/usr/local/SecurityPieces/Frameworks,
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_MODEL_TUNING = G5;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INHIBIT_ALL_WARNINGS = NO;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_PEDANTIC = NO;
GCC_WARN_SHADOW = NO;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VALUE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = CoolKey/Info.plist;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security/tokend";
OPT_CPPXFLAGS = "$(OPT_CXFLAGS) -fno-enforce-eh-specs -fno-implement-inlines";
OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
OPT_INLINEXFLAGS = " -finline-functions";
OPT_LDXFLAGS = "-dead_strip";
OPT_LDXNOPIC = ",_nopic";
OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -DNDEBUG";
OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
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 tokend,_debug -framework PCSC,_debug -framework SecurityTokend,_debug -framework Security,_debug -framework security_cdsa_client,_debug -framework security_cdsa_utilities,_debug -framework security_utilities,_debug";
OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -framework tokend -framework PCSC -framework SecurityTokend -framework Security -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 tokend,_profile -framework PCSC,_profile -framework SecurityTokend,_profile -framework Security,_profile -framework security_cdsa_client,_profile -framework security_cdsa_utilities,_profile -framework security_utilities,_profile";
PRODUCT_NAME = COOLKEY;
VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
WRAPPER_EXTENSION = tokend;
ZERO_LINK = NO;
};
name = Development;
};
00A5CAFD111A373900EBA8FC /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_VARIANTS = (
normal,
debug,
);
CURRENT_PROJECT_VERSION = 35209;
FRAMEWORK_SEARCH_PATHS = (
/usr/local/SecurityPieces/Frameworks,
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
GCC_DYNAMIC_NO_PIC = YES;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_MODEL_TUNING = G5;
INFOPLIST_FILE = CoolKey/Info.plist;
INSTALL_PATH = "$(SYSTEM_LIBRARY_DIR)/Security/tokend";
OPT_CPPXFLAGS = "$(OPT_CXFLAGS) -fno-enforce-eh-specs -fno-implement-inlines";
OPT_CXFLAGS = "-DNDEBUG $(OPT_INLINEXFLAGS)";
OPT_INLINEXFLAGS = " -finline-functions";
OPT_LDXFLAGS = "-dead_strip";
OPT_LDXNOPIC = ",_nopic";
OTHER_ASFLAGS_debug = "$(OTHER_CFLAGS)";
OTHER_ASFLAGS_normal = "$(OTHER_CFLAGS) -DNDEBUG";
OTHER_ASFLAGS_profile = "-DNDEBUG $(OTHER_CFLAGS) -pg";
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 tokend,_debug -framework PCSC,_debug -framework SecurityTokend,_debug -framework Security,_debug -framework security_cdsa_client,_debug -framework security_cdsa_utilities,_debug -framework security_utilities,_debug";
OTHER_LDFLAGS_normal = "$(OPT_LDXFLAGS) $(OTHER_LDFLAGS) -framework tokend -framework PCSC -framework SecurityTokend -framework Security -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 tokend,_profile -framework PCSC,_profile -framework SecurityTokend,_profile -framework Security,_profile -framework security_cdsa_client,_profile -framework security_cdsa_utilities,_profile -framework security_utilities,_profile";
PRODUCT_NAME = COOLKEY;
VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
WRAPPER_EXTENSION = tokend;
ZERO_LINK = NO;
};
name = Deployment;
};
52B260290BC5A864007E00F1 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_VARIANTS = debug;
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_WARN_ABOUT_MISSING_PROTOTYPES = YES;
GCC_WARN_CHECK_SWITCH_STATEMENTS = YES;
GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES;
GCC_WARN_INHIBIT_ALL_WARNINGS = NO;
GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES;
GCC_WARN_MISSING_PARENTHESES = YES;
GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES;
GCC_WARN_PEDANTIC = NO;
GCC_WARN_SHADOW = NO;
GCC_WARN_SIGN_COMPARE = YES;
GCC_WARN_TYPECHECK_CALLS_TO_PRINTF = YES;
GCC_WARN_UNINITIALIZED_AUTOS = NO;
GCC_WARN_UNKNOWN_PRAGMAS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_LABEL = YES;
GCC_WARN_UNUSED_PARAMETER = YES;
GCC_WARN_UNUSED_VALUE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
PRODUCT_NAME = world;
SECTORDER_FLAGS = "";
ZERO_LINK = NO;
};
name = Development;
};
52B2602A0BC5A864007E00F1 /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_ENABLE_FIX_AND_CONTINUE = NO;
PRODUCT_NAME = world;
SECTORDER_FLAGS = "";
ZERO_LINK = NO;
};
name = Deployment;
};
52B260460BC5A864007E00F1 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_VARIANTS = debug;
CURRENT_PROJECT_VERSION = 35209;
FRAMEWORK_SEARCH_PATHS = (
/usr/local/SecurityPieces/Frameworks,
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_GENERATE_DEBUGGING_SYMBOLS = YES;
GCC_PREPROCESSOR_DEFINITIONS = LIMITED_SIGNING;
LIBRARY_STYLE = STATIC;
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 = "";
OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
OTHER_CFLAGS_nopic = "-mdynamic-no-pic $(OPT_CFLAGS) $(OTHER_CFLAGS)";
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_nopic = "-mdynamic-no-pic $(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS) -pg";
OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)";
OTHER_LDFLAGS_nopic = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
OTHER_LDFLAGS_normal = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
OTHER_LDFLAGS_profile = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS) -pg";
PRODUCT_NAME = tokend;
VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = YES;
};
name = Development;
};
52B260470BC5A864007E00F1 /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUILD_VARIANTS = (
normal,
debug,
nopic,
);
COPY_PHASE_STRIP = YES;
CURRENT_PROJECT_VERSION = 35209;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
/usr/local/SecurityPieces/Frameworks,
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
GCC_DEBUGGING_SYMBOLS = default;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_PREPROCESSOR_DEFINITIONS = LIMITED_SIGNING;
LIBRARY_STYLE = STATIC;
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 = "";
OTHER_CFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
OTHER_CFLAGS_nopic = "-mdynamic-no-pic $(OPT_CFLAGS) $(OTHER_CFLAGS)";
OTHER_CFLAGS_normal = "$(OPT_CFLAGS) $(OTHER_CFLAGS)";
OTHER_CFLAGS_profile = "\U0001$(OPT_CFLAGS) $(OTHER_CFLAGS) -pg";
OTHER_CPLUSPLUSFLAGS_debug = "$(OTHER_CFLAGS) -O0 -fno-inline";
OTHER_CPLUSPLUSFLAGS_nopic = "-mdynamic-no-pic $(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
OTHER_CPLUSPLUSFLAGS_normal = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS)";
OTHER_CPLUSPLUSFLAGS_profile = "$(OPT_CPPFLAGS) $(OTHER_CFLAGS) -pg";
OTHER_LDFLAGS_debug = "$(OTHER_LDFLAGS)";
OTHER_LDFLAGS_nopic = "-dead_strip $(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
OTHER_LDFLAGS_normal = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS)";
OTHER_LDFLAGS_profile = "$(OPT_LDFLAGS) $(OTHER_LDFLAGS) -pg";
PRODUCT_NAME = tokend;
VERSIONING_SYSTEM = "apple-generic";
WARNING_CFLAGS = (
"-Wmost",
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
ZERO_LINK = NO;
};
name = Deployment;
};
52B2605E0BC5A864007E00F1 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
/usr/local/SecurityPieces/Frameworks,
"$(SYSTEM_LIBRARY_DIR)/PrivateFrameworks",
);
FRAMEWORK_VERSION = A;
GCC_ENABLE_FIX_AND_CONTINUE = YES;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
INFOPLIST_FILE = "Info-tokend__Upgraded_.plist";
INSTALL_PATH = /usr/local/SecurityPieces/Frameworks;
PRODUCT_NAME = tokend;
WRAPPER_EXTENSION = framework;
ZERO_LINK = YES;
};
name = Development;
};
52B2605F0BC5A864007E00F1 /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_VERSION = A;
GCC_DEBUGGING_SYMBOLS = default;
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
INFOPLIST_FILE = "Info-tokend__Upgraded_.plist";
INSTALL_PATH = /usr/local/SecurityPieces/Frameworks;
PRODUCT_NAME = tokend;
WRAPPER_EXTENSION = framework;
ZERO_LINK = NO;
};
name = Deployment;
};
C27AD2230987FCDC001272E0 /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
};
name = Development;
};
C27AD2240987FCDC001272E0 /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
CONFIGURATION_TEMP_DIR = "$(PROJECT_TEMP_DIR)";
};
name = Deployment;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
00A5CAFB111A373900EBA8FC /* Build configuration list for PBXNativeTarget "COOLKEY" */ = {
isa = XCConfigurationList;
buildConfigurations = (
00A5CAFC111A373900EBA8FC /* Development */,
00A5CAFD111A373900EBA8FC /* Deployment */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
52B260280BC5A864007E00F1 /* Build configuration list for PBXAggregateTarget "world" */ = {
isa = XCConfigurationList;
buildConfigurations = (
52B260290BC5A864007E00F1 /* Development */,
52B2602A0BC5A864007E00F1 /* Deployment */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
52B260450BC5A864007E00F1 /* Build configuration list for PBXNativeTarget "libtokend" */ = {
isa = XCConfigurationList;
buildConfigurations = (
52B260460BC5A864007E00F1 /* Development */,
52B260470BC5A864007E00F1 /* Deployment */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
52B2605D0BC5A864007E00F1 /* Build configuration list for PBXNativeTarget "tokend" */ = {
isa = XCConfigurationList;
buildConfigurations = (
52B2605E0BC5A864007E00F1 /* Development */,
52B2605F0BC5A864007E00F1 /* Deployment */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
C27AD2220987FCDC001272E0 /* Build configuration list for PBXProject "Tokend" */ = {
isa = XCConfigurationList;
buildConfigurations = (
C27AD2230987FCDC001272E0 /* Development */,
C27AD2240987FCDC001272E0 /* Deployment */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Deployment;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}
14 years
esc/mac/Tokend-35209/CoolKey/pkcs11 compile.sh, NONE, 1.1.2.2 cryptoki.h, NONE, 1.1.2.2 mypkcs11.h, NONE, 1.1.2.2 pkcs11.h, NONE, 1.1.2.2 pkcs11f.h, NONE, 1.1.2.2 pkcs11t.h, NONE, 1.1.2.2
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/CoolKey/pkcs11
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528/CoolKey/pkcs11
Added Files:
Tag: PKI_8_0_RTM_BRANCH
compile.sh cryptoki.h mypkcs11.h pkcs11.h pkcs11f.h pkcs11t.h
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE compile.sh ---
#! /bin/csh
gcc -Ipkcs11 $argv[1]
***** Error reading new file: [Errno 2] No such file or directory: 'cryptoki.h'
--- NEW FILE mypkcs11.h ---
// ****************************************************************************
//
// Copyright (c) 2003 America Online, Inc. All rights reserved.
// This software contains valuable confidential and proprietary information
// of America Online, Inc. and is subject to applicable licensing agreements.
// Unauthorized reproduction, transmission or distribution of this file and
// its contents is a violation of applicable laws.
//
// A M E R I C A O N L I N E C O N F I D E N T I A L
//
// ****************************************************************************
#ifndef AOL_NKEY_MYPKCS11_H
#define AOL_NKEY_MYPKCS11_H
#if defined(_WIN32)
#define CK_PTR *
#define CK_DECLARE_FUNCTION(rv,func) rv __declspec(dllexport) func
#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (* func)
#define CK_CALLBACK_FUNCTION(rv,func) rv (* func)
#define CK_NULL_PTR 0
#else
#define CK_PTR *
#define CK_DECLARE_FUNCTION(rv,func) rv func
#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (* func)
#define CK_CALLBACK_FUNCTION(rv,func) rv (* func)
#define CK_NULL_PTR 0
#endif
#if defined(_WIN32)
#pragma warning(disable:4103)
#pragma pack(push, cryptoki, 1)
#endif
#include "pkcs11.h"
//#include "pkcs11n.h"
#if defined (_WIN32)
#pragma warning(disable:4103)
#pragma pack(pop, cryptoki)
#endif
#endif
***** Error reading new file: [Errno 2] No such file or directory: 'pkcs11.h'
***** Error reading new file: [Errno 2] No such file or directory: 'pkcs11f.h'
***** Error reading new file: [Errno 2] No such file or directory: 'pkcs11t.h'
14 years
esc/mac/Tokend-35209/CoolKey/mds coolkey_csp_capabilities.mdsinfo, NONE, 1.1.2.2 coolkey_csp_capabilities_common.mds, NONE, 1.1.2.2 coolkey_csp_primary.mdsinfo, NONE, 1.1.2.2 coolkey_dl_primary.mdsinfo, NONE, 1.1.2.2 coolkey_smartcard.mdsinfo, NONE, 1.1.2.2
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/CoolKey/mds
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528/CoolKey/mds
Added Files:
Tag: PKI_8_0_RTM_BRANCH
coolkey_csp_capabilities.mdsinfo
coolkey_csp_capabilities_common.mds
coolkey_csp_primary.mdsinfo coolkey_dl_primary.mdsinfo
coolkey_smartcard.mdsinfo
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE coolkey_csp_capabilities.mdsinfo ---
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>Capabilities</key>
<string>file:coolkey_csp_capabilities_common.mds</string>
<key>MdsFileDescription</key>
<string>CoolKey Token CSPDL CSP Capabilities</string>
<key>MdsFileType</key>
<string>PluginSpecific</string>
<key>MdsRecordType</key>
<string>MDS_CDSADIR_CSP_CAPABILITY_RECORDTYPE</string>
</dict>
</plist>
--- NEW FILE coolkey_csp_capabilities_common.mds ---
<?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">
<array>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_OUTPUT_SIZE</string>
<key>AttributeValue</key>
<integer>20</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DIGEST</string>
<key>Description</key>
<string>SHA1 Digest</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_MD5</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_OUTPUT_SIZE</string>
<key>AttributeValue</key>
<integer>16</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DIGEST</string>
<key>Description</key>
<string>MD5 Digest</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_MD2</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_OUTPUT_SIZE</string>
<key>AttributeValue</key>
<integer>16</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DIGEST</string>
<key>Description</key>
<string>MD2 Digest</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>RSA Key Pair Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_DES</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_KEY_LENGTH</string>
<key>AttributeValue</key>
<integer>64</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>DES Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_3DES_3KEY</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_KEY_LENGTH</string>
<key>AttributeValue</key>
<integer>192</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>3DES Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RC2</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>RC2 Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RC4</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>RC4 Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RC5</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>RC5 Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_CAST</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>New item</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>CAST Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_BLOWFISH</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>Blowfish Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1HMAC</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>SHA1HMAC Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_MD5HMAC</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>MD5HMAC Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_AES</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_KEY_LENGTH</string>
<key>AttributeValue</key>
<array>
<integer>128</integer>
<integer>192</integer>
<integer>256</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>AES Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_ASC</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>ASC Key Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_FEE</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_KEY_LENGTH</string>
<key>AttributeValue</key>
<array>
<integer>31</integer>
<integer>127</integer>
<integer>128</integer>
<integer>161</integer>
<integer>192</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>FEE Key Pair Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_DSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_KEYGEN</string>
<key>Description</key>
<string>DSA Key Pair Generation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_PKCS5_PBKDF2</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DERIVEKEY</string>
<key>Description</key>
<string>PKCS5 Key Derivation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_PKCS5_PBKDF1_MD5</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DERIVEKEY</string>
<key>Description</key>
<string>PKCS5 PBKDF1 MD5 Key Derivation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_PKCS5_PBKDF1_MD2</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DERIVEKEY</string>
<key>Description</key>
<string>PKCS5 PBKDF1 MD2 Key Derivation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_PKCS5_PBKDF1_SHA1</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_DERIVEKEY</string>
<key>Description</key>
<string>PKCS5 PBKDF1 SHA1 Key Derivation</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_DES</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>2</integer>
<integer>3</integer>
<integer>5</integer>
<integer>6</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>DES Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_3DES_3KEY_EDE</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>2</integer>
<integer>3</integer>
<integer>5</integer>
<integer>6</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>3DES EDE Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_AES</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>2</integer>
<integer>3</integer>
<integer>5</integer>
<integer>6</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>AES Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RC4</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>0</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>RC4 Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RC5</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>2</integer>
<integer>3</integer>
<integer>5</integer>
<integer>6</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>RC5 Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_BLOWFISH</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>2</integer>
<integer>3</integer>
<integer>5</integer>
<integer>6</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>Blowfish Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_CAST</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_MODE</string>
<key>AttributeValue</key>
<array>
<integer>2</integer>
<integer>3</integer>
<integer>5</integer>
<integer>6</integer>
</array>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SYMMETRIC</string>
<key>Description</key>
<string>CAST Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_ASYMMETRIC</string>
<key>Description</key>
<string>RSA Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_FEEDEXP</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_ASYMMETRIC</string>
<key>Description</key>
<string>FEEDExp Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_FEED</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_ASYMMETRIC</string>
<key>Description</key>
<string>FEED Encryption</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1WithRSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>SHA1 With RSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_MD5WithRSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>MD5 With RSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_MD2WithRSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>MD2 With RSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_RSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>Raw RSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1WithDSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>SHA1 With DSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_DSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>Raw DSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_FEE_MD5</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>MD5 with FEE Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_FEE_SHA1</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>SHA1 with FEE Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_FEE</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>Raw FEE Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1WithECDSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>SHA1 with ECDSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_ECDSA</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_SIGNATURE</string>
<key>Description</key>
<string>Raw ECDSA Signature</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1HMAC</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_OUTPUT_SIZE</string>
<key>AttributeValue</key>
<integer>20</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_MAC</string>
<key>Description</key>
<string>SHA1HMAC MAC</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_SHA1HMAC_LEGACY</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_OUTPUT_SIZE</string>
<key>AttributeValue</key>
<integer>20</integer>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_MAC</string>
<key>Description</key>
<string>SHA1HMAC MAC Legacy</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
<dict>
<key>AlgType</key>
<string>CSSM_ALGID_APPLE_YARROW</string>
<key>Attributes</key>
<array>
<dict>
<key>AttributeType</key>
<string>CSSM_ATTRIBUTE_NONE</string>
<key>AttributeValue</key>
<array/>
</dict>
</array>
<key>ContextType</key>
<string>CSSM_ALGCLASS_RANDOMGEN</string>
<key>Description</key>
<string>Yarrow PRNG</string>
<key>UseeTag</key>
<string>CSSM_USEE_NONE</string>
</dict>
</array>
</plist>
--- NEW FILE coolkey_csp_primary.mdsinfo ---
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>AclSubjectTypes</key>
<array>
<string>CSSM_ACL_SUBJECT_TYPE_PASSWORD</string>
<string>CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD</string>
<string>CSSM_ACL_SUBJECT_TYPE_PROTECTED_PASSWORD</string>
</array>
<key>AuthTags</key>
<!-- @@@ complete this -->
<array>
<string>CSSM_ACL_AUTHORIZATION_ANY</string>
</array>
<key>CspCustomFlags</key>
<integer>0</integer>
<key>CspFlags</key>
<!-- @@@ dynamic -->
<string>CSSM_CSP_STORES_PRIVATE_KEYS | CSSM_CSP_STORES_PUBLIC_KEYS | CSSM_CSP_STORES_CERTIFICATES | CSSM_CSP_STORES_GENERIC</string>
<key>CspType</key>
<string>CSSM_CSP_HARDWARE</string>
<key>MdsFileDescription</key>
<string>Token CSPDL CSP Primary info</string>
<key>MdsFileType</key>
<string>PluginSpecific</string>
<key>MdsRecordType</key>
<string>MDS_CDSADIR_CSP_PRIMARY_RECORDTYPE</string>
<key>ModuleName</key>
<string>AppleSDCSPDL</string>
<key>ProductVersion</key>
<string>0.1</string>
<key>SampleTypes</key>
<array>
<string>CSSM_SAMPLE_TYPE_PASSWORD</string>
<string>CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD</string>
<string>CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD</string>
</array>
<key>UseeTags</key>
<array/>
<key>Vendor</key>
<string>Apple Computer, Inc.</string>
</dict>
</plist>
--- NEW FILE coolkey_dl_primary.mdsinfo ---
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>AclSubjectTypes</key>
<array>
<string>CSSM_ACL_SUBJECT_TYPE_PASSWORD</string>
<string>CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD</string>
<string>CSSM_ACL_SUBJECT_TYPE_PROTECTED_PASSWORD</string>
</array>
<key>AuthTags</key>
<array>
<!-- @@@ complete this -->
<string>CSSM_ACL_AUTHORIZATION_ANY</string>
</array>
<key>ConjunctiveOps</key>
<array>
<string>CSSM_DB_NONE</string>
<string>CSSM_DB_AND</string>
<string>CSSM_DB_OR</string>
</array>
<key>DLType</key>
<string>CSSM_DL_FFS</string>
<key>MdsFileDescription</key>
<string>Token CSPDL DL Primary info</string>
<key>MdsFileType</key>
<string>PluginSpecific</string>
<key>MdsRecordType</key>
<string>MDS_CDSADIR_DL_PRIMARY_RECORDTYPE</string>
<key>ModuleName</key>
<string>AppleSDCSPDL</string>
<key>ProductVersion</key>
<string>0.1</string>
<key>QueryLimitsFlag</key>
<integer>0</integer>
<key>RelationalOps</key>
<array>
<string>CSSM_DB_EQUAL</string>
<string>CSSM_DB_LESS_THAN</string>
<string>CSSM_DB_GREATER_THAN</string>
<string>CSSM_DB_CONTAINS_FINAL_SUBSTRING</string>
<string>CSSM_DB_CONTAINS_INITIAL_SUBSTRING</string>
<string>CSSM_DB_CONTAINS</string>
<string></string>
</array>
<key>SampleTypes</key>
<array>
<string>CSSM_SAMPLE_TYPE_PASSWORD</string>
<string>CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD</string>
<string>CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD</string>
</array>
<key>Vendor</key>
<string>Apple Computer, Inc.</string>
</dict>
</plist>
--- NEW FILE coolkey_smartcard.mdsinfo ---
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>MdsFileDescription</key>
<string>SD/CSPDL Generic Smartcard Information</string>
<key>MdsRecordType</key>
<string>MDS_CDSADIR_CSP_SC_INFO_RECORDTYPE</string>
<key>MdsFileType</key>
<string>PluginSpecific</string>
<key>ScVendor</key>
<string>Generic</string>
<key>ScVersion</key>
<string>unknown</string>
<key>ScFirmwareVersion</key>
<string>unknown</string>
<key>ScFlags</key> <!-- @@@ dynamic -->
<integer>0</integer>
<key>ScCustomFlags</key>
<integer>0</integer>
</dict>
</plist>
14 years
esc/mac/Tokend-35209/CoolKey CoolKeyAttributeCoder.cpp, NONE, 1.1.2.2 CoolKeyAttributeCoder.h, NONE, 1.1.2.2 CoolKeyError.cpp, NONE, 1.1.2.2 CoolKeyError.h, NONE, 1.1.2.2 CoolKeyHandle.cpp, NONE, 1.1.2.2 CoolKeyHandle.h, NONE, 1.1.2.2 CoolKeyPK11.cpp, NONE, 1.1.2.2 CoolKeyPK11.h, NONE, 1.1.2.2 CoolKeyRecord.cpp, NONE, 1.1.2.2 CoolKeyRecord.h, NONE, 1.1.2.2 CoolKeySchema.cpp, NONE, 1.1.2.2 CoolKeySchema.h, NONE, 1.1.2.2 CoolKeyToken.cpp, NONE, 1.1.2.2 CoolKeyToken.h, NONE, 1.1.2.2 Info.plist, N
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/CoolKey
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528/CoolKey
Added Files:
Tag: PKI_8_0_RTM_BRANCH
CoolKeyAttributeCoder.cpp CoolKeyAttributeCoder.h
CoolKeyError.cpp CoolKeyError.h CoolKeyHandle.cpp
CoolKeyHandle.h CoolKeyPK11.cpp CoolKeyPK11.h
CoolKeyRecord.cpp CoolKeyRecord.h CoolKeySchema.cpp
CoolKeySchema.h CoolKeyToken.cpp CoolKeyToken.h Info.plist
coolkey.cpp dlfcn.h
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE CoolKeyAttributeCoder.cpp ---
/*CoolKey
* Copyright (c) 2004 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@
*/
/*
* CoolKeyAttributeCoder.cpp
* Tokend CoolKey
*/
#include "CoolKeyAttributeCoder.h"
#include "Adornment.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Attribute.h"
#include <security_utilities/logging.h>
#include "CoolKeyRecord.h"
#include "CoolKeyToken.h"
#include "CoolKeyPK11.h"
#include <Security/cssmtype.h>
#include <Security/SecKeychainItem.h>
#include <security_cdsa_utilities/cssmkey.h>
#include <Security/SecCertificate.h>
#include <Security/SecKey.h>
using namespace Tokend;
//
// CoolKeyDataAttributeCoder
//
CoolKeyDataAttributeCoder::~CoolKeyDataAttributeCoder()
{
}
void CoolKeyDataAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
Syslog::notice("CoolKeyDataAttributeCoder::decode");
}
CoolKeyCertAttributeCoder:: ~CoolKeyCertAttributeCoder()
{
}
void CoolKeyCertAttributeCoder::decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record)
{
uint32 id = metaAttribute.attributeId();
MetaAttribute::Format format = metaAttribute.attributeFormat();
CoolKeyToken *token = (CoolKeyToken *) tokenContext;
if(!token)
return;
CoolKeyRecord &coolRec = dynamic_cast<CoolKeyRecord &> (record);
CoolKeyCertObject *cert = (CoolKeyCertObject *) coolRec.getCoolKeyObject();
Syslog::notice("CertAttributeCoder::decode coder %p cert object %p id %lu format %lu record %p",this,cert,id,format,&record);
if(!cert)
return;
CK_BYTE tData[2048];
CK_ULONG dataLen = 2048;
CK_ULONG type = 0;
switch(id)
{
case kSecAlias:
Syslog::notice("kSecAlias");
cert->getLabel(tData,&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
case kSecSubjectItemAttr:
cert->getSubject(tData,&dataLen);
Syslog::notice("kSecSubjectItemAttr retrieved data %p datalen %lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
case kSecIssuerItemAttr:
cert->getIssuer(tData,&dataLen);
Syslog::notice("kSecIssuertItemAttr retrieved data %p datalen %lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
case kSecSerialNumberItemAttr:
cert->getSerialNo(tData,&dataLen);
Syslog::notice("kSecSerialNumnberItemAttr retrieved data %p datalen %lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
case kSecPublicKeyHashItemAttr:
Syslog::notice("kSecPublicKeyHashItemAttr");
getCertAttributeFromData(cert,kSecPublicKeyHashItemAttr, tData, &dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute((const void *)tData, dataLen));
break;
case kSecSubjectKeyIdentifierItemAttr:
Syslog::notice("kSecSubjectKeyIdentifierItemAttr");
break;
case kSecCertTypeItemAttr:
type = cert->getType();
Syslog::notice("kSecCertTypeItemAttr type %lu",type);
if(type == CKC_X_509)
type = CSSM_CERT_X_509v3;
else
if(type == CKC_X_509_ATTR_CERT)
type = CSSM_CERT_X_509_ATTRIBUTE;
else
type = CSSM_CERT_UNKNOWN;
Syslog::notice("kSecCertTypeItemAttr final type %lu",type);
record.attributeAtIndex(metaAttribute.attributeIndex(),new Attribute((uint32)type));
break;
case kSecCertEncodingItemAttr:
Syslog::notice("kSecCertEncodingItemAttr");
type = CSSM_CERT_ENCODING_BER;
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)type));
break;
case kSecLabelItemAttr:
cert->getLabel(tData,&dataLen);
Syslog::notice("kSecLabelItemAttr retrieved data %p datalen %lu",tData,dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
default:
Syslog::notice("missed one");
break;
};
}
void CoolKeyCertAttributeCoder::getCertAttributeFromData(CoolKeyCertObject *aCert,CK_ULONG aAttribute, CK_BYTE *aData, CK_ULONG *aDataLen)
{
CSSM_DATA csData;
CK_BYTE certData[2048];
CK_ULONG certDataLen = 2048;
OSStatus status = 0;
if(!aCert || !aData || *aDataLen <= 0)
return;
CK_ULONG size_in = *aDataLen;
*aDataLen = 0;
Syslog::notice("CoolKeyCertAttributeCoder::getCertAttributeFromData");
aCert->getData(certData,&certDataLen);
SecCertificateRef theCertificate;
csData.Data = certData;
csData.Length = certDataLen;
status = SecCertificateCreateFromData((CSSM_DATA * )&csData, CSSM_CERT_X_509v3,
CSSM_CERT_ENCODING_BER, &theCertificate);
if(status)
return;
Syslog::notice("CoolKeyCertAttributeCoder::getCertAttributeFromData done created cert");
SecKeychainAttribute ska = { kSecPublicKeyHashItemAttr };
SecKeychainItemRef tRef = (SecKeychainItemRef) theCertificate;
SecKeychainAttributeList skal = { 1, &ska };
status = SecKeychainItemCopyContent(tRef, NULL, &skal,
NULL, NULL);
Syslog::notice("CoolKeyCertAttributeCoder::getCertAttributeFromData done got attribute");
if(!status)
return;
if(ska.length < size_in)
{
memcpy(aData,ska.data,ska.length);
*aDataLen = ska.length;
}
SecKeychainItemFreeContent(&skal, NULL);
}
CoolKeyKeyAttributeCoder:: ~CoolKeyKeyAttributeCoder()
{
}
void CoolKeyKeyAttributeCoder::decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record)
{
Syslog::notice("CoolKeyKeyAttributeCoder::decode");
uint32 id = metaAttribute.attributeId();
MetaAttribute::Format format = metaAttribute.attributeFormat();
CoolKeyRecord &coolRec = dynamic_cast<CoolKeyRecord &> (record);
CoolKeyKeyObject *key = (CoolKeyKeyObject *) coolRec.getCoolKeyObject();
if(!key)
return;
CK_BYTE tData[2048];
CK_ULONG dataLen = 2048;
CK_ULONG value = 0;
CK_BYTE attrib = 0;
Syslog::notice("CoolKeyKeyAttributeCoder::decode coder %p id %d format %d record %p",this,id,format,&record);
switch(id)
{
case kSecKeyKeyClass:
Syslog::notice("kSecKeyKeyClass");
break;
case kSecKeyPrintName:
Syslog::notice("kSecKeyPrintName");
key->getLabel(tData,&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
case kSecKeyAlias:
Syslog::notice("kSecKeyAlias");
break;
case kSecKeyPermanent:
Syslog::notice("kSecKeyPermanent");
break;
case kSecKeyPrivate:
Syslog::notice("kSecKeyKeyPrivate");
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)1));
break;
case kSecKeyModifiable:
Syslog::notice("kSecKeyKeyModifiable");
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)0));
break;
case kSecKeyApplicationTag:
Syslog::notice("kSecKeyApplicationTag");
break;
case kSecKeyKeyCreator:
Syslog::notice("kSecKeyKeyCreator");
break;
case kSecKeyKeyType:
Syslog::notice("kSecKeyType");
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)CSSM_ALGID_RSA));
break;
case kSecKeyKeySizeInBits:
Syslog::notice("kSecKeyKeySizeInBits");
value = key->getKeySize();
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)value));
Syslog::notice("kSecKeyKeySizeInBits %d",value);
break;
case kSecKeyEffectiveKeySize:
Syslog::notice("kSecKeyEffectiveKeySize");
value = key->getKeySize();;
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)value));
Syslog::notice("kSecKeyEffectiveKeySizeInBits %d",value);
break;
case kSecKeyStartDate:
Syslog::notice("kSecKeyKeyStartDate");
break;
case kSecKeyEndDate:
Syslog::notice("kSecKeyKeyEndDate");
break;
case kSecKeySensitive:
attrib = key->getSensitive();
Syslog::notice("kSecKeySensitive %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyAlwaysSensitive:
attrib = key->getAlwaysSensitive();
Syslog::notice("kSecKeyAlwaysSensitive %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyExtractable:
Syslog::notice("kSecKeyExtractable");
attrib = key->getKeyExtractable();
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyNeverExtractable:
Syslog::notice("kSecKeyNeverExtractable");
attrib = key->getKeyNeverExtractable();
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyEncrypt:
Syslog::notice("kSecKeyKeyEncrypt");
attrib = key->getKeyEncrypt();
Syslog::notice("kSecKeyEncrypt value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyDecrypt:
attrib = key->getKeyDecrypt();
Syslog::notice("kSecKeyDecrypt value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyDerive:
attrib = key->getKeyDerive();
Syslog::notice("kSecKeyKeyDerive %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeySign:
attrib = key->getKeySign();
Syslog::notice("kSecKeyKeySign value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyVerify:
attrib = key->getKeyVerify();
Syslog::notice("kSecKeyKeyVerify value %d",attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeySignRecover:
attrib = key->getKeySignRecover();
Syslog::notice("kSecKeyKeySignRecover %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyVerifyRecover:
attrib = key->getKeyVerifyRecover();
Syslog::notice("kSecKeyKeyVerifyRecover %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyWrap:
attrib = key->getKeyWrap();
Syslog::notice("kSecKeyKeyWrap %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyUnwrap:
attrib = key->getKeyUnwrap();
Syslog::notice("kSecKeyKeyUnwrap %d", attrib);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((uint32)attrib));
break;
case kSecKeyLabel:
Syslog::notice("kSecKeyLabel");
key->getLabel(tData,&dataLen);
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute((const void *)tData,dataLen));
break;
};
}
/* arch-tag: 36510900-0DBC-11D9-9CFC-000A9595DEEE */
--- NEW FILE CoolKeyAttributeCoder.h ---
/*
* Copyright (c) 2004 Apple Computer, ICoolKeync. 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@
*/
/*
* CoolKeyAttributeCoder.h
* Tokend CoolKey
*/
#ifndef _COOLKEY_ATTRIBUTECODER_H_
#define _COOLKEY_ATTRIBUTECODER_H_
#include "AttributeCoder.h"
#include <string>
#include <PCSC/musclecard.h>
#include "CoolKeyPK11.h"
//
// A coder that reads the data of an object
//
class CoolKeyDataAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(CoolKeyDataAttributeCoder)
public:
CoolKeyDataAttributeCoder() {}
virtual ~CoolKeyDataAttributeCoder();
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record);
};
class CoolKeyCertAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(CoolKeyCertAttributeCoder)
public:
CoolKeyCertAttributeCoder() {}
virtual ~CoolKeyCertAttributeCoder();
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record);
protected:
void getCertAttributeFromData(CoolKeyCertObject *aCert,CK_ULONG aAttribute, CK_BYTE *aData, CK_ULONG *aDataLen);
};
class CoolKeyKeyAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(CoolKeyKeyAttributeCoder)
public:
CoolKeyKeyAttributeCoder() {}
virtual ~CoolKeyKeyAttributeCoder();
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute, Tokend::Record &record);
};
#endif /* !_CoolKeyATTRIBUTECODER_H_ */
/* arch-tag: 366E16D4-0DBC-11D9-B030-000A9595DEEE */
--- NEW FILE CoolKeyError.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* CoolKeyError.cpp
* TokendMuscle
*/
#include "CoolKeyError.h"
#include <Security/cssmerr.h>
//
// CoolKeyError exceptions
//
CoolKeyError::CoolKeyError(uint16_t sw) : SCardError(sw)
{
IFDEBUG(debugDiagnose(this));
}
const char *CoolKeyError::what() const throw ()
{ return "CoolKey Error"; }
OSStatus CoolKeyError::osStatus() const
{
switch (statusWord)
{
case COOLKEY_AUTHENTICATION_FAILED_0:
case COOLKEY_AUTHENTICATION_FAILED_1:
case COOLKEY_AUTHENTICATION_FAILED_2:
case COOLKEY_AUTHENTICATION_FAILED_3:
return CSSM_ERRCODE_OPERATION_AUTH_DENIED;
default:
return SCardError::osStatus();
}
}
void CoolKeyError::throwMe(uint16_t sw)
{ throw CoolKeyError(sw); }
#if !defined(NDEBUG)
void CoolKeyError::debugDiagnose(const void *id) const
{
secdebug("exception", "%p CoolKeyError %s (%04hX)",
id, errorstr(statusWord), statusWord);
}
const char *CoolKeyError::errorstr(uint16_t sw) const
{
switch (sw)
{
case COOLKEY_AUTHENTICATION_FAILED_0:
return "Authentication failed, 0 retries left.";
case COOLKEY_AUTHENTICATION_FAILED_1:
return "Authentication failed, 1 retry left.";
case COOLKEY_AUTHENTICATION_FAILED_2:
return "Authentication failed, 2 retries left.";
case COOLKEY_AUTHENTICATION_FAILED_3:
return "Authentication failed, 3 retries left.";
default:
return SCardError::errorstr(sw);
}
}
#endif //NDEBUG
/* arch-tag: 0D984528-10D9-11D9-84A3-000393D5F80A */
--- NEW FILE CoolKeyError.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* CoolKeyError.h
* TokendMuscle
*/
#ifndef _COOLKEY_ERROR_H_
#define _COOLKEY_ERROR_H_
/** Entered PIN is not correct and pin was blocked. */
#define COOLKEY_AUTHENTICATION_FAILED_0 0x6300
/** Entered PIN is not correct, 1 try left. */
#define COOLKEY_AUTHENTICATION_FAILED_1 0x6301
/** Entered PIN is not correct, 2 tries left. */
#define COOLKEY_AUTHENTICATION_FAILED_2 0x6302
/** Entered PIN is not correct, 3 tries left. */
#define COOLKEY_AUTHENTICATION_FAILED_3 0x6303
#include "SCardError.h"
class CoolKeyError : public Tokend::SCardError
{
protected:
CoolKeyError(uint16_t sw);
public:
OSStatus osStatus() const;
virtual const char *what () const throw ();
static void check(uint16_t sw) { if (sw != SCARD_SUCCESS) throwMe(sw); }
static void throwMe(uint16_t sw) __attribute__((noreturn));
protected:
IFDEBUG(void debugDiagnose(const void *id) const;)
IFDEBUG(const char *errorstr(uint16_t sw) const;)
};
#endif /* !_CoolKeyERROR_H_ */
/* arch-tag: 0EB9B81B-10D9-11D9-BA83-000393D5F80A */
--- NEW FILE CoolKeyHandle.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* CoolKeyKeyHandle.cpp
* Tokend CoolKey
*/
#include "CoolKeyHandle.h"
#include "CoolKeyRecord.h"
#include "CoolKeyToken.h"
#include <security_utilities/debugging.h>
#include <security_utilities/utilities.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include <security_cdsa_client/aclclient.h>
#include <Security/cssmerr.h>
#include <security_utilities/logging.h>
static const unsigned char sha1sigheader[] =
{
0x30, // SEQUENCE
0x21, // LENGTH
0x30, // SEQUENCE
0x09, // LENGTH
0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1a, // SHA1 OID (1 4 14 3 2 26)
0x05, 0x00, // OPTIONAL ANY algorithm params (NULL)
0x04, 0x14 // OCTECT STRING (20 bytes)
};
static const unsigned char md5sigheader[] =
{
0x30, // SEQUENCE
0x20, // LENGTH
0x30, // SEQUENCE
0x0C, // LENGTH
// MD5 OID (1 2 840 113549 2 5)
0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05,
0x05, 0x00, // OPTIONAL ANY algorithm params (NULL)
0x04, 0x10 // OCTECT STRING (16 bytes)
};
using CssmClient::AclFactory;
//
// CoolKeyKeyHandle
//
CoolKeyKeyHandle::CoolKeyKeyHandle(CoolKeyToken &coolToken,
const Tokend::MetaRecord &metaRecord, CoolKeyRecord &coolKey) :
Tokend::KeyHandle(metaRecord, &coolKey),
mToken(coolToken),mRecord(coolKey)
{
}
CoolKeyKeyHandle::~CoolKeyKeyHandle()
{
}
void CoolKeyKeyHandle::getKeySize(CSSM_KEY_SIZE &keySize)
{
Syslog::notice("CoolKeyHandle::getKeySize");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
uint32 CoolKeyKeyHandle::getOutputSize(const Context &context, uint32 inputSize,
bool encrypting)
{
Syslog::notice("CoolKeyHandle::getOutputSize");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
return 0;
}
void CoolKeyKeyHandle::generateSignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature)
{
Syslog::notice("CoolKeyHandle::generateSignature Input length %d context.type %d context.alg %d",input.length(),context.type(),context.algorithm());
CoolKeyObject * coolObj = mRecord.getCoolKeyObject();
if(!coolObj || coolObj->getClass() != CKO_PRIVATE_KEY)
{
Syslog::notice("Can't find object for record %p or incorrect object type", &mRecord);
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
CoolKeyKeyObject * keyObj = (CoolKeyKeyObject *) coolObj;
CK_ULONG keyLength = keyObj->getKeySize() / 8;
Syslog::notice("keyLength %d",keyLength);
if (context.type() != CSSM_ALGCLASS_SIGNATURE)
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
if (context.algorithm() != CSSM_ALGID_RSA)
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
// Find out if we are doing a SHA1 or MD5 signature and setup header to
// point to the right asn1 blob.
const unsigned char *header = NULL;
size_t headerLength = 0;
if (signOnly == CSSM_ALGID_SHA1)
{
Syslog::notice("Asking for SHA1");
header = sha1sigheader;
headerLength = sizeof(sha1sigheader);
Syslog::notice("header is sha1sigheader, len %d", headerLength);
if (input.Length != 20)
CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);
}
else if (signOnly == CSSM_ALGID_MD5)
{
Syslog::notice("Asking for MD5");
header = md5sigheader;
headerLength = sizeof(md5sigheader);
Syslog::notice("header is md5sigheader, len %d", headerLength);
if (input.Length != 16)
CssmError::throwMe(CSSMERR_CSP_BLOCK_SIZE_MISMATCH);
}
else if (signOnly == CSSM_ALGID_NONE)
{
header = NULL;
headerLength = 0;
Syslog::notice("Asking for CSSM_ALGID_NONE");
// Special case used by SSL it's an RSA signature, without the ASN1 stuff
}
else
CssmError::throwMe(CSSMERR_CSP_INVALID_DIGEST_ALGORITHM);
CoolKeyPK11 pk11Manager = mToken.getPK11Manager();
int loggedIn = pk11Manager.isTokenLoggedIn();
if(!loggedIn)
{
Syslog::error("Can't sign , not logged in.");
CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
}
signature.Data =( uint8*) malloc(keyLength);
// Create an input buffer in which we construct the data we will send to
// the token.
size_t inputDataSize = headerLength + input.Length;
Syslog::notice("inputDataSize %d", inputDataSize);
auto_array<unsigned char> inputData(keyLength);
unsigned char *to = inputData.get();
// Get padding, but default to pkcs1 style padding
uint32 padding = CSSM_PADDING_NONE;
context.getInt(CSSM_ATTRIBUTE_PADDING, padding);
Syslog::notice("padding value %d",padding);
if (padding == CSSM_PADDING_PKCS1)
{
Syslog::notice("CSSM_PADDING_PKCS1.");
// Add PKCS1 style padding
*(to++) = 0;
*(to++) = 1; /* Private Key Block Type. */
size_t padLength = keyLength - 3 - inputDataSize;
Syslog::notice("padlength %d",padLength);
memset(to, 0xff, padLength);
to += padLength;
*(to++) = 0;
inputDataSize = keyLength;
}
else if (padding == CSSM_PADDING_NONE)
{
Syslog::notice("CSSM_PADDING_NONE");
// Token will fail if the input data isn't exactly keysize / 8 octects
// long
}
else
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_PADDING);
if (headerLength)
{
memcpy(to, header, headerLength);
to += headerLength;
}
// Finally copy the passed in data to the input buffer.
memcpy(to, input.Data, input.Length);
if(!signature.Data)
{
Syslog::error("Can't allocate memory for signature operation.");
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
signature.Length = (size_t) keyLength;
int result = pk11Manager.generateSignature(coolObj,inputData.get(),inputDataSize,signature.Data,&signature.Length);
if(!result)
{
Syslog::notice("Problem generating signature");
if(signature.Data)
free(signature.Data);
CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED);
}
Syslog::notice("generateSignature returned %d data lenght %d", result, signature.Length);
}
void CoolKeyKeyHandle::verifySignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input, const CssmData &signature)
{
Syslog::notice("CoolKeyHandle::verifySignature");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::generateMac(const Context &context,
const CssmData &input, CssmData &output)
{
Syslog::notice("CoolKeyHandle::generateMac");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::verifyMac(const Context &context,
const CssmData &input, const CssmData &compare)
{
Syslog::notice("CoolKeyHandle::verifyMac");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::encrypt(const Context &context,
const CssmData &clear, CssmData &cipher)
{
Syslog::notice("CoolKeyHandle::encrypt");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::decrypt(const Context &context,
const CssmData &cipher, CssmData &clear)
{
Syslog::notice("CoolKeyHandle::decrypt type %d alg %d length %d",context.type(), context.algorithm(),cipher.length());
CoolKeyObject * coolObj = mRecord.getCoolKeyObject();
if(!coolObj || coolObj->getClass() != CKO_PRIVATE_KEY )
{
Syslog::notice("Can't find object for record or incorrect object %p", &mRecord);
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
CoolKeyKeyObject * keyObj = (CoolKeyKeyObject *) coolObj;
CK_ULONG keyLength = keyObj->getKeySize() / 8;
Syslog::notice("keyLength %d",keyLength);
if (context.type() != CSSM_ALGCLASS_ASYMMETRIC)
{
Syslog::error("In decrypt wrong key type, not asymmetric");
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
}
if (context.algorithm() != CSSM_ALGID_RSA)
{
Syslog::error("In decrypt wrong algorithm, not RSA");
CssmError::throwMe(CSSMERR_CSP_INVALID_ALGORITHM);
}
CoolKeyPK11 pk11Manager = mToken.getPK11Manager();
int loggedIn = pk11Manager.isTokenLoggedIn();
if(!loggedIn)
{
Syslog::error("Can't decrypt , not logged in.");
CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
}
clear.Data = (uint8 *) malloc((size_t) keyLength);
clear.Length = keyLength;
if(!clear.Data)
{
Syslog::error("Can't allocate data for decrype operation.");
CssmError::throwMe(CSSM_ERRCODE_INVALID_DATA);
}
int result = pk11Manager.decryptData(coolObj,cipher.Data,cipher.Length,clear.Data,&clear.Length);
if(!result)
{
Syslog::error("Problem with decrypt operation");
if(clear.Data)
{
free(clear.Data);
}
CssmError::throwMe(CSSMERR_CSP_FUNCTION_FAILED);
}
Syslog::notice("decryptData returned %d data lenght %d", result, clear.Length);
}
void CoolKeyKeyHandle::exportKey(const Context &context,
const AccessCredentials *cred, CssmKey &wrappedKey)
{
Syslog::notice("CoolKeyHandle::exportKey");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void CoolKeyKeyHandle::getOwner(AclOwnerPrototype &owner)
{
Syslog::notice("CoolKeyKeyHandle::getOwner");
if (!mAclOwner) {
Allocator &alloc = Allocator::standard();
mAclOwner.allocator(alloc);
mAclOwner = AclFactory::AnySubject(alloc);
}
owner = mAclOwner;
}
void CoolKeyKeyHandle::getAcl(const char *tag, uint32 &count, AclEntryInfo *&aclList)
{
Syslog::notice("CoolKeyKeyHandle::getAcl tag %s",tag);
// we don't (yet) support queries by tag
if (tag)
CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_ENTRY_TAG);
if(!mAclEntries) {
mAclEntries.allocator(Allocator::standard());
// Anyone can read the DB record for this key (which is a reference
// CSSM_KEY)
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
CssmData prompt;
CoolKeyPK11 pk11Manager = mToken.getPK11Manager();
int loggedIn = pk11Manager.isTokenLoggedIn();
if(!loggedIn)
{
Syslog::notice("CoolKeyKeyHandle:getAcl token NOT logged in already");
mAclEntries.add(CssmClient::AclFactory::PromptPWSubject(
mAclEntries.allocator(), prompt),
AclAuthorizationSet(
CSSM_ACL_AUTHORIZATION_SIGN
, CSSM_ACL_AUTHORIZATION_DECRYPT,CSSM_ACL_AUTHORIZATION_ENCRYPT, 0));
}
else
{
Syslog::notice("CoolKeyKeyHandle:getAcl token logged in already");
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(
CSSM_ACL_AUTHORIZATION_SIGN
, CSSM_ACL_AUTHORIZATION_DECRYPT,CSSM_ACL_AUTHORIZATION_ENCRYPT, 0));
}
}
count = mAclEntries.size();
aclList = mAclEntries.entries();
}
//
// CoolKeyKeyHandleFactory
//
CoolKeyKeyHandleFactory::~CoolKeyKeyHandleFactory()
{
}
Tokend::KeyHandle *CoolKeyKeyHandleFactory::keyHandle(
Tokend::TokenContext *tokenContext, const Tokend::MetaRecord &metaRecord,
Tokend::Record &record) const
{
Syslog::notice("CoolKeyKeyHandleFactory::keyHandle record %p ",&record);
CoolKeyToken &theToken = static_cast<CoolKeyToken& >(*tokenContext);
CoolKeyRecord &keyRecord = dynamic_cast<CoolKeyRecord &>(record);
return new CoolKeyKeyHandle(theToken, metaRecord, keyRecord);
}
/* arch-tag: 3685A262-0DBC-11D9-BC66-000A9595DEEE */
--- NEW FILE CoolKeyHandle.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* CoolKeyKeyHandle.h
* Tokend CoolKey
*/
#ifndef _COOLKEY_KEYHANDLE_H_
#define _COOLKEY_KEYHANDLE_H_
#include "KeyHandle.h"
class CoolKeyToken;
class CoolKeyRecord;
//
// A KeyHandle object which implements the crypto interface to muscle.
//
class CoolKeyKeyHandle: public Tokend::KeyHandle
{
NOCOPY(CoolKeyKeyHandle)
public:
CoolKeyKeyHandle(CoolKeyToken &cacToken, const Tokend::MetaRecord &metaRecord,
CoolKeyRecord &cacKey);
~CoolKeyKeyHandle();
virtual void getKeySize(CSSM_KEY_SIZE &keySize);
virtual uint32 getOutputSize(const Context &context, uint32 inputSize,
bool encrypting);
virtual void generateSignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input, CssmData &signature);
virtual void verifySignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input,
const CssmData &signature);
virtual void generateMac(const Context &context, const CssmData &input,
CssmData &output);
virtual void verifyMac(const Context &context, const CssmData &input,
const CssmData &compare);
virtual void encrypt(const Context &context, const CssmData &clear,
CssmData &cipher);
virtual void decrypt(const Context &context, const CssmData &cipher,
CssmData &clear);
virtual void exportKey(const Context &context,
const AccessCredentials *cred, CssmKey &wrappedKey);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count, AclEntryInfo *&aclList);
private:
AutoAclOwnerPrototype mAclOwner;
AutoAclEntryInfoList mAclEntries;
CoolKeyToken &mToken;
CoolKeyRecord &mRecord;
};
//
// A factory that creates CoolKeyKeyHandle objects.
//
class CoolKeyKeyHandleFactory : public Tokend::KeyHandleFactory
{
NOCOPY(CoolKeyKeyHandleFactory)
public:
CoolKeyKeyHandleFactory() {}
virtual ~CoolKeyKeyHandleFactory();
virtual Tokend::KeyHandle *keyHandle(Tokend::TokenContext *tokenContext,
const Tokend::MetaRecord &metaRecord, Tokend::Record &record) const;
};
#endif /* !_CoolKeyKEYHANDLE_H_ */
/* arch-tag: 36A35766-0DBC-11D9-BB4D-000A9595DEEE */
--- NEW FILE CoolKeyPK11.cpp ---
/*
* CoolKeyPK11.cpp - CoolKey.tokend PKCS11 helper class
*/
#include "CoolKeyPK11.h"
#include <security_utilities/logging.h>
#include <dlfcn.h>
CK_ATTRIBUTE obj_classTemplate[] = {
{CKA_CLASS,NULL,0}
};
CK_ATTRIBUTE certTemplate[] = {
{CKA_CERTIFICATE_TYPE,NULL,0},{CKA_LABEL,NULL,0},
{CKA_SUBJECT,NULL,0},{CKA_ID,NULL,0},{CKA_ISSUER,NULL,0},
{CKA_SERIAL_NUMBER,NULL,0}, {CKA_VALUE,NULL,0}
};
CK_ATTRIBUTE public_keyTemplate[] = {
{CKA_KEY_TYPE,NULL,0},{CKA_ID,NULL,0},{CKA_LABEL,NULL,0},{CKA_MODULUS,NULL,0},
{CKA_PUBLIC_EXPONENT,NULL,0},{CKA_START_DATE,NULL,0},
{CKA_END_DATE,NULL,0},
{CKA_ENCRYPT,NULL,0},{CKA_VERIFY,NULL,0},{CKA_VERIFY_RECOVER,NULL,0},
{CKA_WRAP,NULL,0}
};
CK_ATTRIBUTE private_keyTemplate[] = {
{CKA_KEY_TYPE,NULL,0},{CKA_ID,NULL,0},{CKA_MODULUS,NULL,0},
{CKA_LABEL,NULL,0},{CKA_START_DATE,NULL,0},
{CKA_END_DATE,NULL,0}, {CKA_SENSITIVE,NULL,0},
{CKA_DECRYPT,NULL,0}, {CKA_SIGN,NULL,0}, {CKA_SIGN_RECOVER,NULL,0},
{CKA_UNWRAP,NULL,0}, {CKA_EXTRACTABLE,NULL,0}, {CKA_ALWAYS_SENSITIVE,NULL,0},
{CKA_NEVER_EXTRACTABLE,NULL,0},
{CKA_UNWRAP_TEMPLATE,NULL,0},{CKA_ALWAYS_AUTHENTICATE}
};
CK_ATTRIBUTE secret_keyTemplate[] = {
{CKA_KEY_TYPE,NULL,0},{CKA_ID,NULL,0},{CKA_LABEL,NULL,0},
{CKA_SENSITIVE,NULL,0},{CKA_ENCRYPT,NULL,0},{CKA_DECRYPT,NULL,0},
{CKA_SIGN,NULL,0},{CKA_VERIFY,NULL,0},{CKA_WRAP,NULL,0},{CKA_UNWRAP,NULL,0},
{CKA_EXTRACTABLE,NULL,0},{CKA_ALWAYS_SENSITIVE,NULL,0},{CKA_NEVER_EXTRACTABLE,NULL,0},
{CKA_CHECK_VALUE,NULL,0},{CKA_WRAP_WITH_TRUSTED,NULL,0},{CKA_TRUSTED,NULL,0},
{CKA_WRAP_TEMPLATE,NULL,0}
};
int CoolKeyPK11::loginToken(char *aPIN)
{
if(!mInitialized)
return 0;
if(!aPIN)
return 0;
CK_RV ck_rv = mEpv->C_Login(mSessHandle,CKU_USER,(CK_UTF8CHAR_PTR ) aPIN,(CK_ULONG) strlen(aPIN));
Syslog::notice("CoolKeyPK11::loginToken result %d aPin %s ",ck_rv,"****");
if(ck_rv == CKR_OK && !mCachedPIN.size())
{
//Syslog::notice("CoolKeyPK11::loginToken setting cached PIN");
mCachedPIN = aPIN;
}
return ck_rv;
}
void CoolKeyPK11::logoutToken()
{
if(!mInitialized)
return;
CK_RV ck_rv = mEpv->C_Logout(mSessHandle);
//clear cached pin
mCachedPIN = "";
Syslog::notice("CoolKeyPK11::logout result %d ",ck_rv);
}
int CoolKeyPK11::verifyCachedPIN(char *aPIN)
{
if(!aPIN || !mInitialized)
return CKR_PIN_INCORRECT;
if(!strcmp(aPIN,(char *) mCachedPIN.c_str()))
{
Syslog::notice("PIN OK!");
return CKR_OK;
}
Syslog::notice("PIN not OK!");
return CKR_PIN_INCORRECT;
}
int CoolKeyPK11::isTokenLoggedIn()
{
CK_RV ck_rv;
if(!mInitialized)
return 0;
CK_SESSION_INFO sinfo;
CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
ck_rv = mEpv->C_GetSessionInfo(mSessHandle, &sinfo);
if( CKR_OK != ck_rv ) {
Syslog::notice("isTokenLoggedIn C_GetSessionInfo(0x%08x) returned %lu ulDeviceError %lu", mSessHandle, ck_rv,sinfo.ulDeviceError);
ck_rv = mEpv->C_OpenSession(mSlots[mOurSlotIndex], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
if( CKR_OK != ck_rv ) {
Syslog::error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x", mSlots[mOurSlotIndex], ck_rv);
return 0;
}
ck_rv = mEpv->C_GetSessionInfo(h, &sinfo);
if( CKR_OK != ck_rv) {
Syslog::error("Failed second chance to get session info!!");
return 0;
}
else
{
Syslog::notice("Created new session handle, old one is invalid! 0x%08x ",h);
mSessHandle = h;
}
}
int loggedIn = 0;
Syslog::notice("isTokenLoggedIn token state %d", sinfo.state);
if(sinfo.state == CKS_RO_USER_FUNCTIONS || sinfo.state == CKS_RW_USER_FUNCTIONS)
{
Syslog::notice("isTokenLoggedIn Token IS logged in");
loggedIn = 1;
}
else
{
Syslog::notice("isTokenLoggedIn Token IS NOT logged in");
}
return loggedIn;
}
int CoolKeyPK11::loadModule()
{
CK_RV ck_rv;
CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR) NULL;
CK_C_GetFunctionList gfl;
CK_C_INITIALIZE_ARGS InitArgs;
InitArgs.CreateMutex=0; //CK_CREATEMUTEX
InitArgs.DestroyMutex=0; //CK_DESTROYMUTEX
InitArgs.LockMutex=0; //CK_LOCKMUTEX
InitArgs.UnlockMutex=0; //CK_UNLOCKMUTEX
InitArgs.flags=0; //CK_FLAGS
InitArgs.pReserved=0; //CK_C_INITIALIZE_ARGS
mTokenUid[0] = 0;
mPk11Driver = dlopen(PKCS11_PATH_NAME,RTLD_LAZY);
if(!mPk11Driver)
{
Syslog::error("Can't load pkcs11 driver error: %d ",dlerror());
return 0;
}
else
{
Syslog::debug("In CoolKeyToken::loadPKCS11() . past load lib %p ",mPk11Driver);
}
// Now try to load the functions
gfl =(CK_C_GetFunctionList) dlsym(mPk11Driver,"C_GetFunctionList");
if(gfl == NULL)
{
Syslog::error("In CoolKeyToken::loadPKCS11() Can't load symbol C_GetFunctionList error: $d ",dlerror());
dlclose(mPk11Driver);
mPk11Driver = NULL;
return 0;
}
//Syslog::debug("Found C_GetFunctionList : %p " , gfl);
ck_rv = (*gfl)(&epv);
if(ck_rv != CKR_OK)
{
Syslog::error("Can't get actual function list ");
dlclose(mPk11Driver);
mPk11Driver = NULL;
return 0;
}
//Syslog::debug("Function list found %p ", epv);
mEpv = epv;
//Now try to actually initialize the module
ck_rv = mEpv->C_Initialize(&InitArgs);
if(ck_rv != CKR_OK)
{
Syslog::error("Error initializing PKCS11 module result: %d ",ck_rv);
dlclose(mPk11Driver);
mPk11Driver = NULL;
mEpv = NULL;
return 0;
}
//Syslog::debug("Successfully Initialized PKCS11 module. ");
mInitialized = 1;
int res = loadSlotList();
if(res)
{
mIsOurToken = 1;
}
else
mInitialized = 0;
return res;
}
int CoolKeyPK11::freeModule()
{
if(!mInitialized)
{
return 1;
}
if(mEpv)
{
mEpv->C_Finalize(NULL);
mInitialized = NULL;
}
return 1;
}
int CoolKeyPK11::freeObjects()
{
return 1;
}
int CoolKeyPK11::loadObjects()
{
CK_RV ck_rv;
if(!mInitialized)
return 0;
CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
CK_SESSION_INFO sinfo;
CK_ULONG tnObjects = 0;
mSessHandle = 0;
ck_rv = mEpv->C_OpenSession(mSlots[mOurSlotIndex], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
if( CKR_OK != ck_rv ) {
Syslog::error("C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x", mSlots[mOurSlotIndex], ck_rv);
return 0;
}
Syslog::notice(" Opened a session: handle = 0x%08x", h);
mSessHandle = h;
ck_rv = mEpv->C_GetSessionInfo(h, &sinfo);
if( CKR_OK != ck_rv ) {
Syslog::notice("C_GetSessionInfo(%lu, ) returned 0x%08x", h, ck_rv);
return 0;
}
Syslog::notice(" SESSION INFO:");
Syslog::notice(" slotID = %lu", sinfo.slotID);
Syslog::notice(" state = %lu", sinfo.state);
Syslog::notice(" flags = 0x%08x", sinfo.flags);
Syslog::notice(" ulDeviceError = %lu", sinfo.ulDeviceError);
ck_rv = mEpv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0);
if( CKR_OK != ck_rv ) {
Syslog::error("C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08x", h, ck_rv);
return 0;
}
Syslog::notice(" All objects:");
while(1) {
CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
CK_ULONG nObjects = 0;
ck_rv = mEpv->C_FindObjects(h, &o, 1, &nObjects);
if( CKR_OK != ck_rv ) {
Syslog::notice("C_FindObjects(%lu, , 1, ) returned 0x%08x", h, ck_rv);
return 0;
}
if( 0 == nObjects ) {
break;
}
tnObjects++;
Syslog::notice(" OBJECT HANDLE %lu", o);
ck_rv = mEpv->C_GetAttributeValue(h, o, obj_classTemplate, 1);
//Syslog::notice("ck_rv %d",ck_rv);
switch( ck_rv ) {
case CKR_OK:
case CKR_ATTRIBUTE_SENSITIVE:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_BUFFER_TOO_SMALL:
break;
default:
Syslog::notice("C_GetAtributeValue(%lu, %lu, {one attribute type}, %lu) returned 0x%08x",
h, o, 1, ck_rv);
return 0;
}
if( 1 ) {
if( -1 != (CK_LONG)obj_classTemplate[0].ulValueLen ) {
obj_classTemplate[0].pValue = (CK_VOID_PTR) new char[obj_classTemplate[0].ulValueLen];
if(!obj_classTemplate[0].pValue)
{
Syslog::notice("Can't allocate memory for attribute of size %d",(int) obj_classTemplate[0].ulValueLen);
continue;
}
ck_rv = mEpv->C_GetAttributeValue(h, o, obj_classTemplate, 1);
if(ck_rv == CKR_OK)
{
CK_LONG obj_class = (CK_LONG) *((CK_LONG *) obj_classTemplate[0].pValue);
Syslog::notice("objclass: %lu",obj_class);
CoolKeyObject *newObject = NULL;
switch(obj_class)
{
case CKO_CERTIFICATE:
Syslog::notice("Found certificate:-----------------");
newObject = (CoolKeyObject *) new CoolKeyCertObject(o,h,obj_class,this);
break;
case CKO_PUBLIC_KEY:
Syslog::notice("Found public key:----------------");
newObject = (CoolKeyObject *) new CoolKeyKeyObject(o,h,obj_class,this);
Syslog::notice("Found public key:");
break;
case CKO_PRIVATE_KEY:
Syslog::notice("Found private key:-------------------");
newObject = (CoolKeyObject *) new CoolKeyKeyObject(o,h,obj_class,this);
break;
default:
Syslog::notice("Found something else:");
break;
};
if(newObject)
{
mObjects[o] = newObject;
}
}
if(obj_classTemplate[0].pValue)
delete [] (char *) obj_classTemplate[0].pValue;
obj_classTemplate[0].pValue = NULL;
}
}
} /* while(1) */
ck_rv = mEpv->C_FindObjectsFinal(h);
if( CKR_OK != ck_rv ) {
Syslog::notice("C_FindObjectsFinal(%lu) returned 0x%08x", h, ck_rv);
return 0;
}
Syslog::notice(" (%lu objects total)", tnObjects);
ck_rv = mEpv->C_CloseSession(h);
if( CKR_OK != ck_rv ) {
Syslog::notice( "C_CloseSession(%lu) returned 0x%08x", h, ck_rv);
return 0;
}
return 1;
}
int CoolKeyPK11::loadSlotList()
{
mTokenUid[0] = 0;
int result = 0;
if(!mInitialized)
{
return result;
}
CK_RV ck_rv = 0;
CK_ULONG nSlots = 0;
ck_rv = mEpv->C_GetSlotList(CK_FALSE,(CK_SLOT_ID) CK_NULL_PTR,&nSlots);
if(ck_rv == CKR_OK)
{
Syslog::notice("In CoolKeyPK11:loadSlotList() GetSlotList found %d slot(s) ",nSlots);
}
else
{
Syslog::notice("In CoolKeyToken::probe() GetSlotList error: %d ",ck_rv);
}
if(nSlots > COOLKEY_MAX_SLOTS)
{
return result;
}
if(nSlots > 0)
{
ck_rv = mEpv->C_GetSlotList(CK_FALSE,mSlots, &nSlots);
if(ck_rv != CKR_OK)
{
Syslog::debug("In CoolKeyToken::probe() GetSlotList error: %d ",ck_rv);
}
mOurSlotIndex = nSlots - 1;
for(CK_ULONG i = 0; i < nSlots ; i++)
{
CK_SLOT_INFO sinfo;
int j = 0;
while( j++ < 5)
{
ck_rv = mEpv->C_GetSlotInfo(mSlots[i],&sinfo);
if(ck_rv != CKR_OK)
{
Syslog::error("In CoolKeyPK11::loadSlotListe() GetSlotInfo error: %d ",ck_rv);
break;
//continue;
}
Syslog::notice(" Slot Info: Slot: %d" ,i);
Syslog::notice(" slotDescription = \"%.64s\"", sinfo.slotDescription);
Syslog::notice(" manufacturerID = \"%.32s\"", sinfo.manufacturerID);
Syslog::notice(" flags = 0x%08lx", sinfo.flags);
Syslog::notice(" -> TOKEN PRESENT = %s",
sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" : "FALSE");
Syslog::notice(" -> REMOVABLE DEVICE = %s",
sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" : "FALSE");
Syslog::notice(" -> HW SLOT = %s",
sinfo.flags & CKF_HW_SLOT ? "TRUE" : "FALSE");
Syslog::notice(" hardwareVersion = %lu.%02lu",
sinfo.hardwareVersion.major, sinfo.hardwareVersion.minor);
Syslog::notice(" firmwareVersion = %lu.%02lu",
sinfo.firmwareVersion.major, sinfo.firmwareVersion.minor);
Syslog::notice(" See if token is present in reader");
if(!(sinfo.flags & CKF_TOKEN_PRESENT))
{
Syslog::notice(" Failed to connect to the token try again.");
usleep(100000);
continue;
}
Syslog::notice(" Token is really present!");
break;
}
if(sinfo.flags & CKF_TOKEN_PRESENT )
{
CK_TOKEN_INFO tinfo;
(void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
ck_rv = mEpv->C_GetTokenInfo(mSlots[i], &tinfo);
if( CKR_OK != ck_rv ) {
Syslog::debug("C_GetTokenInfo(%lu, ) returned 0x%08x", mSlots[i], ck_rv);
return result;
}
Syslog::notice(" Token Info:");
Syslog::notice(" label = \"%.32s\"", tinfo.label);
Syslog::notice(" manufacturerID = \"%.32s\"", tinfo.manufacturerID);
Syslog::notice(" model = \"%.16s\"", tinfo.model);
Syslog::notice(" serialNumber = \"%.16s\"", tinfo.serialNumber);
Syslog::notice(" flags = 0x%08lx", tinfo.flags);
/*
Syslog::notice(" -> RNG = %s",
tinfo.flags & CKF_RNG ? "TRUE" : "FALSE");
Syslog::notice(" -> WRITE PROTECTED = %s",
tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" : "FALSE");
Syslog::notice(" -> LOGIN REQUIRED = %s",
tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" : "FALSE");
Syslog::notice(" -> USER PIN INITIALIZED = %s",
tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" : "FALSE");
Syslog::notice(" -> RESTORE KEY NOT NEEDED = %s",
tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" : "FALSE");
Syslog::debug(" -> CLOCK ON TOKEN = %s",
tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" : "FALSE");
Syslog::notice( " ulMaxSessionCount = %lu", tinfo.ulMaxSessionCount);
Syslog::notice( " ulSessionCount = %lu", tinfo.ulSessionCount);
Syslog::notice( " ulMaxRwSessionCount = %lu", tinfo.ulMaxRwSessionCount);
Syslog::notice(" ulRwSessionCount = %lu", tinfo.ulRwSessionCount);
Syslog::notice( " ulMaxPinLen = %lu", tinfo.ulMaxPinLen);
Syslog::notice(" ulMinPinLen = %lu", tinfo.ulMinPinLen);
Syslog::notice(" ulTotalPublicMemory = %lu", tinfo.ulTotalPublicMemory);
Syslog::notice(" ulFreePublicMemory = %lu", tinfo.ulFreePublicMemory);
Syslog::notice(" ulTotalPrivateMemory = %lu", tinfo.ulTotalPrivateMemory);
Syslog::notice(" ulFreePrivateMemory = %lu", tinfo.ulFreePrivateMemory);
Syslog::notice(" hardwareVersion = %lu.%02lu",
(uint32)tinfo.hardwareVersion.major, (uint32)tinfo.hardwareVersion.minor);
Syslog::notice(" firmwareVersion = %lu.%02lu",
(uint32)tinfo.firmwareVersion.major, (uint32)tinfo.firmwareVersion.minor);
Syslog::notice(" utcTime = \"%.16s\"", tinfo.utcTime);
*/
Syslog::notice(" Token is present uid %s",tinfo.label);
int label_size = 32;
memcpy((void *) mTokenUid, (void *) tinfo.label,label_size);
mTokenUid[label_size -1] = 0;
}
else
{
Syslog::error(" Token not present in slot ");
return result;
}
}
}else
{
return result;
}
return 1;
}
//Actual crypto ops
int CoolKeyPK11::decryptData(CoolKeyObject *aObj,CK_BYTE *aEncData, CK_ULONG aEncDataLen, CK_BYTE *aData, CK_ULONG *aDataLen)
{
int result = 0;
if( !mEpv || !aObj || !aEncData || !aEncDataLen || !aData || !aDataLen
|| aDataLen <=0 || *aDataLen <= 0)
{
Syslog::error(" CoolKeyPK11::decryptData bad input data");
return result;
}
CK_OBJECT_HANDLE objHandle = aObj->getHandle();
CK_RV ck_rv = mEpv->C_DecryptInit(mSessHandle,NULL,objHandle);
Syslog::notice("decryptData C_DecryptInit Init result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("decryptData error calling C_DecryptInit");
return result;
}
ck_rv = mEpv->C_Decrypt(mSessHandle,aEncData,aEncDataLen,aData,aDataLen);
Syslog::notice("C_Decrypt result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("C_Decrypt result in error");
return 0;
}
Syslog::notice("decryptData return success");
return 1;
}
int CoolKeyPK11::generateSignature(CoolKeyObject *aObj,CK_BYTE *aData, CK_ULONG aDataLen, CK_BYTE *aSignature, CK_ULONG *aSignatureLen)
{
int result = 0;
if( !mEpv || !aObj || !aData || !aDataLen || !aSignature || !aSignatureLen
|| aDataLen <=0 || *aSignatureLen <= 0)
{
Syslog::error(" CoolKeyPK11::generateSignature bad input data");
return result;
}
CK_OBJECT_HANDLE objHandle = aObj->getHandle();
CK_RV ck_rv = mEpv->C_SignInit(mSessHandle,NULL,objHandle);
Syslog::notice("generateSignature C_SignInit result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("generatSignature error calling C_SignInit");
return result;
}
ck_rv = mEpv->C_Sign(mSessHandle,aData,aDataLen,aSignature,aSignatureLen);
Syslog::notice("C_Sign result %d", ck_rv);
if(ck_rv != CKR_OK)
{
Syslog::notice("C_Sign result in error");
return 0;
}
Syslog::notice("generateSignature return success");
return 1;
}
void CoolKeyObject::dumpData(CK_CHAR *aData, CK_ULONG aDataLen)
{
char line[256];
Syslog::notice("dumping data %p len %lu",aData,aDataLen);
CK_ULONG max = 8;
for(CK_ULONG i = 0 ; i < aDataLen; i ++)
{
if(i > max)
break;
sprintf(line," val[%lu]= %X",i,aData[i]);
Syslog::notice(line);
}
}
void CoolKeyObject::loadAttributes(CK_ATTRIBUTE *aTemplate,int aTemplateSize)
{
CK_RV ck_rv;
Syslog::notice("CoolKeyObject::loadAttributes with args template size %d",aTemplateSize);
if(!aTemplate || aTemplateSize <= 0 || mAttributesLoaded)
return;
CK_FUNCTION_LIST_PTR funcPtr = NULL;
if(mParent && (funcPtr = mParent->getFunctionPointer()))
{
Syslog::notice("CoolKeyObject::loadAttributes got function pointer");
ck_rv = funcPtr->C_GetAttributeValue(mSessHandle, mObjHandle, aTemplate, aTemplateSize);
switch(ck_rv)
{
case CKR_OK:
case CKR_ATTRIBUTE_SENSITIVE:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_BUFFER_TOO_SMALL:
break;
default:
Syslog::notice("CoolKeyObject::loadAttributes failed ck_rv %d",ck_rv);
return;
break;
};
for(int i = 0 ; i < aTemplateSize ; i++)
{
Syslog::notice("Object attribute: name % stype 0x%lx , size %d",
attributeName(aTemplate[i].type),aTemplate[i].type,
aTemplate[i].ulValueLen);
}
//Do it again to get actual data
for(int i = 0; i < aTemplateSize ; i++)
{
int size = (int)aTemplate[i].ulValueLen;
if(size && size != -1)
{
char *objData = new char [aTemplate[i].ulValueLen];
if(!objData)
{
continue;
}
aTemplate[i].pValue = objData;
}
}
//Now have the data alocated go get it.
ck_rv = funcPtr->C_GetAttributeValue(mSessHandle, mObjHandle, aTemplate, aTemplateSize);
switch(ck_rv)
{
case CKR_OK:
case CKR_ATTRIBUTE_SENSITIVE:
case CKR_ATTRIBUTE_TYPE_INVALID:
case CKR_BUFFER_TOO_SMALL:
break;
default:
Syslog::notice("CoolKeyObject::loadAttributes failed ck_rv %d",ck_rv);
return;
break;
};
//print out results of actually getting the data
for(int i = 0 ; i < aTemplateSize ; i++)
{
int size = aTemplate[i].ulValueLen;
char *data = (char *) aTemplate[i].pValue;
if(size && size != -1 && data)
{
Syslog::notice("Legitimate Object attribute saving.... Name: %s : type 0x%lx , size %d",
attributeName(aTemplate[i].type),aTemplate[i].type,
aTemplate[i].ulValueLen);
CK_ATTRIBUTE * newAttr = new CK_ATTRIBUTE ;
//Check for CAC data, we want to let the Apple CAC TokenD take care of these.
if(strstr(data,"CAC"))
{
Syslog::notice("CAC related item found, exiting... \n");
// exit(0);
}
if(!newAttr)
{
Syslog::notice("Can't allocate memory for new attribute");
continue;
}
newAttr->ulValueLen = aTemplate[i].ulValueLen;
newAttr->type = aTemplate[i].type;
newAttr->pValue = aTemplate[i].pValue;
CoolKeyObject::dumpData((CK_BYTE *)newAttr->pValue,newAttr->ulValueLen);
// put the attribute in our local map
aTemplate[i].ulValueLen = 0;
aTemplate[i].pValue = NULL;
mAttributes[newAttr->type] = newAttr;
}
}
}
}
void CoolKeyKeyObject::loadAttributes()
{
Syslog::notice("CoolKeyKeyObject::loadAttributes no args");
if(mAttributesLoaded)
return;
int templateSize = 0;
if(mObjClass == CKO_PRIVATE_KEY)
{
templateSize = sizeof(private_keyTemplate)/sizeof(CK_ATTRIBUTE);
CoolKeyObject::loadAttributes((CK_ATTRIBUTE *)private_keyTemplate,templateSize);
}
else
{
templateSize = sizeof(public_keyTemplate)/sizeof(CK_ATTRIBUTE);
CoolKeyObject::loadAttributes((CK_ATTRIBUTE *)public_keyTemplate, templateSize);
}
}
CK_BYTE CoolKeyKeyObject::getSensitive()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_SENSITIVE);
Syslog::notice("In CoolKeyObject::getID type %c",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyEncrypt()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_ENCRYPT);
Syslog::notice("In CoolKeyObject::getKeyEncrypt result %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyDecrypt()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_DECRYPT);
Syslog::notice("In CoolKeyObject::getKeyDecrypt type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeySign()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_SIGN);
Syslog::notice("In CoolKeyKeyObject::getKeySign type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyWrap()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_WRAP);
Syslog::notice("In CoolKeyKeyObject::getKeyWrap type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyVerify()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_VERIFY);
Syslog::notice("In CoolKeyKeyObject::getKeyVerify type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyDerive()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_DERIVE);
Syslog::notice("In CoolKeyKeyObject::getKeyDerive type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyUnwrap()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_UNWRAP);
Syslog::notice("In CoolKeyKeyObject::getKeyUnwrap type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeySignRecover()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_SIGN_RECOVER);
Syslog::notice("In CoolKeyKeyObject::getKeySignRecover type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyVerifyRecover()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_VERIFY_RECOVER);
Syslog::notice("In CoolKeyObject::getKeyKeyVerifyRecover type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyExtractable()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_EXTRACTABLE);
Syslog::notice("In CoolKeyKeyObject::getExtractable type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getKeyNeverExtractable()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_NEVER_EXTRACTABLE);
Syslog::notice("In CoolKeyKeyObject::getNeverExtractable type %d",result);
return result;
}
CK_BYTE CoolKeyKeyObject::getAlwaysSensitive()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_ALWAYS_SENSITIVE);
Syslog::notice("In CoolKeyKeyObject::getAlwaysSensitive type %d",result);
return result;
}
void CoolKeyKeyObject::getLabel(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_LABEL,aData,aDataLen);
Syslog::notice("In CoolKeyKeyObject::getLabel %s",aData);
}
CK_BYTE CoolKeyObject::getID()
{
CK_BYTE result = 0;
result = getByteAttribute(CKA_ID);
Syslog::notice("In CoolKeyObject::getID type %c",result);
return result;
}
void CoolKeyObject::freeAttributes()
{
Syslog::notice("CoolKeyObject::freeAttributes");
map< CK_ATTRIBUTE_TYPE, CK_ATTRIBUTE * >::iterator i;
CK_ATTRIBUTE *cur = NULL;
for(i = mAttributes.begin(); i!= mAttributes.end(); i++)
{
cur = (*i).second;
if(cur)
{
if(cur->pValue)
delete [] (char *) cur->pValue;
delete cur;
}
}
}
void CoolKeyObject::loadAttributes()
{
//Syslog::notice("CoolKeyObject::loadAttributes no args");
}
void CoolKeyCertObject::loadAttributes()
{
//Syslog::notice("In CoolKeyCertObject::loadAttributes no args");
if(mAttributesLoaded)
return;
int templateSize = sizeof(certTemplate)/sizeof(CK_ATTRIBUTE);
if(!templateSize)
return;
CoolKeyObject::loadAttributes(certTemplate,templateSize);
}
CoolKeyKeyObject::CoolKeyKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) : CoolKeyObject(aObjHandle,aSessHandle,aObjClass,aParent)
{
//Syslog::notice("CoolKeyKeyObject::CoolKeyKeyObject");
loadAttributes();
}
CK_ULONG CoolKeyKeyObject::getKeySize()
{
CK_ULONG size = 0;
CK_ATTRIBUTE *theMod = getAttribute(CKA_MODULUS);
if(theMod)
{
size = (theMod->ulValueLen - 1 ) * 8;
}
return size;
}
CoolKeyCertObject::CoolKeyCertObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) : CoolKeyObject(aObjHandle,aSessHandle,aObjClass,aParent)
{
loadAttributes();
}
void CoolKeyCertObject::getIssuer(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_ISSUER,aData,aDataLen);
}
void CoolKeyCertObject::getSerialNo(CK_BYTE *aData,CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_SERIAL_NUMBER,aData,aDataLen);
}
void CoolKeyCertObject::getLabel(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_LABEL,aData,aDataLen);
}
void CoolKeyCertObject::getPublicKeyHash(CK_BYTE *aData,CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
}
void CoolKeyCertObject::getData(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_VALUE,aData,aDataLen);
}
void CoolKeyCertObject::getSubject(CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen < 1)
return;
aData[0] = 0;
getByteDataAttribute(CKA_SUBJECT,aData,aDataLen);
}
CK_ULONG CoolKeyCertObject::getType()
{
CK_ULONG result = 0;
result = getULongAttribute(CKA_CERTIFICATE_TYPE);
Syslog::notice("In CoolKeyCertObject::getType type %lu",result);
return result;
}
CoolKeyObject::CoolKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) : mObjHandle(aObjHandle),mSessHandle(aSessHandle),mAttributesLoaded(0),mObjClass(aObjClass),mParent(aParent)
{
Syslog::notice("In CoolKeyObject::CoolKeyObject mObjClass %d",mObjClass);
}
CK_ATTRIBUTE * CoolKeyObject::getAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = mAttributes[aAttr];
return theAttr;
}
CK_LONG CoolKeyObject::getLongAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
if(!theAttr)
return 0;
CK_ULONG size = theAttr->ulValueLen ;
if(size != sizeof(CK_LONG))
return 0;
if(!theAttr->pValue)
return 0;
return (CK_LONG) *((CK_LONG *) theAttr->pValue);
}
CK_ULONG CoolKeyObject::getULongAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
Syslog::notice("In CoolKeyObject::getULongAttr attr %p size %d value %p",theAttr,theAttr->ulValueLen,theAttr->pValue);
if(!theAttr)
return 0;
CK_ULONG size = theAttr->ulValueLen ;
if(size != sizeof(CK_ULONG))
return 0;
if(!theAttr->pValue)
return 0;
return (CK_ULONG) *((CK_ULONG *) theAttr->pValue);
}
CK_BYTE CoolKeyObject::getByteAttribute(CK_ATTRIBUTE_TYPE aAttr)
{
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
if(!theAttr)
return 0;
CK_ULONG size = theAttr->ulValueLen ;
if(size != sizeof(CK_BYTE))
return 0;
if(!theAttr->pValue)
return 0;
return (CK_BYTE) *((CK_BYTE *) theAttr->pValue);
}
void CoolKeyObject::getByteDataAttribute(CK_ATTRIBUTE_TYPE aAttr,CK_BYTE *aData, CK_ULONG *aDataLen)
{
if(!aData || !aDataLen || *aDataLen <= 0 )
return;
CK_ATTRIBUTE *theAttr = getAttribute(aAttr);
Syslog::notice("In CoolKeyObject::getByteData attr %p attr size %d ",theAttr,theAttr->ulValueLen);
if(!theAttr)
return ;
CK_ULONG size = theAttr->ulValueLen ;
if(size < 1 || size >= *aDataLen)
return;
*aDataLen = 0;
aData[0] = 0;
if(!theAttr->pValue)
return;
memcpy( aData, theAttr->pValue,size);
*aDataLen = size;
}
char *CoolKeyObject::attributeName(uint32_t attributeId)
{
static char buffer[20];
switch (attributeId)
{
case CKA_CLASS: return "CLASS";
case CKA_TOKEN: return "TOKEN";
case CKA_PRIVATE: return "PRIVATE";
case CKA_LABEL: return "LABEL";
case CKA_APPLICATION: return "APPLICATION";
case CKA_VALUE: return "VALUE";
case CKA_OBJECT_ID: return "OBJECT_ID";
case CKA_CERTIFICATE_TYPE: return "CERTIFICATE_TYPE";
case CKA_ISSUER: return "ISSUER";
case CKA_SERIAL_NUMBER: return "SERIAL_NUMBER";
case CKA_AC_ISSUER: return "AC_ISSUER";
case CKA_OWNER: return "OWNER";
case CKA_ATTR_TYPES: return "ATTR_TYPES";
case CKA_TRUSTED: return "TRUSTED";
case CKA_KEY_TYPE: return "KEY_TYPE";
case CKA_SUBJECT: return "SUBJECT";
case CKA_ID: return "ID";
case CKA_SENSITIVE: return "SENSITIVE";
case CKA_ENCRYPT: return "ENCRYPT";
case CKA_DECRYPT: return "DECRYPT";
case CKA_WRAP: return "WRAP";
case CKA_WRAP_TEMPLATE: return "WRAP_TEMPLATE";
case CKA_UNWRAP: return "UNWRAP";
case CKA_SIGN: return "SIGN";
case CKA_SIGN_RECOVER: return "SIGN_RECOVER";
case CKA_VERIFY: return "VERIFY";
case CKA_VERIFY_RECOVER: return "VERIFY_RECOVER";
case CKA_DERIVE: return "DERIVE";
case CKA_START_DATE: return "START_DATE";
case CKA_END_DATE: return "END_DATE";
case CKA_MODULUS: return "MODULUS";
case CKA_MODULUS_BITS: return "MODULUS_BITS";
case CKA_PUBLIC_EXPONENT: return "PUBLIC_EXPONENT";
case CKA_PRIVATE_EXPONENT: return "PRIVATE_EXPONENT";
case CKA_PRIME_1: return "PRIME_1";
case CKA_PRIME_2: return "PRIME_2";
case CKA_EXPONENT_1: return "EXPONENT_1";
case CKA_EXPONENT_2: return "EXPONENT_2";
case CKA_COEFFICIENT: return "COEFFICIENT";
case CKA_PRIME: return "PRIME";
case CKA_SUBPRIME: return "SUBPRIME";
case CKA_BASE: return "BASE";
case CKA_PRIME_BITS: return "PRIME_BITS";
case CKA_SUB_PRIME_BITS: return "SUB_PRIME_BITS";
case CKA_VALUE_BITS: return "VALUE_BITS";
case CKA_VALUE_LEN: return "VALUE_LEN";
case CKA_EXTRACTABLE: return "EXTRACTABLE";
case CKA_LOCAL: return "LOCAL";
case CKA_NEVER_EXTRACTABLE: return "NEVER_EXTRACTABLE";
case CKA_ALWAYS_SENSITIVE: return "ALWAYS_SENSITIVE";
case CKA_KEY_GEN_MECHANISM: return "KEY_GEN_MECHANISM";
case CKA_MODIFIABLE: return "MODIFIABLE";
case CKA_EC_PARAMS: return "EC_PARAMS";
case CKA_EC_POINT: return "EC_POINT";
case CKA_SECONDARY_AUTH: return "SECONDARY_AUTH";
case CKA_AUTH_PIN_FLAGS: return "AUTH_PIN_FLAGS";
case CKA_HW_FEATURE_TYPE: return "HW_FEATURE_TYPE";
case CKA_RESET_ON_INIT: return "RESET_ON_INIT";
case CKA_HAS_RESET: return "HAS_RESET";
case CKA_VENDOR_DEFINED: return "VENDOR_DEFINED";
case CKA_ALWAYS_AUTHENTICATE: return "ALWAYS_AUTHENTICATE";
case CKA_WRAP_WITH_TRUSTED: return "WRAP_WITH_TRUSTED";
case CKA_UNWRAP_TEMPLATE: return "UNWRAP_TEMPLATE";
case CKA_HASH_OF_SUBJECT_PUBLIC_KEY: return "HASH_OF_SUBJECT_PUBLIC_KEY";
case CKA_HASH_OF_ISSUER_PUBLIC_KEY: return "HASH_OF_ISSUER_PUBLIC_KEY";
default:
snprintf(buffer, sizeof(buffer), "unknown(%0x08X)", attributeId);
return buffer;
}
}
--- NEW FILE CoolKeyPK11.h ---
/*
* CoolKeyPK11.h
* Tokend CoolKey
*/
#ifndef _COOLKEYPK11_H_
#define _COOLKEYPK11_H_
#include "mypkcs11.h"
//#include <Security/SecKey.h>
#include <map>
#include <string>
#define COOLKEY_MAX_SLOTS 20
#define PKCS11_PATH_NAME "/Library/Application Support/CoolKey/PKCS11/libcoolkeypk11.dylib"
class CoolKeyPK11;
class CoolKeyObject
{
public:
CoolKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent);
virtual ~CoolKeyObject() { freeAttributes();};
virtual void loadAttributes() ;
char *CoolKeyObject::attributeName(uint32_t attributeId);
CK_ATTRIBUTE * getAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_LONG getLongAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_ULONG getULongAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_BYTE getByteAttribute(CK_ATTRIBUTE_TYPE aAttr);
CK_BYTE getID();
void getByteDataAttribute(CK_ATTRIBUTE_TYPE aAttr,CK_BYTE *aData, CK_ULONG *aDataLen);
CK_OBJECT_CLASS getClass() {return mObjClass;}
static void dumpData(CK_BYTE *aData, CK_ULONG aDataLen);
CK_OBJECT_HANDLE getHandle() { return mObjHandle;}
CK_SESSION_HANDLE getSessHandle() { return mSessHandle; }
protected:
void loadAttributes(CK_ATTRIBUTE *aTemplate,int aTemplateSize);
void freeAttributes();
CK_OBJECT_HANDLE mObjHandle;
CK_SESSION_HANDLE mSessHandle;
int mAttributesLoaded;
CK_LONG mObjClass;
std::map< CK_ATTRIBUTE_TYPE, CK_ATTRIBUTE* > mAttributes;
private:
CoolKeyPK11 *mParent;
public:
};
class CoolKeyKeyObject : public CoolKeyObject
{
public:
CoolKeyKeyObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessionHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) ;
CK_ULONG getKeySize();
void getLabel(CK_BYTE *aData, CK_ULONG *aDataLen);
CK_BYTE getSensitive();
CK_BYTE getAlwaysSensitive();
CK_BYTE getKeyEncrypt();
CK_BYTE getKeyDecrypt();
CK_BYTE getKeySign();
CK_BYTE getKeyWrap();
CK_BYTE getKeyExtractable();
CK_BYTE getKeyNeverExtractable();
CK_BYTE getKeyVerify();
CK_BYTE getKeyDerive();
CK_BYTE getKeyUnwrap();
CK_BYTE getKeySignRecover();
CK_BYTE getKeyVerifyRecover();
void loadAttributes();
~CoolKeyKeyObject() {};
};
class CoolKeyCertObject : public CoolKeyObject
{
public:
CoolKeyCertObject(CK_OBJECT_HANDLE aObjHandle, CK_SESSION_HANDLE aSessionHandle,CK_LONG aObjClass,CoolKeyPK11 *aParent) ;
void loadAttributes();
void getSubject(CK_BYTE *aData, CK_ULONG *aDataLen);
void getIssuer(CK_BYTE *aData, CK_ULONG *aDataLen);
void getSerialNo(CK_BYTE *aData,CK_ULONG *aDataLen);
void getLabel(CK_BYTE *aData, CK_ULONG *aDataLen);
void getData(CK_BYTE *aData, CK_ULONG *aDataLen);
void getPublicKeyHash(CK_BYTE *aData,CK_ULONG *aDataLen);
CK_ULONG getType();
~CoolKeyCertObject() {};
};
class CoolKeyPK11
{
public:
typedef std::map< CK_OBJECT_HANDLE, CoolKeyObject * >::iterator ObjIterator;
CoolKeyPK11(): mPk11Driver(NULL),mEpv(NULL),mInitialized(0),mOurSlotIndex(0),mIsOurToken(0),mCachedPIN("") {} ;
virtual ~CoolKeyPK11() {};
int loadModule();
int freeModule();
int loginToken(char *aPIN);
void logoutToken();
int isTokenLoggedIn();
int loadObjects();
int freeObjects();
int getIsOurToken() { return mIsOurToken;}
char *getTokenId() {
if(mTokenUid[0] != 0)
return mTokenUid;
else
return NULL;
};
CK_FUNCTION_LIST_PTR getFunctionPointer() { return mEpv;}
int getInitialized() { return mInitialized; }
int verifyCachedPIN(char *aPIN);
//Actual cryto operations
int generateSignature(CoolKeyObject *aObj,CK_BYTE *aData, CK_ULONG aDataLen, CK_BYTE *aSignature, CK_ULONG *aSignatureLen);
int decryptData(CoolKeyObject *aObj,CK_BYTE *aEncData, CK_ULONG aEncDataLen, CK_BYTE *aData, CK_ULONG *aDataLen);
protected:
private:
int loadSlotList();
void * mPk11Driver;
CK_FUNCTION_LIST_PTR mEpv;
int mInitialized;
CK_SLOT_ID mSlots[COOLKEY_MAX_SLOTS];
int mOurSlotIndex;
CK_SLOT_INFO mOurSlotInfo;
char mTokenUid[32];
int mIsOurToken;
CK_SESSION_HANDLE mSessHandle;
std::map<CK_OBJECT_HANDLE , CoolKeyObject * > mObjects;
std::string mCachedPIN;
public:
ObjIterator begin() { return ObjIterator(mObjects.begin()); }
ObjIterator end() { return ObjIterator(mObjects.end()); }
};
#endif /* !_COOLKEYPK11_H_ */
--- NEW FILE CoolKeyRecord.cpp ---
/*
* Copyright (c) 2004 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 LicenseCoolKey
* 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@
*/
/*
* CoolKeyRecord.cpp
* Tokend CoolKey
*/
#include "CoolKeyPK11.h"
#include "CoolKeyRecord.h"
#include "CoolKeyError.h"
#include "CoolKeyToken.h"
//#include "Attribute.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include <security_cdsa_client/aclclient.h>
#include <Security/SecKey.h>
#include <security_utilities/logging.h>
//
// CoolKeyRecord
//
CoolKeyRecord::~CoolKeyRecord()
{
}
Tokend::Attribute *CoolKeyRecord::getDataAttribute(Tokend::TokenContext *tokenContext)
{
Syslog::notice("CoolKeyRecord::getDataAttribute");
CoolKeyObject *obj = (CoolKeyObject *) getCoolKeyObject();
CK_OBJECT_CLASS theClass = 0;
if(obj)
{
theClass = obj->getClass();
}
if(!obj)
return NULL;
CK_BYTE tData[2048];
CK_ULONG dataLen = 2048;
CoolKeyCertObject *theCert = NULL;
switch(theClass)
{
case CKO_CERTIFICATE:
Syslog::notice("getDataAttribute: Found certificate:-----------------");
theCert = (CoolKeyCertObject *) obj;
if(theCert)
{
theCert->getData((CK_BYTE *)tData,&dataLen);
}
return new Tokend::Attribute((const void *)tData,dataLen);
break;
case CKO_PUBLIC_KEY:
Syslog::notice("getDataAttribute:Found public key:----------------");
break;
case CKO_PRIVATE_KEY:
Syslog::notice("getDataAttribute:Found private key:-------------------");
break;
default:
Syslog::notice("getDataAttribute:Found something else:");
break;
};
return NULL;
}
void CoolKeyRecord::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
Allocator &alloc = Allocator::standard();
Syslog::notice("CoolKeyRecord::getAcl ----------------");
if (!mAclEntries) {
mAclEntries.allocator(alloc);
// Anyone can read the DB record for this key (which is a reference
// CSSM_KEY)
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
}
count = mAclEntries.size();
acls = mAclEntries.entries();
Syslog::notice("CoolKeyRecord::getAcl done");
}
/* arch-tag: 9703BFF8-0E73-11D9-ACDD-000A9595DEEE */
--- NEW FILE CoolKeyRecord.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* CoolKeyRecord.h
* TokendMuscle
*/
#ifndef _COOLKEYRECORD_H_
#define _COOLKEYRECORD_H_
#include "Record.h"
#include "CoolKeyPK11.h"
//class CoolKeyObject;
class CoolKeyRecord : public Tokend::Record
{
NOCOPY(CoolKeyRecord)
public:
CoolKeyRecord(CoolKeyObject *aObject) :
mObject(aObject) {}
virtual ~CoolKeyRecord();
CoolKeyObject *getCoolKeyObject() { return mObject; }
virtual Tokend::Attribute *getDataAttribute(Tokend::TokenContext *tokenContext);
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&aclList);
private:
AutoAclEntryInfoList mAclEntries;
protected:
CoolKeyObject *mObject;
};
#endif /* !_CACRECORD_H_ */
/* arch-tag: 96BC854C-0E73-11D9-B9B1-000A9595DEEE */
--- NEW FILE CoolKeySchema.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@
* CoolKey
* 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@
*/
/*
* CoolKeySchema.cpp
* Tokend CoolKey
*/
#include "CoolKeySchema.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include <Security/SecCertificate.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecKey.h>
#include <Security/SecKeychainItemPriv.h>
#include <security_utilities/logging.h>
#include <Security/cssmapple.h>
using namespace Tokend;
CoolKeySchema::CoolKeySchema()
{
}
CoolKeySchema::~CoolKeySchema()
{
}
Tokend::Relation *CoolKeySchema::createKeyRelation(CSSM_DB_RECORDTYPE keyType)
{
Relation *rn = createStandardRelation(keyType);
Syslog::info("createKeyRelation coder %p",&mCoolKeyKeyAttributeCoder);
// Set up coders for key records.
MetaRecord &mr = rn->metaRecord();
mr.keyHandleFactory(&mCoolKeyKeyHandleFactory);
mr.attributeCoder(kSecKeyPrintName, &mCoolKeyKeyAttributeCoder);
// Other key valuess
mr.attributeCoder(kSecKeyKeyType, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyKeySizeInBits, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyEffectiveKeySize, &mCoolKeyKeyAttributeCoder);
// Key attributes
mr.attributeCoder(kSecKeyExtractable, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeySensitive, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyModifiable, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyPrivate, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyNeverExtractable, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyAlwaysSensitive, &mCoolKeyKeyAttributeCoder);
// Key usage
mr.attributeCoder(kSecKeyEncrypt, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyDecrypt, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyWrap, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyUnwrap,&mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyVerify, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyDerive, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeySignRecover, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyVerifyRecover, &mCoolKeyKeyAttributeCoder);
mr.attributeCoder(kSecKeyLabel, &mPublicKeyHashCoder);
mr.attributeCoder(kSecKeySign, &mCoolKeyKeyAttributeCoder);
return rn;
}
Tokend::Relation *CoolKeySchema::createCertRelation(CSSM_DB_RECORDTYPE certType)
{
Relation *rn = createStandardRelation(certType);
// Set up coders for key records.
MetaRecord &mr = rn->metaRecord();
Syslog::info("createCertRelation coder %p",&mCoolKeyCertAttributeCoder);
// cert attributes
mr.attributeCoder(kSecAlias,&mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecSubjectItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecLabelItemAttr,&mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecIssuerItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecSerialNumberItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecPublicKeyHashItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecSubjectKeyIdentifierItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecCertTypeItemAttr, &mCoolKeyCertAttributeCoder);
mr.attributeCoder(kSecCertEncodingItemAttr, &mCoolKeyCertAttributeCoder);
return rn;
}
void CoolKeySchema::create()
{
Schema::create();
createStandardRelation(CSSM_DL_DB_RECORD_X509_CERTIFICATE);
createKeyRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY);
Relation *rn_publ = createKeyRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY);
// @@@ We need a coder that calculates the public key hash of a public key
rn_publ->metaRecord().attributeCoder(kSecKeyLabel, &mPublicKeyHashCoder);
}
/* arch-tag: 36BF1864-0DBC-11D9-8518-000A9595DEEE */
--- NEW FILE CoolKeySchema.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* CoolKeySchema.h
* TokendMuscle
*/
#ifndef _COOLKEYCHEMA_H_
#define _COOLKEYSCHEMA_H_
#include "Schema.h"
#include "CoolKeyAttributeCoder.h"
#include "CoolKeyHandle.h"
namespace Tokend
{
class Relation;
class MetaRecord;
class AttributeCoder;
}
class CoolKeySchema : public Tokend::Schema
{
NOCOPY(CoolKeySchema)
public:
CoolKeySchema();
virtual ~CoolKeySchema();
virtual void create();
protected:
Tokend::Relation *createKeyRelation(CSSM_DB_RECORDTYPE keyType);
Tokend::Relation *createCertRelation(CSSM_DB_RECORDTYPE certType);
private:
// Coders we need.
CoolKeyDataAttributeCoder mCoolKeyDataAttributeCoder;
CoolKeyCertAttributeCoder mCoolKeyCertAttributeCoder;
CoolKeyKeyAttributeCoder mCoolKeyKeyAttributeCoder;
CoolKeyKeyHandleFactory mCoolKeyKeyHandleFactory;
};
#endif /* !_CACSCHEMA_H_ */
/* arch-tag: 36DB400E-0DBC-11D9-A9F5-000A9595DEEE */
--- NEW FILE CoolKeyToken.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
* CoolKey
* @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@
*/
/*
* CoolKeyToken.cpp
* Tokend CoolKey
*/
#include "CoolKeyToken.h"
#include "Adornment.h"
#include "AttributeCoder.h"
#include "CoolKeyError.h"
#include "CoolKeyRecord.h"
#include "CoolKeySchema.h"
#include <security_cdsa_client/aclclient.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include <security_utilities/logging.h>
#include <security_utilities/refcount.h>
#include <map>
#include <vector>
#include <dlfcn.h>
#include <csignal>
using CssmClient::AclFactory;
static CoolKeyPK11 *coolKeyModule = NULL;
CoolKeyToken::CoolKeyToken() :
mCurrentApplet(NULL),
mPinStatus(1)
{
mTokenContext = this;
}
CoolKeyToken::~CoolKeyToken()
{
Syslog::notice("CoolKeyToken::~CoolKeyToken");
delete mSchema;
}
// Here is where we initialize our PKCS11 module
void CoolKeyToken::initial()
{
Syslog::notice("In CoolKeyToken::initial() . " );
}
bool CoolKeyToken::identify()
{
Syslog::notice("In CoolKeyToken::identify");
return true;
}
void CoolKeyToken::select(const unsigned char *applet)
{
Syslog::debug("In CoolKeyToken::select");
}
uint32_t CoolKeyToken::exchangeAPDU(const unsigned char *apdu, size_t apduLength,
unsigned char *result, size_t &resultLength)
{
return 0;
}
void CoolKeyToken::didDisconnect()
{
Syslog::debug("In CoolKeyToken::didDisconnect");
}
void CoolKeyToken::didEnd()
{
mCurrentApplet = NULL;
}
void CoolKeyToken::changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength)
{
Syslog::debug("In CoolKeyToken::changePIN");
}
uint32_t CoolKeyToken::pinStatus(int pinNum)
{
Syslog::notice("In CoolKeyToken::pinStatus num %d",pinNum);
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
bool CoolKeyToken::isLocked()
{
int result = mCoolKey.isTokenLoggedIn();
mPinStatus = 1 - result;
Syslog::notice("In CoolKeyToken::isLocked mPinStatus %d",mPinStatus);
return mPinStatus;
}
void CoolKeyToken::verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength)
{
Syslog::notice("In CoolKeyToken::verifyPIN");
int result = 0;
if(mCoolKey.isTokenLoggedIn())
{
result = mCoolKey.verifyCachedPIN((char *) pin);
}
else
{
result = mCoolKey.loginToken((char *) pin);
}
Syslog::notice("Result of loginToken %d",result);
if(result == CKR_OK)
return;
//logout because we failed
mCoolKey.logoutToken();
//any other error complain
CssmError::throwMe(CSSM_ERRCODE_OPERATION_AUTH_DENIED);
}
void CoolKeyToken::unverifyPIN(int pinNum)
{
Syslog::notice("In CoolKeyToken::unverifyPIN");
mPinStatus = 1;
}
uint32_t CoolKeyToken::getData(unsigned char *result, size_t &resultLength)
{
Syslog::notice("In CoolKeyToken::getData");
return NULL;
}
uint32 CoolKeyToken::probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID])
{
uint32 score = 0; //Tokend::ISO7816Token::probe(flags, tokenUid);
uint32 max_uid = TOKEND_MAX_UID;
const SCARD_READERSTATE &readerState = *(*startupReaderInfo)();
Syslog::notice("TOKEND_MAX_UID %d",max_uid);
Syslog::notice("READER_STATE -> szReader %s", (char *) readerState.szReader);
Syslog::notice ("READER_STATE -> dwCurrentState %u",readerState.dwCurrentState);
Syslog::notice ("READER_STATE -> dwEventState %u",readerState.dwEventState);
Syslog::notice ("READER_STATE -> cbAtr %u",readerState.cbAtr);
Syslog::notice("READER_STATE -> rgbAtr %32x",(char *) readerState.rgbAtr);
int res = mCoolKey.loadModule();
/* if(res)
res = mCoolKey.loadObjects();
*/
if(!res || ! mCoolKey.getIsOurToken())
{
Syslog::error(" Can't load CoolKey pkcs11 module. ");
return score;
}
if(coolKeyModule == NULL)
coolKeyModule = &mCoolKey;
char *tUid = mCoolKey.getTokenId();
if(tUid)
{
sprintf((char *) tokenUid,"%s",(char *)tUid);
Syslog::notice("tokenUid %s",(char *) tokenUid);
}
score = 299;
signal(SIGTERM, cleanup); // register a SIGTERM handler
return score;
}
void CoolKeyToken::establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
char *mCuid = mCoolKey.getTokenId();
int pathSize = PATH_MAX;
if(mCuid)
{
Syslog::notice("printName size %d", pathSize);
int predictedSize = strlen(mCuid);
if(predictedSize < pathSize)
{
sprintf((char *) printName, (char *) "%s",mCuid);
}
}
Syslog::notice("In CoolKeyToken::establish setting printName to: %s subserviceId: %d",printName,subserviceId);
int res = mCoolKey.loadObjects();
if(!res)
return;
mSchema = new CoolKeySchema();
mSchema->create();
populate();
}
//
// Authenticate to the token
//
void CoolKeyToken::authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred)
{
Syslog::notice("In CoolKeyToken::authenticate mode %d cred %p tag %s size %d",mode, cred,cred->tag(),cred->size());
if (cred) {
if(mode == CSSM_DB_ACCESS_RESET)
{
Syslog::notice("authenticate CSSM_DB_ACCESS_RESET");
return;
}
const TypedList &sample = (*cred)[0];
switch (sample.type()) {
case CSSM_SAMPLE_TYPE_PASSWORD:
case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD:
case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD:
{
Syslog::notice("sample type %d",sample.type());
CssmData &pin = sample[1].data();
verifyPIN(1, pin.Data,pin.Length);
}
break;
default:
Syslog::notice("sample type %ld not supported", sample.type());
CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
}
} else
Syslog::notice("authenticate without credentials ignored");
}
//
// Database-level ACLs
//
void CoolKeyToken::getOwner(AclOwnerPrototype &owner)
{
Syslog::notice("In CoolKeyToken::getOwner");
// we don't really know (right now), so claim we're owned by PIN #0
if (!mAclOwner)
{
mAclOwner.allocator(Allocator::standard());
mAclOwner = AclFactory::PinSubject(Allocator::standard(), 0);
}
owner = mAclOwner;
}
void CoolKeyToken::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
Syslog::notice("In CoolKeyToken::getAcl.");
Allocator &alloc = Allocator::standard();
// mAclEntries sets the handle of each AclEntryInfo to the
// offset in the array.
if (!mAclEntries) {
mAclEntries.allocator(alloc);
// Anyone can read the attributes and data of any record on this token
// (it's further limited by the object itself).
mAclEntries.add(CssmClient::AclFactory::AnySubject(
mAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
// We support PIN1 with either a passed in password
// subject or a prompted password subject.
mAclEntries.addPin(AclFactory::PWSubject(alloc),1);
mAclEntries.addPin(AclFactory::PromptPWSubject(alloc,CssmData()), 1);
}
count = mAclEntries.size();
acls = mAclEntries.entries();
}
#pragma mark ---------------- CoolKey Specific --------------
void CoolKeyToken::populate()
{
Syslog::notice("In CoolKeyToken::populate");
Tokend::Relation &certRelation = mSchema->findRelation(CSSM_DL_DB_RECORD_X509_CERTIFICATE);
Tokend::Relation &privateKeyRelation = mSchema->findRelation(CSSM_DL_DB_RECORD_PRIVATE_KEY);
Tokend::Relation &publicKeyRelation = mSchema->findRelation(CSSM_DL_DB_RECORD_PUBLIC_KEY);
std::map<int, CoolKeyObject *> certs;
std::map< CoolKeyObject *, RefPointer<CoolKeyRecord> > keys;
std::map< CoolKeyObject *, RefPointer<CoolKeyRecord> > certRecs;
for(CoolKeyPK11::ObjIterator i = mCoolKey.begin(); i != mCoolKey.end() ; i++)
{
CoolKeyObject *obj =(*i).second;
CK_OBJECT_CLASS oClass;
if(obj)
{
CK_BYTE id = obj->getID();
oClass = obj->getClass();
Syslog::notice("Retrieved object %p class %lu id %d",obj,oClass,id);
CoolKeyRecord *newRecord = new CoolKeyRecord(obj);
RefPointer<CoolKeyRecord> theRecord( newRecord);
if(!theRecord)
continue;
switch(oClass)
{
case CKO_PRIVATE_KEY:
privateKeyRelation.insertRecord(theRecord);
Syslog::notice("Inserting private key record %p",newRecord);
keys[obj] = theRecord;
break;
case CKO_PUBLIC_KEY:
Syslog::notice("Inserting public key record %p theRefRecord %p",newRecord,theRecord.get());
publicKeyRelation.insertRecord(theRecord);
keys[obj] = theRecord;
break;
case CKO_CERTIFICATE:
certs[id] = obj;
certRecs[obj] = theRecord;
Syslog::notice("Inserting cert record %p",newRecord);
certRelation.insertRecord(theRecord);
break;
default:
break;
};
}
}
for(CoolKeyPK11::ObjIterator i = mCoolKey.begin(); i != mCoolKey.end() ; i++)
{
CoolKeyObject *obj =(*i).second;
CoolKeyObject *cert = NULL;
CK_OBJECT_CLASS oClass;
if(obj)
{
CK_BYTE id = obj->getID();
oClass = obj->getClass();
switch(oClass)
{
case CKO_PRIVATE_KEY:
case CKO_PUBLIC_KEY:
cert = certs[id];
if(cert)
{
RefPointer<CoolKeyRecord> coolKeyRecRef = keys[obj];
CoolKeyRecord * coolKeyRec = coolKeyRecRef.get();
Syslog::notice("Key %p linked to cert %p",obj,cert);
if(coolKeyRec)
{
Syslog::notice("Found record to create adornment record: %p",coolKeyRec);
if(certRecs[cert])
{
Tokend::LinkedRecordAdornment * lra = new Tokend::LinkedRecordAdornment(certRecs[cert]);
Syslog::notice("lra %p",lra);
if(lra)
{
coolKeyRec->setAdornment(mSchema->publicKeyHashCoder().certificateKey(),
lra);
Syslog::notice("certificateKey %p certRecs[cert] %p",mSchema->publicKeyHashCoder().certificateKey(),certRecs[cert].get());
}
}
}
}
else
Syslog::notice("Key %p not linked to found cert");
break;
default:
break;
};
}
}
}
void CoolKeyToken::cleanup(int aSig)
{
Syslog::notice("We are going away!");
if(coolKeyModule)
{
coolKeyModule->logoutToken();
coolKeyModule->freeModule();
}
}
/* arch-tag: 36F733B4-0DBC-11D9-914C-000A9595DEEE */
--- NEW FILE CoolKeyToken.h ---
/*
* Copyright (c) 2004 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 filCoolKeye 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@
*/
/*
* CoolKeyToken.h
* Tokend CoolKey
*/
#ifndef _COOLKEY_TOKEN_H_
#define _COOLKEY_TOKEN_H_
#include "mypkcs11.h"
#include <Token.h>
#include "TokenContext.h"
#include "CoolKeyPK11.h"
#include <security_utilities/pcsc++.h>
class CoolKeySchema;
#define PKCS11_PATH_NAME "/Library/Application Support/CoolKey/PKCS11/libcoolkeypk11.dylib"
#define COOLKEY_PRESENT_SCORE 10000000
//
// "The" token
//
class CoolKeyToken : public Tokend::ISO7816Token
{
NOCOPY(CoolKeyToken)
public:
CoolKeyToken() ;
~CoolKeyToken();
virtual void didDisconnect();
virtual void didEnd();
virtual void initial();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]);
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls);
virtual void changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength);
virtual uint32_t pinStatus(int pinNum);
virtual void verifyPIN(int pinNum, const unsigned char *pin, size_t pinLength);
virtual void unverifyPIN(int pinNum);
virtual void authenticate(CSSM_DB_ACCESS_TYPE mode, const AccessCredentials *cred);
virtual bool isLocked();
bool identify();
void select(const unsigned char *applet);
uint32_t exchangeAPDU(const unsigned char *apdu, size_t apduLength,
unsigned char *result, size_t &resultLength);
uint32_t getData(unsigned char *result, size_t &resultLength);
CoolKeyPK11 &getPK11Manager() { return mCoolKey; }
protected:
void populate();
CoolKeyPK11 mCoolKey;
public:
const unsigned char *mCurrentApplet;
uint32_t mPinStatus;
// temporary ACL cache hack - to be removed
AutoAclOwnerPrototype mAclOwner;
AutoAclEntryInfoList mAclEntries;
private:
static void cleanup(int aSig);
};
#endif /* !_CACTOKEN_H_ */
/* arch-tag: 3714259E-0DBC-11D9-8D58-000A9595DEEE */
--- NEW FILE Info.plist ---
<?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>COOLKEY</string>
<key>CFBundleIdentifier</key>
<string>com.apple.tokend.coolkey</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>COOLKEY</string>
<key>CFBundlePackageType</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.1.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>30557</string>
</dict>
</plist>
--- NEW FILE coolkey.cpp ---
/*
* Copyright (c) 2004 Apple Computer, Inc. All Rights Reserved.
*
* @APPLE_LICENSE_HEADER_START@CoolKey
*
* 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@
*/
/*
* CoolKey.cpp - CoolKey.tokend main program
*/
#include "CoolKeyToken.h"
#include <security_utilities/logging.h>
int main(int argc, const char *argv[])
{
secdebug("CoolKey.tokend", "main starting with %d arguments", argc);
secdelay("/tmp/delay/CoolKey");
Syslog::notice("argc %d",argc);
for(int i = 0; i < argc ; i++)
{
Syslog::notice("coolkey arg[%d]: %s",i,argv[i]);
}
token = new CoolKeyToken();
return SecTokendMain(argc, argv, token->callbacks(), token->support());
Syslog::notice("CoolKey.tokend exiting.... ");
}
/* arch-tag: 372EB7FE-0DBC-11D9-9A28-000A9595DEEE */
--- NEW FILE dlfcn.h ---
/*
* Copyright (c) 2004-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@
*/
/*
Based on the dlcompat work done by:
Jorge Acereda <jacereda(a)users.sourceforge.net> &
Peter O'Gorman <ogorman(a)users.sourceforge.net>
*/
#ifndef _DLFCN_H_
#define _DLFCN_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/cdefs.h>
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#include <stdbool.h>
#include <AvailabilityMacros.h>
/*
* Structure filled in by dladdr().
*/
typedef struct dl_info {
const char *dli_fname; /* Pathname of shared object */
void *dli_fbase; /* Base address of shared object */
const char *dli_sname; /* Name of nearest symbol */
void *dli_saddr; /* Address of nearest symbol */
} Dl_info;
extern int dladdr(const void *, Dl_info *);
#endif /* not POSIX */
extern int dlclose(void * __handle);
extern char * dlerror(void);
extern void * dlopen(const char * __path, int __mode);
extern void * dlsym(void * __handle, const char * __symbol);
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
extern bool dlopen_preflight(const char* __path) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER;
#endif /* not POSIX */
#define RTLD_LAZY 0x1
#define RTLD_NOW 0x2
#define RTLD_LOCAL 0x4
#define RTLD_GLOBAL 0x8
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
#define RTLD_NOLOAD 0x10
#define RTLD_NODELETE 0x80
#define RTLD_FIRST 0x100 /* Mac OS X 10.5 and later */
/*
* Special handle arguments for dlsym().
*/
#define RTLD_NEXT ((void *) -1) /* Search subsequent objects. */
#define RTLD_DEFAULT ((void *) -2) /* Use default search algorithm. */
#define RTLD_SELF ((void *) -3) /* Search this and subsequent objects (Mac OS X 10.5 and later) */
#endif /* not POSIX */
#ifdef __cplusplus
}
#endif
#endif /* _DLFCN_H_ */
14 years
esc/mac/Tokend-35209 APPLE_LICENSE, NONE, 1.1.2.2 testcms.sh, NONE, 1.1.2.2 testssl.sh, NONE, 1.1.2.2
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv18528
Added Files:
Tag: PKI_8_0_RTM_BRANCH
APPLE_LICENSE testcms.sh testssl.sh
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE APPLE_LICENSE ---
APPLE PUBLIC SOURCE LICENSE
Version 2.0 - August 6, 2003
Please read this License carefully before downloading this software.
By downloading or 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") makes publicly available 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 2.0 ("License"). As used in
this License:
1.1 "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.2 "Contributor" means any person or entity that creates or
contributes to the creation of Modifications.
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 "Externally Deploy" means: (a) to sublicense, distribute or
otherwise make Covered Code available, directly or indirectly, to
anyone other than You; and/or (b) to use Covered Code, alone or as
part of a Larger Work, in any way to provide a service, including but
not limited to delivery of content, through electronic communication
with a client other than You.
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 the Original Code, any previous
Modifications, the combination of Original Code and any previous
Modifications, and/or any respective portions thereof. 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 Unmodified Code. You may use, reproduce, display, perform,
internally distribute within Your organization, and Externally Deploy
verbatim, unmodified copies of the Original Code, for commercial or
non-commercial purposes, provided that in each instance:
(a) You must 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; and
(b) You must include a copy of this License with every copy of Source
Code of Covered Code and documentation You distribute or Externally
Deploy, 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.
2.2 Modified Code. You may modify Covered Code and use, reproduce,
display, perform, internally distribute within Your organization, and
Externally Deploy Your Modifications and Covered Code, for commercial
or non-commercial purposes, provided that in each instance You also
meet all of these conditions:
(a) You must satisfy all the conditions of Section 2.1 with respect to
the Source Code of the Covered Code;
(b) You must duplicate, to the extent it does not already exist, the
notice in Exhibit A in each file of the Source Code of all Your
Modifications, and cause the modified files to carry prominent notices
stating that You changed the files and the date of any change; and
(c) If You Externally Deploy Your Modifications, You must make
Source Code of all Your Externally Deployed Modifications either
available to those to whom You have Externally Deployed Your
Modifications, or publicly available. Source Code of Your Externally
Deployed Modifications must be released under the terms set forth in
this License, including the license grants set forth in Section 3
below, for as long as you Externally Deploy the Covered Code or twelve
(12) months from the date of initial External Deployment, whichever is
longer. You should preferably distribute the Source Code of Your
Externally Deployed Modifications electronically (e.g. download from a
web site).
2.3 Distribution of Executable Versions. In addition, if You
Externally Deploy Covered Code (Original Code and/or Modifications) in
object code, executable form only, You must 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.
2.4 Third Party Rights. You expressly acknowledge and agree that
although Apple and each Contributor grants the licenses to their
respective portions of the Covered Code set forth herein, no
assurances are provided by Apple or any Contributor that the Covered
Code does not infringe the patent or other intellectual property
rights of any other entity. Apple and each Contributor disclaim any
liability to You for claims brought by any other entity based on
infringement of intellectual property rights or otherwise. As a
condition to exercising the rights and licenses granted hereunder, You
hereby assume sole responsibility to secure any other intellectual
property rights needed, if any. For example, if a third party patent
license is required to allow You to distribute the Covered Code, it is
Your responsibility to acquire that license before distributing the
Covered Code.
3. Your Grants. In consideration of, and as a condition to, the
licenses granted to You under this License, You hereby grant to any
person or entity receiving or distributing Covered Code under this
License a non-exclusive, royalty-free, perpetual, irrevocable license,
under Your Applicable Patent Rights and other intellectual property
rights (other than patent) owned or controlled by You, to use,
reproduce, display, perform, modify, sublicense, distribute and
Externally Deploy Your Modifications of the same scope and extent as
Apple's licenses under Sections 2.1 and 2.2 above.
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 or any Contributor. 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 and every Contributor harmless for any liability
incurred by or claims asserted against Apple or such Contributor 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 Covered Code may contain in whole or in
part pre-release, untested, or not fully tested works. The Covered
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 Covered Code, or any portion thereof, is at
Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND
WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND
APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE
PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM
ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF
MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR
PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD
PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST
INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE
FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS,
THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR
ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO
ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE
AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY.
You acknowledge that the Covered 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 Covered Code could lead to death, personal injury, or severe
physical or environmental damage.
9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO
EVENT SHALL APPLE OR ANY CONTRIBUTOR 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 COVERED CODE, OR
ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY,
TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF
APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY
REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF
INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY
TO YOU. In no event shall Apple's total liability to You for all
damages (other than as may be required by applicable law) 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", "Mac OS",
"QuickTime", "QuickTime Streaming Server" or any other trademarks,
service marks, logos or trade names belonging to Apple (collectively
"Apple Marks") or to any trademark, service mark, logo or trade name
belonging to any Contributor. You agree not to use any Apple Marks in
or as part of the name of products derived from the Original Code or
to endorse or promote products derived from the Original Code other
than as expressly 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. Subject to the licenses granted under this License,
each Contributor retains all rights, title and interest in and to any
Modifications made by such Contributor. 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.
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; provided that Apple did not first commence
an action for patent infringement against You in that instance.
12.2 Effect of Termination. Upon termination, You agree to immediately
stop any further use, reproduction, modification, sublicensing and
distribution of the Covered Code. 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. No party will be liable to any 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
any 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 or among You, Apple or any Contributor, 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 or any Contributor 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-2003 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 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."
--- NEW FILE testcms.sh ---
#!/bin/sh
# usage: point LOCAL_BUILD_DIR to your build folder, insert a card
# and run this script
echo $PATH | fgrep -q "${LOCAL_BUILD_DIR}:" || PATH=${LOCAL_BUILD_DIR}:$PATH
SECURITY=`which security`
HOME=/tmp/test$$
export HOME
mkdir $HOME
cd $HOME
mkdir Library
mkdir Library/Preferences
mkdir Library/Keychains
echo Creating a login.keychain
$SECURITY create -p login login.keychain
echo "listing keychains"
$SECURITY list-keychains
echo "listing default keychain"
$SECURITY default-keychain
echo "Looking for the email address of the first certificate on the card"
if [ "x$EMAIL" == "x" ]; then
EMAIL=`$SECURITY find-certificate | awk -F = '/\"alis\"<blob>/ { addr=$2; gsub(/\"/, "", addr); print addr }'`
if [ "x$EMAIL" == "x" ]; then
echo "No certificate with an email address found."
exit 1
fi
fi
echo "Email addres found: <$EMAIL>"
echo "CONTENT: The secret and possibly signed content." > content.txt
echo "Creating a signed cms message."
$SECURITY cms -S -N "$EMAIL" -i content.txt -o signed.cms
echo "Verifying the signed cms message."
$SECURITY cms -D -i signed.cms -h0
echo "Creating an encrypted cms message."
$SECURITY cms -E -r "$EMAIL" -i content.txt -o encrypted.cms
echo "Decrypting the message."
$SECURITY cms -D -i encrypted.cms
#echo "Exporting the identity to pkcs12."
#$SECURITY export -f pkcs12 -t identities -p -P testcms -o identity.p12
# arch-tag: D00EE88A-08E5-11D9-B1C3-000A9595DEEE
--- NEW FILE testssl.sh ---
#!/bin/sh
SECURITY=${SECURITY:=security}
EMAIL=${EMAIL:=$USER@apple.com}
SSLVIEW=${SSLVIEW:=sslViewer}
SERVER=${SERVER:=hurljo3.apple.com}
HOME=/tmp/test$$
mkdir $HOME
cd $HOME
mkdir Library
mkdir Library/Preferences
mkdir Library/Keychains
echo Creating a login.keychain
$SECURITY create -p login login.keychain
echo "listing keychains"
$SECURITY list-keychains
echo "listing default keychain"
$SECURITY default-keychain
echo "CONTENT: The secret and possibly signed content." > content.txt
echo "Connecting to SSL Test server " $SERVER
$SSLVIEW $SERVER r c P=4443 V 3 a
# arch-tag: 51571215-09B6-11D9-8D4F-000A95C4302E
14 years
esc/mac/Tokend-35209/Tokend Adornment.cpp, NONE, 1.1 Adornment.h, NONE, 1.1 Attribute.cpp, NONE, 1.1 Attribute.h, NONE, 1.1 AttributeCoder.cpp, NONE, 1.1 AttributeCoder.h, NONE, 1.1 Cursor.cpp, NONE, 1.1 Cursor.h, NONE, 1.1 DbValue.cpp, NONE, 1.1 DbValue.h, NONE, 1.1 KeyHandle.cpp, NONE, 1.1 KeyHandle.h, NONE, 1.1 MetaAttribute.cpp, NONE, 1.1 MetaAttribute.h, NONE, 1.1 MetaRecord.cpp, NONE, 1.1 MetaRecord.h, NONE, 1.1 PKCS11Object.cpp, NONE, 1.1 PKCS11Object.h, NONE, 1.1 Record.cpp, NONE, 1.1
by Jack Magne
Author: jmagne
Update of /cvs/dirsec/esc/mac/Tokend-35209/Tokend
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv16499/Tokend
Added Files:
Adornment.cpp Adornment.h Attribute.cpp Attribute.h
AttributeCoder.cpp AttributeCoder.h Cursor.cpp Cursor.h
DbValue.cpp DbValue.h KeyHandle.cpp KeyHandle.h
MetaAttribute.cpp MetaAttribute.h MetaRecord.cpp MetaRecord.h
PKCS11Object.cpp PKCS11Object.h Record.cpp Record.h
RecordHandle.cpp RecordHandle.h Relation.cpp Relation.h
SCardError.cpp SCardError.h Schema.cpp Schema.h
SelectionPredicate.cpp SelectionPredicate.h Token.cpp Token.h
TokenContext.cpp TokenContext.h
Log Message:
Add directory for Tokend-35209 for Leopard.
--- NEW FILE Adornment.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Adornment.cpp
* TokendMuscle
*/
#include "Adornment.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Record.h"
namespace Tokend
{
//
// LinkedRecordAdornment
//
//const Adornment::Key LinkedRecordAdornment::key = "LinkedRecordAdornment";
LinkedRecordAdornment::LinkedRecordAdornment(RefPointer<Record> record) :
mRecord(record)
{
}
LinkedRecordAdornment::~LinkedRecordAdornment()
{
}
Record &LinkedRecordAdornment::record()
{
return *mRecord;
}
//
// SecCertificateAdornment
//
SecCertificateAdornment::SecCertificateAdornment(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
// Get the data for record (the actual certificate).
const MetaAttribute &dma =
metaAttribute.metaRecord().metaAttributeForData();
const Attribute &data = dma.attribute(tokenContext, record);
// Data should have exactly one value.
if (data.size() != 1)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
// Create a new adornment using the data from the certificate.
OSStatus status = SecCertificateCreateFromData(&data[0], CSSM_CERT_X_509v3,
CSSM_CERT_ENCODING_BER, &mCertificate);
if (status)
MacOSError::throwMe(status);
}
SecCertificateAdornment::~SecCertificateAdornment()
{
CFRelease(mCertificate);
}
SecCertificateRef SecCertificateAdornment::certificate()
{
return mCertificate;
}
SecKeychainItemRef SecCertificateAdornment::certificateItem()
{
return SecKeychainItemRef(mCertificate);
}
} // end namespace Tokend
--- NEW FILE Adornment.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Adornment.h
* TokendMuscle
*/
#ifndef _TOKEND_ADORNMENT_H_
#define _TOKEND_ADORNMENT_H_
#include <security_utilities/adornments.h>
#include <security_utilities/refcount.h>
#include <Security/SecCertificate.h>
namespace Tokend
{
class TokenContext;
class MetaRecord;
class MetaAttribute;
class Record;
//
// Adornment that refers to another record
//
class LinkedRecordAdornment : public Adornment
{
NOCOPY(LinkedRecordAdornment)
public:
LinkedRecordAdornment(RefPointer<Record> record);
~LinkedRecordAdornment();
Record &record();
private:
RefPointer<Record> mRecord;
};
class SecCertificateAdornment : public Adornment
{
NOCOPY(SecCertificateAdornment)
public:
SecCertificateAdornment(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
~SecCertificateAdornment();
SecCertificateRef certificate();
SecKeychainItemRef certificateItem();
private:
SecCertificateRef mCertificate;
};
} // end namespace Tokend
#endif /* !_TOKEND_ADORNMENT_H_ */
--- NEW FILE Attribute.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Attribute.cpp
* TokendMuscle
*/
#include "Attribute.h"
namespace Tokend
{
Attribute::Attribute()
{
mCount = 0;
mValues = NULL;
}
Attribute::Attribute(const Attribute &attribute)
{
set(attribute.mValues, attribute.mCount);
}
Attribute::Attribute(bool value)
{
uint32 v = value ? 1 : 0;
set(&v, sizeof(v));
}
Attribute::Attribute(sint32 value)
{
set(&value, sizeof(value));
}
Attribute::Attribute(uint32 value)
{
set(&value, sizeof(value));
}
Attribute::Attribute(const char *value)
{
set(value, strlen(value));
}
Attribute::Attribute(const std::string &value)
{
set(value.c_str(), value.size());
}
Attribute::Attribute(const void *data, uint32 length)
{
set(data, length);
}
Attribute::Attribute(const CSSM_DATA *datas, uint32 count)
{
set(datas, count);
}
Attribute::~Attribute()
{
if (mValues)
free(mValues);
}
Attribute &Attribute::operator = (const Attribute &attribute)
{
if (mValues)
free(mValues);
set(attribute.mValues, attribute.mCount);
return *this;
}
void Attribute::set(const CSSM_DATA *datas, uint32 count)
{
mCount = count;
uint32 size = count * sizeof(CSSM_DATA);
for (uint32 ix = 0; ix < count; ++ix)
size += datas[ix].Length;
uint8 *buffer = (uint8 *)malloc(size);
mValues = CSSM_DATA_PTR(buffer);
buffer += sizeof(CSSM_DATA) * count;
for (uint32 ix = 0; ix < count; ++ix)
{
uint32 length = datas[ix].Length;
mValues[ix].Data = buffer;
mValues[ix].Length = length;
memcpy(mValues[ix].Data, datas[ix].Data, length);
buffer += length;
}
}
void Attribute::set(const void *data, uint32 length)
{
mCount = 1;
uint8 *buffer = (uint8 *)malloc(sizeof(CSSM_DATA) + length);
mValues = CSSM_DATA_PTR(buffer);
mValues[0].Data = buffer + sizeof(CSSM_DATA);
mValues[0].Length = length;
memcpy(mValues[0].Data, data, length);
}
void Attribute::getDateValue(CSSM_DATE &date) const
{
if (mCount == 0 || mValues[0].Length == 0)
{
memset(&date, 0, sizeof(date));
}
else if (mCount == 1 && mValues[0].Length == sizeof(date))
{
memcpy(&date, mValues[0].Data, sizeof(date));
}
else
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
uint32 Attribute::uint32Value() const
{
if (mCount != 1 || mValues[0].Length != 4)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
return *reinterpret_cast<uint32 *>(mValues[0].Data);
}
} // end namespace Tokend
--- NEW FILE Attribute.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Attribute.h
* TokendMuscle
*/
#ifndef _TOKEND_ATTRIBUTE_H_
#define _TOKEND_ATTRIBUTE_H_
#include <Security/cssmtype.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <string>
namespace Tokend
{
class Attribute
{
public:
Attribute();
Attribute(const Attribute &attribute);
Attribute(bool value);
Attribute(sint32 value);
Attribute(uint32 value);
Attribute(const char *value);
Attribute(const std::string &value);
Attribute(const void *data, uint32 length);
Attribute(const CSSM_DATA *datas, uint32 count);
~Attribute();
Attribute &operator = (const Attribute &attribute);
uint32 size() const { return mCount; }
const CSSM_DATA &operator [](uint32 ix) const { return mValues[ix]; }
const CSSM_DATA *values() const { return mValues; }
void getDateValue(CSSM_DATE &date) const;
uint32 uint32Value() const;
bool boolValue() const { return uint32Value() != 0; }
private:
void set(const CSSM_DATA *datas, uint32 count);
void set(const void *data, uint32 length);
uint32 mCount;
CSSM_DATA_PTR mValues;
};
} // end namespace Tokend
#endif /* !_TOKEND_ATTRIBUTE_H_ */
--- NEW FILE AttributeCoder.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* AttributeCoder.cpp
* TokendMuscle
*/
#include "AttributeCoder.h"
#include "Attribute.h"
#include "Adornment.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Record.h"
#include <security_cdsa_utilities/cssmerrors.h>
#include <security_cdsa_utilities/cssmkey.h>
#include <Security/cssmerr.h>
#include <Security/SecKey.h>
#include <Security/SecCertificate.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecKeychainItemPriv.h>
namespace Tokend
{
//
// AttributeCoder
//
AttributeCoder::~AttributeCoder() {}
//
// CertificateAttributeCoder
//
CertificateAttributeCoder::~CertificateAttributeCoder() {}
void CertificateAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute,
Record &record)
{
// Get the SecCertificateAdornment off record using a pointer to ourself as
// the key
SecCertificateAdornment &sca =
record.adornment<SecCertificateAdornment>(this, tokenContext,
metaAttribute, record);
// Get the keychain item for the certificate from the record's adornment.
SecKeychainItemRef certificate = sca.certificateItem();
// Read the attribute with the requested attributeId from the item.
SecKeychainAttribute ska = { metaAttribute.attributeId() };
SecKeychainAttributeList skal = { 1, &ska };
OSStatus status = SecKeychainItemCopyContent(certificate, NULL, &skal,
NULL, NULL);
if (status)
MacOSError::throwMe(status);
// Add the retrieved attribute as an attribute to the record.
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(ska.data, ska.length));
// Free the retrieved attribute.
status = SecKeychainItemFreeContent(&skal, NULL);
if (status)
MacOSError::throwMe(status);
// @@@ The code above only returns one email address. Fix this.
}
//
// ConstAttributeCoder
//
ConstAttributeCoder::ConstAttributeCoder(uint32 value) : mValue(value) {}
ConstAttributeCoder::ConstAttributeCoder(bool value) : mValue(value ? 1 : 0) {}
ConstAttributeCoder::~ConstAttributeCoder() {}
void ConstAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(mValue));
}
//
// GuidAttributeCoder
//
GuidAttributeCoder::GuidAttributeCoder(const CSSM_GUID &guid) : mGuid(guid) {}
GuidAttributeCoder::~GuidAttributeCoder() {}
void GuidAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(&mGuid, sizeof(CSSM_GUID)));
}
//
// NullAttributeCoder
//
NullAttributeCoder::~NullAttributeCoder() {}
void NullAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(), new Attribute());
}
//
// ZeroAttributeCoder
//
ZeroAttributeCoder::~ZeroAttributeCoder() {}
void ZeroAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(reinterpret_cast<const void *>(NULL), 0));
}
//
// KeyDataAttributeCoder
//
KeyDataAttributeCoder::~KeyDataAttributeCoder() {}
void KeyDataAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
const MetaRecord &mr = metaAttribute.metaRecord();
CssmKey key;
key.header().cspGuid(Guid::overlay(gGuidAppleSdCSPDL));
key.blobType(CSSM_KEYBLOB_REFERENCE);
key.blobFormat(CSSM_KEYBLOB_REF_FORMAT_INTEGER);
key.algorithm(mr.metaAttribute(kSecKeyKeyType)
.attribute(tokenContext, record).uint32Value());
key.keyClass(mr.metaAttribute(kSecKeyKeyClass)
.attribute(tokenContext, record).uint32Value());
key.header().LogicalKeySizeInBits =
mr.metaAttribute(kSecKeyKeySizeInBits).attribute(tokenContext, record)
.uint32Value();
key.header().KeyAttr =
(mr.metaAttribute(kSecKeyPermanent).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_PERMANENT : 0)
| (mr.metaAttribute(kSecKeyPrivate).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_PRIVATE : 0)
| (mr.metaAttribute(kSecKeyModifiable).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_MODIFIABLE : 0)
| (mr.metaAttribute(kSecKeySensitive).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_SENSITIVE : 0)
| (mr.metaAttribute(kSecKeyAlwaysSensitive)
.attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_ALWAYS_SENSITIVE : 0)
| (mr.metaAttribute(kSecKeyExtractable).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_EXTRACTABLE : 0)
| (mr.metaAttribute(kSecKeyNeverExtractable)
.attribute(tokenContext, record)
.boolValue() ? CSSM_KEYATTR_NEVER_EXTRACTABLE : 0);
CSSM_KEYUSE usage =
(mr.metaAttribute(kSecKeyEncrypt).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_ENCRYPT : 0)
| (mr.metaAttribute(kSecKeyDecrypt).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_DECRYPT : 0)
| (mr.metaAttribute(kSecKeySign).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_SIGN : 0)
| (mr.metaAttribute(kSecKeyVerify).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_VERIFY : 0)
| (mr.metaAttribute(kSecKeySignRecover).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_SIGN_RECOVER : 0)
| (mr.metaAttribute(kSecKeyVerifyRecover)
.attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_VERIFY_RECOVER : 0)
| (mr.metaAttribute(kSecKeyWrap).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_WRAP : 0)
| (mr.metaAttribute(kSecKeyUnwrap).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_UNWRAP : 0)
| (mr.metaAttribute(kSecKeyDerive).attribute(tokenContext, record)
.boolValue() ? CSSM_KEYUSE_DERIVE : 0);
if (usage == (CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN
| CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_SIGN_RECOVER
| CSSM_KEYUSE_VERIFY_RECOVER | CSSM_KEYUSE_WRAP | CSSM_KEYUSE_UNWRAP
| CSSM_KEYUSE_DERIVE))
usage = CSSM_KEYUSE_ANY;
key.header().KeyUsage = usage;
// Dates
mr.metaAttribute(kSecKeyStartDate).attribute(tokenContext, record)
.getDateValue(key.header().StartDate);
mr.metaAttribute(kSecKeyEndDate).attribute(tokenContext, record)
.getDateValue(key.header().EndDate);
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(&key, sizeof(key)));
}
//
// LinkedRecordAttributeCoder
//
LinkedRecordAttributeCoder::~LinkedRecordAttributeCoder() {}
void LinkedRecordAttributeCoder::decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute,
Tokend::Record &record)
{
const Tokend::MetaAttribute *lma = NULL;
LinkedRecordAdornment *lra = NULL;
if (mCertificateMetaAttribute)
{
lma = mCertificateMetaAttribute;
lra = record.getAdornment<LinkedRecordAdornment>(certificateKey());
}
if (!lra && mPublicKeyMetaAttribute)
{
lma = mPublicKeyMetaAttribute;
lra = record.getAdornment<LinkedRecordAdornment>(publicKeyKey());
}
if (!lma || !lra)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
// Get the linked record's attribute and set it on record.
const Attribute &attribute = lma->attribute(tokenContext, lra->record());
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(attribute));
}
//
// DecriptionAttributeCoder
//
DescriptionAttributeCoder::~DescriptionAttributeCoder()
{
}
void DescriptionAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
new Attribute(record.description()));
}
//
// DataAttributeCoder
//
DataAttributeCoder::~DataAttributeCoder()
{
}
void DataAttributeCoder::decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record)
{
record.attributeAtIndex(metaAttribute.attributeIndex(),
record.getDataAttribute(tokenContext));
}
} // end namespace Tokend
--- NEW FILE AttributeCoder.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* AttributeCoder.h
* TokendMuscle
*/
#ifndef _TOKEND_ATTRIBUTECODER_H_
#define _TOKEND_ATTRIBUTECODER_H_
#include <security_utilities/utilities.h>
#include <Security/cssmtype.h>
namespace Tokend
{
class MetaAttribute;
class Record;
class TokenContext;
class AttributeCoder
{
NOCOPY(AttributeCoder)
public:
AttributeCoder() {}
virtual ~AttributeCoder() = 0;
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record) = 0;
};
//
// A coder that derives certificate attributes for the certificate data
//
class CertificateAttributeCoder : public AttributeCoder
{
NOCOPY(CertificateAttributeCoder)
public:
CertificateAttributeCoder() {}
virtual ~CertificateAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
private:
};
//
// A coder with a constant value
//
class ConstAttributeCoder : public AttributeCoder
{
NOCOPY(ConstAttributeCoder)
public:
ConstAttributeCoder(uint32 value);
ConstAttributeCoder(bool value);
virtual ~ConstAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
private:
uint32 mValue;
};
//
// A coder whose value is a guid.
//
class GuidAttributeCoder : public AttributeCoder
{
NOCOPY(GuidAttributeCoder)
public:
GuidAttributeCoder(const CSSM_GUID &guid);
virtual ~GuidAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
private:
const CSSM_GUID mGuid;
};
//
// A coder whose value contains 0 values.
//
class NullAttributeCoder : public AttributeCoder
{
NOCOPY(NullAttributeCoder)
public:
NullAttributeCoder() {}
virtual ~NullAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A coder whose value contains 1 zero length value.
//
class ZeroAttributeCoder : public AttributeCoder
{
NOCOPY(ZeroAttributeCoder)
public:
ZeroAttributeCoder() {}
virtual ~ZeroAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A data coder for key relations
//
class KeyDataAttributeCoder : public AttributeCoder
{
NOCOPY(KeyDataAttributeCoder)
public:
KeyDataAttributeCoder() {}
virtual ~KeyDataAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A coder for private key objects value is the public key hash of a
// certificate. Generic get an attribute of a linked record coder.
//
class LinkedRecordAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(LinkedRecordAttributeCoder)
public:
LinkedRecordAttributeCoder() {}
virtual ~LinkedRecordAttributeCoder();
const void *certificateKey() const { return mCertificateMetaAttribute; }
const void *publicKeyKey() const { return mPublicKeyMetaAttribute; }
void setCertificateMetaAttribute(
const Tokend::MetaAttribute *linkedRecordMetaAttribute)
{ mCertificateMetaAttribute = linkedRecordMetaAttribute; }
void setPublicKeyMetaAttribute(
const Tokend::MetaAttribute *linkedRecordMetaAttribute)
{ mPublicKeyMetaAttribute = linkedRecordMetaAttribute; }
virtual void decode(Tokend::TokenContext *tokenContext,
const Tokend::MetaAttribute &metaAttribute,
Tokend::Record &record);
private:
const Tokend::MetaAttribute *mCertificateMetaAttribute;
const Tokend::MetaAttribute *mPublicKeyMetaAttribute;
};
//
// A coder that reads the description of an object
//
class DescriptionAttributeCoder : public AttributeCoder
{
NOCOPY(DescriptionAttributeCoder)
public:
DescriptionAttributeCoder() {}
virtual ~DescriptionAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
//
// A coder that reads the data of an object
//
class DataAttributeCoder : public Tokend::AttributeCoder
{
NOCOPY(DataAttributeCoder)
public:
DataAttributeCoder() {}
virtual ~DataAttributeCoder();
virtual void decode(TokenContext *tokenContext,
const MetaAttribute &metaAttribute, Record &record);
};
} // end namespace Tokend
#endif /* !_TOKEND_ATTRIBUTECODER_H_ */
--- NEW FILE Cursor.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Cursor.cpp
* TokendMuscle
*/
#include "Cursor.h"
#include "MetaRecord.h"
#include "Record.h"
#include "RecordHandle.h"
#include "Relation.h"
#include "Token.h"
#include "SelectionPredicate.h"
namespace Tokend
{
#pragma mark ---------------- Cursor methods --------------
//
// Cursor implemetation
//
Cursor::Cursor()
{
}
Cursor::~Cursor()
{
}
//
// LinearCursor implemetation
//
LinearCursor::LinearCursor(const CSSM_QUERY *inQuery,
const Relation &inRelation) :
mIterator(inRelation.begin()),
mEnd(inRelation.end()),
mMetaRecord(inRelation.metaRecord())
{
mConjunctive = inQuery->Conjunctive;
mQueryFlags = inQuery->QueryFlags;
// @@@ Do something with inQuery->QueryLimits?
uint32 aPredicatesCount = inQuery->NumSelectionPredicates;
mPredicates.resize(aPredicatesCount);
try
{
for (uint32 anIndex = 0; anIndex < aPredicatesCount; anIndex++)
{
CSSM_SELECTION_PREDICATE &aPredicate =
inQuery->SelectionPredicate[anIndex];
mPredicates[anIndex] =
new SelectionPredicate(mMetaRecord, aPredicate);
}
}
catch (...)
{
for_each_delete(mPredicates.begin(), mPredicates.end());
throw;
}
}
LinearCursor::~LinearCursor()
{
for_each_delete(mPredicates.begin(), mPredicates.end());
}
RecordHandle *LinearCursor::next(TokenContext *tokenContext)
{
while (mIterator != mEnd)
{
RefPointer<Record> rec = *mIterator;
++mIterator;
PredicateVector::const_iterator anIt = mPredicates.begin();
PredicateVector::const_iterator anEnd = mPredicates.end();
bool aMatch;
if (anIt == anEnd) // If there are no predicates we have a match.
aMatch = true;
else if (mConjunctive == CSSM_DB_OR)
{
// If mConjunctive is OR, the first predicate that returns
// true indicates a match. Dropthough means no match
aMatch = false;
for (; anIt != anEnd; anIt++)
{
if ((*anIt)->evaluate(tokenContext, *rec))
{
aMatch = true;
break;
}
}
}
else if (mConjunctive == CSSM_DB_AND || mConjunctive == CSSM_DB_NONE)
{
// If mConjunctive is AND (or NONE), the first predicate that
// returns false indicates a mismatch. Dropthough means a match.
aMatch = true;
for (; anIt != anEnd; anIt++)
{
if (!(*anIt)->evaluate(tokenContext, *rec))
{
aMatch = false;
break;
}
}
}
else
{
CssmError::throwMe(CSSMERR_DL_INVALID_QUERY);
}
if (aMatch)
return new RecordHandle(mMetaRecord, rec);
}
return NULL;
}
#pragma mark ---------------- MultiCursor methods --------------
MultiCursor::MultiCursor(const CSSM_QUERY *inQuery, const Schema &inSchema) :
mRelationIterator(inSchema.begin()),
mRelationEnd(inSchema.end())
{
if (inQuery)
mQuery.reset(new CssmAutoQuery(*inQuery));
else
{
mQuery.reset(new CssmAutoQuery());
mQuery->recordType(CSSM_DL_DB_RECORD_ANY);
}
}
MultiCursor::~MultiCursor()
{
}
RecordHandle *MultiCursor::next(TokenContext *tokenContext)
{
RecordHandle *result = NULL;
for (;;)
{
if (!mCursor.get())
{
if (mRelationIterator == mRelationEnd)
return NULL;
const Relation &aRelation = *(mRelationIterator->second);
++mRelationIterator;
if (!aRelation.matchesId(mQuery->recordType()))
continue;
mCursor.reset(new LinearCursor(mQuery.get(), aRelation));
}
if ((result = mCursor->next(tokenContext)))
return result;
mCursor.reset(NULL);
}
}
} // end namespace Tokend
--- NEW FILE Cursor.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Cursor.h
* TokendMuscle
*/
#ifndef _TOKEND_CURSOR_H_
#define _TOKEND_CURSOR_H_
#include "Relation.h"
#include "Schema.h"
#include <security_cdsa_utilities/handleobject.h>
#include <vector>
namespace Tokend
{
class MetaRecord;
class RecordHandle;
class Relation;
class SelectionPredicate;
class Cursor : public HandleObject
{
NOCOPY(Cursor)
public:
Cursor();
virtual ~Cursor() = 0;
virtual RecordHandle *next(TokenContext *tokenContext) = 0;
};
class LinearCursor : public Cursor
{
NOCOPY(LinearCursor)
public:
LinearCursor(const CSSM_QUERY *inQuery, const Relation &inRelation);
virtual ~LinearCursor();
virtual RecordHandle *next(TokenContext *tokenContext);
private:
Relation::const_iterator mIterator;
Relation::const_iterator mEnd;
const MetaRecord &mMetaRecord;
CSSM_DB_CONJUNCTIVE mConjunctive;
// If CSSM_QUERY_RETURN_DATA is set return the raw key bits
CSSM_QUERY_FLAGS mQueryFlags;
typedef vector<SelectionPredicate *> PredicateVector;
PredicateVector mPredicates;
};
class MultiCursor : public Cursor
{
NOCOPY(MultiCursor)
public:
MultiCursor(const CSSM_QUERY *inQuery, const Schema &inSchema);
virtual ~MultiCursor();
virtual RecordHandle *next(TokenContext *tokenContext);
private:
Schema::ConstRelationMapIterator mRelationIterator;
Schema::ConstRelationMapIterator mRelationEnd;
auto_ptr<CssmAutoQuery> mQuery;
auto_ptr<Cursor> mCursor;
};
} // end namespace Tokend
#endif /* !_TOKEND_CURSOR_H_ */
--- NEW FILE DbValue.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* DbValue.cpp
* TokendMuscle
*/
#include "DbValue.h"
#include <ctype.h>
// @@@ missing "pack" methods with WriteSection parameter
namespace Tokend
{
//
// DbValue
//
DbValue::DbValue()
{
}
DbValue::~DbValue()
{
}
UInt32Value::UInt32Value(const CSSM_DATA &data)
{
switch (data.Length)
{
case 1: mValue = *reinterpret_cast<uint8 *>(data.Data); break;
case 2: mValue = *reinterpret_cast<uint16 *>(data.Data); break;
case 4: mValue = *reinterpret_cast<uint32 *>(data.Data); break;
default:
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
}
UInt32Value::~UInt32Value()
{
}
//
// SInt32Value
//
SInt32Value::SInt32Value(const CSSM_DATA &data)
{
switch (data.Length)
{
case 1: mValue = *reinterpret_cast<sint8 *>(data.Data); break;
case 2: mValue = *reinterpret_cast<sint16 *>(data.Data); break;
case 4: mValue = *reinterpret_cast<sint32 *>(data.Data); break;
default:
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
}
SInt32Value::~SInt32Value()
{
}
//
// DoubleValue
//
DoubleValue::DoubleValue(const CSSM_DATA &data)
{
switch (data.Length)
{
case 4: mValue = *reinterpret_cast<float *>(data.Data); break;
case 8: mValue = *reinterpret_cast<double *>(data.Data); break;
default:
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
}
DoubleValue::~DoubleValue()
{
}
//
// BlobValue
//
BlobValue::BlobValue(const CSSM_DATA &data) : CssmData(CssmData::overlay(data))
{
}
BlobValue::~BlobValue()
{
}
BlobValue::Comparator::~Comparator()
{
}
int
BlobValue::Comparator::operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length)
{
return memcmp(ptr1, ptr2, length);
}
bool
BlobValue::evaluate(const BlobValue &other, CSSM_DB_OPERATOR op) const
{
return evaluate(*this, other, op, Comparator());
}
bool
BlobValue::evaluate(const CssmData &inData1, const CssmData &inData2,
CSSM_DB_OPERATOR op, Comparator compare)
{
uint32 length1 = inData1.Length, length2 = inData2.Length;
const uint8 *data1 = inData1.Data;
const uint8 *data2 = inData2.Data;
switch (op) {
case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
if (length1 > length2)
return false;
length2 = length1;
goto DB_EQUAL;
case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
if (length1 > length2)
return false;
data2 += (length2 - length1);
length2 = length1;
// dropthrough...
case CSSM_DB_EQUAL:
DB_EQUAL:
if (length1 != length2)
return false;
if (length1 == 0)
return true;
return compare(data1, data2, length1) == 0;
case CSSM_DB_NOT_EQUAL:
if (length1 != length2)
return true;
if (length1 == 0)
return false;
return compare(data1, data2, length1) != 0;
case CSSM_DB_LESS_THAN:
case CSSM_DB_GREATER_THAN:
{
uint32 length = min(length1, length2);
int result = (length == 0) ? 0 : compare(data1, data2, length);
if (result < 0 || (result == 0 && length1 < length2))
return op == CSSM_DB_LESS_THAN;
else if (result > 0 || (result == 0 && length1 > length2))
return op == CSSM_DB_GREATER_THAN;
break;
}
case CSSM_DB_CONTAINS:
if (length1 > length2)
return false;
if (length1 == 0)
return true;
// Both buffers are at least 1 byte long.
for (const uint8 *data = data2; data + length1 <= data2 + length2;
++data)
if (compare(data1, data, length1) == 0)
return true;
break;
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
return false;
}
//
// TimeDateValue
//
TimeDateValue::TimeDateValue(const CSSM_DATA &data)
: BlobValue(data)
{
if (Length != kTimeDateSize || !isValidDate())
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
}
TimeDateValue::~TimeDateValue()
{
}
bool
TimeDateValue::isValidDate() const
{
if (Length != kTimeDateSize || Data[kTimeDateSize - 1] != 0 ||
Data[kTimeDateSize - 2] != 'Z')
return false;
for (uint32 i = 0; i < kTimeDateSize - 2; i++)
if (!isdigit(Data[i]))
return false;
uint32 month = rangeValue(4, 2);
if (month < 1 || month > 12)
return false;
uint32 day = rangeValue(6, 2);
if (day < 1 || day > 31)
return false;
uint32 hour = rangeValue(8, 2);
if (hour < 0 || hour > 23)
return false;
uint32 minute = rangeValue(10, 2);
if (minute < 0 || minute > 59)
return false;
uint32 second = rangeValue(12, 2);
if (second < 0 || second > 59)
return false;
return true;
}
uint32
TimeDateValue::rangeValue(uint32 start, uint32 length) const
{
uint32 value = 0;
for (uint32 i = 0; i < length; i++)
value = value * 10 + Data[start + i] - '0';
return value;
}
//
// StringValue
//
StringValue::StringValue(const CSSM_DATA &data)
: BlobValue(data)
{
}
StringValue::~StringValue()
{
}
int
StringValue::Comparator::operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length)
{
return strncmp(reinterpret_cast<const char *>(ptr1),
reinterpret_cast<const char *>(ptr2), length);
}
bool
StringValue::evaluate(const StringValue &other, CSSM_DB_OPERATOR op) const
{
return BlobValue::evaluate(*this, other, op, StringValue::Comparator());
}
//
// BigNumValue
//
BigNumValue::BigNumValue(const CSSM_DATA &data)
: BlobValue(data)
{
// remove trailing zero bytes
while (Length > 1 && Data[Length - 1] == 0)
Length--;
// if the number is zero (positive or negative), make the length zero
if (Length == 1 && (Data[0] & ~kSignBit) == 0)
Length = 0;
}
BigNumValue::~BigNumValue()
{
}
// Walk the contents of two equal-sized bignums, moving backward
// from the high-order bytes, and return the comparison result
// ala memcmp.
int
BigNumValue::compare(const uint8 *a, const uint8 *b, int length)
{
for (int diff, i = length - 1; i >= 1; i--)
if ((diff = a[i] - b[i]))
return diff;
// for the last (i.e. first) byte, mask out the sign bit
return (a[0] & ~kSignBit) - (b[0] & ~kSignBit);
}
// Compare two bignums, assuming they are in canonical form (i.e.,
// no bytes containing trailing zeros.
bool
BigNumValue::evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const
{
uint32 length1 = Length, length2 = other.Length;
uint8 sign1 = length1 ? (Data[0] & kSignBit) : 0;
uint8 sign2 = length2 ? (other.Data[0] & kSignBit) : 0;
switch (op)
{
case CSSM_DB_EQUAL:
case CSSM_DB_NOT_EQUAL:
return BlobValue::evaluate(other, op);
case CSSM_DB_LESS_THAN:
if (sign1 ^ sign2)
// different signs: return true iff left value is the negative one
return sign1;
else if (length1 != length2)
// in canonical form, shorter numbers have smaller absolute value
return sign1 ? (length1 > length2) : (length1 < length2);
else {
// same length, same sign...
int c = compare(Data, other.Data, length1);
return sign1 ? (c > 0) : (c < 0);
}
break;
case CSSM_DB_GREATER_THAN:
if (sign1 ^ sign2)
return sign2;
else if (length1 != length2)
return sign1 ? (length1 < length2) : (length1 > length2);
else {
int c = compare(Data, other.Data, length1);
return sign1 ? (c < 0) : (c > 0);
}
break;
case CSSM_DB_CONTAINS:
case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
}
//
// MultiUInt32Value
//
MultiUInt32Value::MultiUInt32Value(const CSSM_DATA &data)
{
if (data.Length & (sizeof(uint32) - 1))
CssmError::throwMe(CSSMERR_DL_INVALID_VALUE);
mNumValues = data.Length / sizeof(uint32);
mValues = reinterpret_cast<uint32 *>(data.Data);
mOwnsValues = false;
}
MultiUInt32Value::~MultiUInt32Value()
{
if (mOwnsValues)
delete [] mValues;
}
static inline int
uint32cmp(const uint32 *a, const uint32 *b, uint32 length)
{
return memcmp(a, b, length * sizeof(uint32));
}
bool
MultiUInt32Value::evaluate(const MultiUInt32Value &other,
CSSM_DB_OPERATOR op) const
{
uint32 length1 = mNumValues, length2 = other.mNumValues;
const uint32 *values1 = mValues;
const uint32 *values2 = other.mValues;
switch (op)
{
case CSSM_DB_EQUAL:
if (length1 == length2)
return uint32cmp(values1, values2, length1) == 0;
break;
case CSSM_DB_NOT_EQUAL:
if (length1 != length2 || uint32cmp(values1, values2, length1))
return true;
break;
case CSSM_DB_CONTAINS_INITIAL_SUBSTRING:
if (length1 <= length2)
return uint32cmp(values1, values2, length1) == 0;
break;
case CSSM_DB_CONTAINS_FINAL_SUBSTRING:
if (length1 <= length2)
return uint32cmp(values1, values2 + (length2 - length1), length1)
== 0;
break;
case CSSM_DB_CONTAINS:
if (length1 <= length2) {
if (length1 == 0)
return true;
for (const uint32 *values = values2;
values + length1 < values2 + length2; values++)
if (uint32cmp(values1, values, length1) == 0)
return true;
}
break;
case CSSM_DB_LESS_THAN:
// this is not required by the spec, but is required to sort indexes
// over multi uint32 keys...
if (length1 < length2)
return true;
else if (length1 == length2)
return uint32cmp(values1, values2, length1) < 0;
break;
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
return false;
}
} // end namespace Tokend
--- NEW FILE DbValue.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* DbValue.h
* TokendMuscle
*/
#ifndef _TOKEND_DBVALUE_H_
#define _TOKEND_DBVALUE_H_
#include <security_cdsa_utilities/cssmdata.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <Security/cssmerr.h>
#include <map>
#include <vector>
namespace Tokend
{
//
// DbValue -- A base class for all types of database values.
//
class DbValue
{
NOCOPY(DbValue)
public:
DbValue();
virtual ~DbValue() = 0;
};
// A collection of subclasses of DbValue that work for simple
// data types, e.g. uint32, sint32, and double, that have
// the usual C comparison and sizeof operations. Defining this
// template saves typing below.
template <class T>
class BasicValue : public DbValue
{
NOCOPY(BasicValue)
public:
BasicValue() {}
BasicValue(T value) : mValue(value) {}
bool evaluate(const BasicValue<T> &other, CSSM_DB_OPERATOR op) const
{
switch (op)
{
case CSSM_DB_EQUAL: return mValue == other.mValue;
case CSSM_DB_NOT_EQUAL: return mValue != other.mValue;
case CSSM_DB_LESS_THAN: return mValue < other.mValue;
case CSSM_DB_GREATER_THAN: return mValue > other.mValue;
default: CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
}
}
size_t size() const { return sizeof(T); }
const uint8 *bytes() const
{ return reinterpret_cast<const uint8 *>(&mValue); }
protected:
T mValue;
};
// Actual useful subclasses of DbValue as instances of BasicValue.
// Note that all of these require a constructor of the form
// (const ReadSection &, uint32 &offset) that advances the offset
// to just after the value.
class UInt32Value : public BasicValue<uint32>
{
NOCOPY(UInt32Value)
public:
UInt32Value(const CSSM_DATA &data);
virtual ~UInt32Value();
};
class SInt32Value : public BasicValue<sint32>
{
NOCOPY(SInt32Value)
public:
SInt32Value(const CSSM_DATA &data);
virtual ~SInt32Value();
};
class DoubleValue : public BasicValue<double>
{
NOCOPY(DoubleValue)
public:
DoubleValue(const CSSM_DATA &data);
virtual ~DoubleValue();
};
// Subclasses of Value for more complex types.
class BlobValue : public DbValue, public CssmData
{
NOCOPY(BlobValue)
public:
BlobValue() {}
BlobValue(const CSSM_DATA &data);
virtual ~BlobValue();
bool evaluate(const BlobValue &other, CSSM_DB_OPERATOR op) const;
size_t size() const { return Length; }
const uint8 *bytes() const { return Data; }
protected:
class Comparator {
public:
virtual ~Comparator();
virtual int operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length);
};
static bool evaluate(const CssmData &data1, const CssmData &data2,
CSSM_DB_OPERATOR op, Comparator compare);
};
class TimeDateValue : public BlobValue
{
NOCOPY(TimeDateValue)
public:
enum { kTimeDateSize = 16 };
TimeDateValue(const CSSM_DATA &data);
virtual ~TimeDateValue();
bool isValidDate() const;
private:
uint32 rangeValue(uint32 start, uint32 length) const;
};
class StringValue : public BlobValue
{
NOCOPY(StringValue)
public:
StringValue(const CSSM_DATA &data);
virtual ~StringValue();
bool evaluate(const StringValue &other, CSSM_DB_OPERATOR op) const;
private:
class Comparator : public BlobValue::Comparator {
public:
virtual int operator ()(const uint8 *ptr1, const uint8 *ptr2,
uint32 length);
};
};
class BigNumValue : public BlobValue
{
NOCOPY(BigNumValue)
public:
static const uint8 kSignBit = 0x80;
BigNumValue(const CSSM_DATA &data);
virtual ~BigNumValue();
bool evaluate(const BigNumValue &other, CSSM_DB_OPERATOR op) const;
private:
static int compare(const uint8 *a, const uint8 *b, int length);
};
class MultiUInt32Value : public DbValue
{
NOCOPY(MultiUInt32Value)
public:
MultiUInt32Value(const CSSM_DATA &data);
virtual ~MultiUInt32Value();
bool evaluate(const MultiUInt32Value &other, CSSM_DB_OPERATOR op) const;
size_t size() const { return mNumValues * sizeof(uint32); }
const uint8 *bytes() const { return reinterpret_cast<uint8 *>(mValues); }
private:
uint32 mNumValues;
uint32 *mValues;
bool mOwnsValues;
};
} // end namespace Tokend
#endif /* !_TOKEND_DBVALUE_H_ */
--- NEW FILE KeyHandle.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* KeyHandle.cpp
* TokendMuscle
*/
#include "KeyHandle.h"
namespace Tokend
{
//
// KeyHandle
//
KeyHandle::KeyHandle(const MetaRecord &metaRecord,
const RefPointer<Record> &record) :
RecordHandle(metaRecord, record)
{
}
KeyHandle::~KeyHandle()
{
}
void KeyHandle::wrapUsingKey(const Context &context,
const AccessCredentials *cred, KeyHandle *wrappingKeyHandle,
const CssmKey *wrappingKey, const CssmData *descriptiveData,
CssmKey &wrappedKey)
{
/* We are being asked to wrap this key using another key. */
secdebug("crypto", "wrapKey alg: %u", context.algorithm());
IFDUMPING("crypto", context.dump("wrapKey context"));
if (wrappingKeyHandle)
{
secdebug("tokend",
"wrapKey of a reference key using a reference key not supported");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
/* First export the key from the card. */
exportKey(context, cred, wrappedKey);
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void KeyHandle::wrapKey(const Context &context, const CssmKey &subjectKey,
const CssmData *descriptiveData, CssmKey &wrappedKey)
{
/* We are being asked to wrap a raw subject key using a key on the card. */
secdebug("tokend", "wrapKey of a raw subject key not supported");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void KeyHandle::unwrapKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *access,
const CssmKey &wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CssmData *descriptiveData,
CSSM_HANDLE &hUnwrappedKey, CssmKey &unwrappedKey)
{
secdebug("crypto", "unwrapKey alg: %u", context.algorithm());
IFDUMPING("crypto", context.dump("unwrapKey context"));
#if 0
/* Make sure our key type matches the context type */
if (keyClass() == CSSM_KEYCLASS_SESSION_KEY)
{
if (context.type() != CSSM_ALGCLASS_SYMMETRIC))
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
}
else
#endif
if (context.type() != CSSM_ALGCLASS_ASYMMETRIC)
CssmError::throwMe(CSSMERR_CSP_INVALID_CONTEXT);
/* validate wrappedKey */
if (wrappedKey.keyClass() != CSSM_KEYCLASS_SESSION_KEY)
CssmError::throwMe(CSSMERR_CSP_INVALID_KEY_CLASS);
if(wrappedKey.blobType() != CSSM_KEYBLOB_WRAPPED)
CssmError::throwMe(CSSMERR_CSP_KEY_BLOB_TYPE_INCORRECT);
/* validate requested storage and usage */
if (!(attributes & CSSM_KEYATTR_RETURN_DATA)
|| (attributes & (CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE
| CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_PRIVATE)) != 0)
CssmError::throwMe(CSSMERR_CSP_INVALID_KEYATTR_MASK);
/* prepare outgoing header */
CssmKey::Header &hdr = unwrappedKey.header();
hdr.clearPod();
hdr.HeaderVersion = CSSM_KEYHEADER_VERSION;
hdr.cspGuid(gGuidAppleSdCSPDL);
hdr.blobType(CSSM_KEYBLOB_RAW);
hdr.algorithm(wrappedKey.algorithm());
hdr.keyClass(wrappedKey.keyClass());
hdr.KeyUsage = usage;
hdr.KeyAttr = attributes & ~(CSSM_KEYATTR_RETURN_DATA
| CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_RETURN_NONE);
// defaults (change as needed)
hdr.StartDate = wrappedKey.header().StartDate;
hdr.EndDate = wrappedKey.header().EndDate;
unwrappedKey.KeyData.Data = NULL; // ignore possible incoming KeyData
unwrappedKey.KeyData.Length = 0;
/* validate wrappedKey format */
if (wrappedKey.blobFormat() != CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7)
CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_WRAPPED_KEY_FORMAT);
/* There is no descriptiveData in a PKCS7 wrapped blob. */
if (descriptiveData)
{
descriptiveData->Data = NULL;
descriptiveData->Length = 0;
}
/* Decrypt the key blob. */
decrypt(context, wrappedKey.keyData(), unwrappedKey.keyData());
/* We are assuming a CSSM_KEYBLOB_WRAPPED_FORMAT_PKCS7 from here on. */
hdr.blobFormat(CSSM_KEYBLOB_RAW_FORMAT_OCTET_STRING);
hdr.LogicalKeySizeInBits = unwrappedKey.length() * 8;
}
//
// KeyHandleFactory
//
KeyHandleFactory::~KeyHandleFactory()
{
}
} // end namespace Tokend
--- NEW FILE KeyHandle.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* KeyHandle.h
* TokendMuscle
*/
#ifndef _TOKEND_KEYHANDLE_H_
#define _TOKEND_KEYHANDLE_H_
#include "RecordHandle.h"
#include <security_cdsa_utilities/handleobject.h>
#include <security_cdsa_utilities/context.h>
#include <security_cdsa_utilities/cssmaclpod.h>
namespace Tokend
{
class MetaRecord;
class Record;
class TokenContext;
//
// A (nearly pure virtual) KeyHandle object which implements the crypto
// interface.
//
class KeyHandle : public RecordHandle
{
NOCOPY(KeyHandle)
public:
KeyHandle(const MetaRecord &metaRecord, const RefPointer<Record> &record);
~KeyHandle();
virtual void getKeySize(CSSM_KEY_SIZE &keySize) = 0;
virtual uint32 getOutputSize(const Context &context, uint32 inputSize,
bool encrypting) = 0;
virtual void generateSignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input,
CssmData &signature) = 0;
virtual void verifySignature(const Context &context,
CSSM_ALGORITHMS signOnly, const CssmData &input,
const CssmData &signature) = 0;
virtual void generateMac(const Context &context, const CssmData &input,
CssmData &output) = 0;
virtual void verifyMac(const Context &context, const CssmData &input,
const CssmData &compare) = 0;
virtual void encrypt(const Context &context, const CssmData &clear,
CssmData &cipher) = 0;
virtual void decrypt(const Context &context, const CssmData &cipher,
CssmData &clear) = 0;
virtual void exportKey(const Context &context,
const AccessCredentials *cred, CssmKey &wrappedKey) = 0;
virtual void wrapUsingKey(const Context &context,
const AccessCredentials *cred, KeyHandle *wrappingKeyHandle,
const CssmKey *wrappingKey, const CssmData *descriptiveData,
CssmKey &wrappedKey);
virtual void wrapKey(const Context &context, const CssmKey &subjectKey,
const CssmData *descriptiveData, CssmKey &wrappedKey);
virtual void unwrapKey(const Context &context,
const AccessCredentials *cred, const AclEntryPrototype *access,
const CssmKey &wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CssmData *descriptiveData,
CSSM_HANDLE &hUnwrappedKey, CssmKey &unwrappedKey);
private:
};
//
// A (pure virtual) factory that creates KeyHandle objects.
//
class KeyHandleFactory
{
NOCOPY(KeyHandleFactory)
public:
KeyHandleFactory() {}
virtual ~KeyHandleFactory() = 0;
virtual KeyHandle *keyHandle(TokenContext *tokenContext,
const MetaRecord &metaRecord, Record &record) const = 0;
};
} // end namespace Tokend
#endif /* !_TOKEND_KEYHANDLE_H_ */
--- NEW FILE MetaAttribute.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaAttribute.cpp
* TokendMuscle
*/
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "Record.h"
#include "DbValue.h"
#include "DbValue.h"
namespace Tokend
{
MetaAttribute::~MetaAttribute()
{
}
// Construct an instance of an appropriate subclass of MetaAttribute based on
// the given format. Called in MetaRecord.cpp createAttribute.
MetaAttribute *MetaAttribute::create(MetaRecord& metaRecord, Format format,
uint32 attributeIndex, uint32 attributeId)
{
switch (format)
{
case kAF_STRING:
return new TypedMetaAttribute<StringValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_SINT32:
return new TypedMetaAttribute<SInt32Value>(metaRecord, format,
attributeIndex, attributeId);
case kAF_UINT32:
return new TypedMetaAttribute<UInt32Value>(metaRecord, format,
attributeIndex, attributeId);
case kAF_BIG_NUM:
return new TypedMetaAttribute<BigNumValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_REAL:
return new TypedMetaAttribute<DoubleValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_TIME_DATE:
return new TypedMetaAttribute<TimeDateValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_BLOB:
return new TypedMetaAttribute<BlobValue>(metaRecord, format,
attributeIndex, attributeId);
case kAF_MULTI_UINT32:
return new TypedMetaAttribute<MultiUInt32Value>(metaRecord, format,
attributeIndex, attributeId);
case kAF_COMPLEX:
default:
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_FIELD_FORMAT);
}
}
const Attribute &
MetaAttribute::attribute(TokenContext *tokenContext, Record &record) const
{
if (!record.hasAttributeAtIndex(mAttributeIndex))
{
if (!mCoder)
{
secdebug("coder",
"No coder for r: %p rid: 0x%08X aid: %u aix: %u",
&record, mMetaRecord.relationId(), mAttributeId,
mAttributeIndex);
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
secdebug("coder",
"Asking coder %p for r: %p rid: 0x%08X aid: %u aix: %u",
mCoder, &record, mMetaRecord.relationId(), mAttributeId,
mAttributeIndex);
mCoder->decode(tokenContext, *this, record);
// The coder had better put something useful in the attribute we asked it to.
if (!record.hasAttributeAtIndex(mAttributeIndex))
{
secdebug("coder",
"Coder %p did not set r: %p rid: 0x%08X aid: %u aix: %u",
mCoder, &record, mMetaRecord.relationId(), mAttributeId,
mAttributeIndex);
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
}
const Attribute &attribute = record.attributeAtIndex(mAttributeIndex);
#ifndef NDEBUG
if (attribute.size() == 1)
secdebug("mscread",
"r: %p rid: 0x%08X aid: %u aix: %u has: 1 value of length: %lu",
&record, mMetaRecord.relationId(), mAttributeId, mAttributeIndex,
attribute[0].Length);
else
secdebug("mscread",
"r: %p rid: 0x%08X aid: %u aix: %u has: %u values",
&record, mMetaRecord.relationId(), mAttributeId, mAttributeIndex,
attribute.size());
#endif
return attribute;
}
} // end namespace Tokend
--- NEW FILE MetaAttribute.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaAttribute.h
* TokendMuscle
*/
#ifndef _TOKEND_METAATTRIBUTE_H_
#define _TOKEND_METAATTRIBUTE_H_
#include <Security/cssmtype.h>
#include <security_utilities/utilities.h>
#include "Attribute.h"
namespace Tokend
{
class Attribute;
class AttributeCoder;
class DbValue;
class MetaRecord;
class Record;
class TokenContext;
// A base class for all meta attributes.
class MetaAttribute
{
NOCOPY(MetaAttribute)
public:
typedef CSSM_DB_ATTRIBUTE_FORMAT Format;
virtual ~MetaAttribute();
// construct an appropriate subclass of MetaAttribute
static MetaAttribute *create(MetaRecord& metaRecord, Format format,
uint32 attributeIndex, uint32 attributeId);
void attributeCoder(AttributeCoder *coder) { mCoder = coder; }
Format attributeFormat() const { return mFormat; }
uint32 attributeIndex() const { return mAttributeIndex; }
uint32 attributeId() const { return mAttributeId; }
const Attribute &attribute(TokenContext *tokenContext,
Record &record) const;
const MetaRecord &metaRecord() const { return mMetaRecord; }
// interface required of all subclasses, implemented with templates below
virtual DbValue *createValue(const CSSM_DATA &data) const = 0;
virtual bool evaluate(TokenContext *tokenContext, const DbValue *value,
Record& record, CSSM_DB_OPERATOR op) const = 0;
protected:
MetaAttribute(MetaRecord& metaRecord, Format format, uint32 attributeIndex,
uint32 attributeId)
: mCoder(NULL), mMetaRecord(metaRecord), mFormat(format),
mAttributeIndex(attributeIndex), mAttributeId(attributeId) {}
AttributeCoder *mCoder;
MetaRecord &mMetaRecord;
Format mFormat;
uint32 mAttributeIndex;
uint32 mAttributeId;
};
// Template used to describe particular subclasses of MetaAttribute
template <class T>
class TypedMetaAttribute : public MetaAttribute
{
public:
TypedMetaAttribute(MetaRecord& metaRecord, Format format,
uint32 attributeIndex, uint32 attributeId)
: MetaAttribute(metaRecord, format, attributeIndex, attributeId) {}
DbValue *createValue(const CSSM_DATA &data) const
{
return new T(data);
}
bool evaluate(TokenContext *tokenContext, const DbValue *value,
Record &record, CSSM_DB_OPERATOR op) const
{
const Attribute &attr = attribute(tokenContext, record);
uint32 numValues = attr.size();
/* If any of the values for this attribute match we have a match. */
for (uint32 ix = 0; ix < numValues; ++ix)
if (dynamic_cast<const T *>(value)->evaluate(static_cast<const T &>(attr[ix]), op))
return true;
return false;
}
bool evaluate(const DbValue *value1, const DbValue *value2,
CSSM_DB_OPERATOR op) const
{
return (dynamic_cast<const T *>(value1))->
evaluate(*dynamic_cast<const T *>(value2), op);
}
};
} // end namespace Tokend
#endif /* !_TOKEND_METAATTRIBUTE_H_ */
--- NEW FILE MetaRecord.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaRecord.cpp
* TokendMuscle
*/
#include "MetaRecord.h"
#include "Attribute.h"
#include "KeyHandle.h"
#include "MetaAttribute.h"
#include "Record.h"
#include <security_utilities/trackingallocator.h>
#include <security_cdsa_utilities/cssmbridge.h>
namespace Tokend
{
#pragma mark ---------------- MetaRecord methods --------------
// Used for normal relations.
MetaRecord::MetaRecord(RelationId inRelationId) : mRelationId(inRelationId),
mKeyHandleFactory(NULL)
{
// Passing in a bogus attributeId for the attribute at index 0 (which is
// the data). It's not possible to look up the attribute by attributeId,
// nor should any coder rely on it's value.
mAttributeVector.push_back(MetaAttribute::create(*this, kAF_BLOB, 0,
'data'));
}
MetaRecord::~MetaRecord()
{
for_each_delete(mAttributeVector.begin(), mAttributeVector.end());
}
MetaAttribute &MetaRecord::createAttribute(const std::string &inAttributeName,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
{
uint32 anAttributeId = mAttributeVector.size() - 1;
return createAttribute(&inAttributeName, NULL, anAttributeId,
inAttributeFormat);
}
MetaAttribute &MetaRecord::createAttribute(const string *inAttributeName,
const CssmOid *inAttributeOID, uint32 inAttributeID,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat)
{
// Index of new element is current size of vector
uint32 anAttributeIndex = mAttributeVector.size();
bool aInsertedAttributeName = false;
bool aInsertedAttributeOID = false;
bool aInsertedAttributeID = false;
if (inAttributeName)
{
if (!mNameStringMap.insert(NameStringMap::value_type(*inAttributeName,
anAttributeIndex)).second)
CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
aInsertedAttributeName = true;
}
try
{
if (inAttributeOID)
{
if (!mNameOIDMap.insert(NameOIDMap::value_type(*inAttributeOID,
anAttributeIndex)).second)
CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
aInsertedAttributeOID = true;
}
if (!mNameIntMap.insert(NameIntMap::value_type(inAttributeID,
anAttributeIndex)).second)
CssmError::throwMe(CSSMERR_DL_FIELD_SPECIFIED_MULTIPLE);
aInsertedAttributeID = true;
// Note: this no longer throws INVALID_FIELD_NAME since the attribute
// will always have an attribute ID by which it is known.
MetaAttribute *ma = MetaAttribute::create(*this, inAttributeFormat,
anAttributeIndex, inAttributeID);
mAttributeVector.push_back(ma);
return *ma;
}
catch (...)
{
if (aInsertedAttributeName)
mNameStringMap.erase(*inAttributeName);
if (aInsertedAttributeOID)
mNameOIDMap.erase(*inAttributeOID);
if (inAttributeID)
mNameIntMap.erase(inAttributeID);
throw;
}
}
// Return the index (0 though NumAttributes - 1) of the attribute
// represented by inAttributeInfo
uint32 MetaRecord::attributeIndex(
const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
{
uint32 anIndex;
switch (inAttributeInfo.AttributeNameFormat)
{
case CSSM_DB_ATTRIBUTE_NAME_AS_STRING:
{
string aName(inAttributeInfo.Label.AttributeName);
NameStringMap::const_iterator it = mNameStringMap.find(aName);
if (it == mNameStringMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
anIndex = it->second;
break;
}
case CSSM_DB_ATTRIBUTE_NAME_AS_OID:
{
const CssmOid &aName =
CssmOid::overlay(inAttributeInfo.Label.AttributeOID);
NameOIDMap::const_iterator it = mNameOIDMap.find(aName);
if (it == mNameOIDMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
anIndex = it->second;
break;
}
case CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER:
{
uint32 aName = inAttributeInfo.Label.AttributeID;
NameIntMap::const_iterator it = mNameIntMap.find(aName);
if (it == mNameIntMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
anIndex = it->second;
break;
}
default:
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
break;
}
return anIndex;
}
const MetaAttribute &MetaRecord::metaAttribute(
const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const
{
return *mAttributeVector[attributeIndex(inAttributeInfo)];
}
const MetaAttribute &MetaRecord::metaAttribute(uint32 name) const
{
NameIntMap::const_iterator it = mNameIntMap.find(name);
if (it == mNameIntMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
return *mAttributeVector[it->second];
}
const MetaAttribute &MetaRecord::metaAttribute(const std::string &name) const
{
NameStringMap::const_iterator it = mNameStringMap.find(name);
if (it == mNameStringMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_FIELD_NAME);
return *mAttributeVector[it->second];
}
const MetaAttribute &MetaRecord::metaAttributeForData() const
{
return *mAttributeVector[0];
}
void MetaRecord::attributeCoder(uint32 name, AttributeCoder *coder)
{
const_cast<MetaAttribute &>(metaAttribute(name)).attributeCoder(coder);
}
void MetaRecord::attributeCoder(const std::string &name, AttributeCoder *coder)
{
const_cast<MetaAttribute &>(metaAttribute(name)).attributeCoder(coder);
}
void MetaRecord::attributeCoderForData(AttributeCoder *coder)
{
const_cast<MetaAttribute &>(metaAttributeForData()).attributeCoder(coder);
}
void
MetaRecord::get(TokenContext *tokenContext, Record &record,
TOKEND_RETURN_DATA &data) const
{
if (data.attributes)
{
// Fetch the requested attributes.
CSSM_DB_RECORD_ATTRIBUTE_DATA &drad = *data.attributes;
drad.DataRecordType = mRelationId;
drad.SemanticInformation = 0;
for (uint32 ix = 0; ix < drad.NumberOfAttributes; ++ix)
{
CSSM_DB_ATTRIBUTE_DATA &dad = drad.AttributeData[ix];
const MetaAttribute &ma = metaAttribute(dad.Info);
dad.Info.AttributeFormat = ma.attributeFormat();
const Attribute &attr = ma.attribute(tokenContext, record);
dad.NumberOfValues = attr.size();
dad.Value = const_cast<CSSM_DATA_PTR>(attr.values());
}
}
if (data.data)
{
// Fetch the data.
const MetaAttribute &ma = metaAttributeForData();
const Attribute &attr = ma.attribute(tokenContext, record);
if (attr.size() != 1)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
(*data.data) = attr.values()[0];
if (mKeyHandleFactory)
{
KeyHandle *keyHandle = mKeyHandleFactory->keyHandle(tokenContext,
*this, record);
data.keyhandle = keyHandle ? keyHandle->handle() : 0;
}
else
data.keyhandle = 0;
}
}
} // end namespace Tokend
--- NEW FILE MetaRecord.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* MetaRecord.h
* TokendMuscle
*/
#ifndef _TOKEND_METARECORD_H_
#define _TOKEND_METARECORD_H_
#include <security_cdsa_utilities/cssmdata.h>
#include <map>
#include <string>
#include <vector>
#include <SecurityTokend/SecTokend.h>
namespace Tokend
{
// Shorter names for some long cssm constants
enum
{
kAF_STRING = CSSM_DB_ATTRIBUTE_FORMAT_STRING,
kAF_SINT32 = CSSM_DB_ATTRIBUTE_FORMAT_SINT32,
kAF_UINT32 = CSSM_DB_ATTRIBUTE_FORMAT_UINT32,
kAF_BIG_NUM = CSSM_DB_ATTRIBUTE_FORMAT_BIG_NUM,
kAF_REAL = CSSM_DB_ATTRIBUTE_FORMAT_REAL,
kAF_TIME_DATE = CSSM_DB_ATTRIBUTE_FORMAT_TIME_DATE,
kAF_BLOB = CSSM_DB_ATTRIBUTE_FORMAT_BLOB,
kAF_MULTI_UINT32 = CSSM_DB_ATTRIBUTE_FORMAT_MULTI_UINT32,
kAF_COMPLEX = CSSM_DB_ATTRIBUTE_FORMAT_COMPLEX
};
typedef CSSM_DB_RECORDTYPE RelationId;
class AttributeCoder;
class KeyHandleFactory;
class MetaAttribute;
class Record;
class TokenContext;
//
// Meta (or Schema) representation of an a Record. Used for packing and
// unpacking objects.
//
class MetaRecord
{
NOCOPY(MetaRecord)
public:
// Used for normal relations
// dataCoder is the coder which will be used for the "data" value
// (metaAttributeForData() returns a metaAttribute using this coder.
MetaRecord(RelationId inRelationId);
~MetaRecord();
MetaAttribute &createAttribute(const std::string &inAttributeName,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat);
MetaAttribute &createAttribute(const std::string *inAttributeName,
const CssmOid *inAttributeOID,
uint32 inAttributeID,
CSSM_DB_ATTRIBUTE_FORMAT inAttributeFormat);
const MetaAttribute &metaAttribute(
const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
const MetaAttribute &MetaRecord::metaAttribute(uint32 name) const;
const MetaAttribute &MetaRecord::metaAttribute(
const std::string &name) const;
const MetaAttribute &metaAttributeForData() const;
void attributeCoder(uint32 name, AttributeCoder *coder);
void attributeCoder(const std::string &name, AttributeCoder *coder);
void attributeCoderForData(AttributeCoder *coder);
RelationId relationId() const { return mRelationId; }
// Return the index (0 though NumAttributes - 1) of the attribute
// represented by inAttributeInfo
uint32 attributeIndex(const CSSM_DB_ATTRIBUTE_INFO &inAttributeInfo) const;
void get(TokenContext *tokenContext, Record &record,
TOKEND_RETURN_DATA &data) const;
void keyHandleFactory(KeyHandleFactory *keyHandleFactory)
{ mKeyHandleFactory = keyHandleFactory; }
private:
//friend class MetaAttribute;
RelationId mRelationId;
typedef std::map<std::string, uint32> NameStringMap;
typedef std::map<CssmBuffer<CssmOidContainer>, uint32> NameOIDMap;
typedef std::map<uint32, uint32> NameIntMap;
NameStringMap mNameStringMap;
NameOIDMap mNameOIDMap;
NameIntMap mNameIntMap;
typedef std::vector<MetaAttribute *> AttributeVector;
typedef AttributeVector::iterator AttributeIterator;
typedef AttributeVector::const_iterator ConstAttributeIterator;
AttributeVector mAttributeVector;
KeyHandleFactory *mKeyHandleFactory;
};
} // end namespace Tokend
#endif /* !_TOKEND_METARECORD_H_ */
--- NEW FILE PKCS11Object.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* PKCS11Object.cpp
* TokendMuscle
*/
#include "PKCS11Object.h"
#include <security_utilities/debugging.h>
#include <security_cdsa_utilities/cssmerrors.h>
#include <Security/cssmerr.h>
#if defined(DEBUGDUMP)
#include "cryptoki.h"
#include "pkcs11.h"
#endif /* !defined(DEBUGDUMP) */
namespace Tokend
{
PKCS11Object::PKCS11Object(const void *inData, size_t inSize)
{
const PKCS11ObjectHeader *object =
reinterpret_cast<const PKCS11ObjectHeader *>(inData);
if (inSize < sizeof(PKCS11ObjectHeader) || !object
|| inSize < (object->size() + sizeof(PKCS11ObjectHeader)))
CssmError::throwMe(CSSM_ERRCODE_INTERNAL_ERROR);
size_t objectSize = object->size();
const uint8_t *data = object->data();
for (size_t bytesRead = 0; bytesRead < objectSize;)
{
const PKCS11Attribute *attribute =
reinterpret_cast<const PKCS11Attribute *>(&data[bytesRead]);
IFDUMPING("pkcs11", debugDump(*attribute));
mAttributeMap.insert(pair<uint32_t,
const PKCS11Attribute *>(attribute->attributeId(), attribute));
bytesRead += sizeof(PKCS11Attribute) + attribute->size();
}
}
const PKCS11Object::PKCS11Attribute *
PKCS11Object::attribute(uint32_t attributeId) const
{
AttributeMap::const_iterator it = mAttributeMap.find(attributeId);
if (it == mAttributeMap.end())
{
secdebug("pkcs11", "pkcs11 attribute: %08X not found", attributeId);
return NULL;
}
secdebug("pkcs11-d", "accessing pkcs11 attribute: %08X size: %lu",
attributeId, it->second->size());
return it->second;
}
bool PKCS11Object::attributeValueAsBool(uint32_t attributeId) const
{
const PKCS11Attribute *attr = attribute(attributeId);
if (!attr)
return false;
if (attr->size() != 1)
{
secdebug("pkcs11",
"attributeValueAsBool: pkcs11 attribute: %08X size: %lu",
attributeId, attr->size());
CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
}
return *attr->data() != 0;
}
uint32_t PKCS11Object::attributeValueAsUint32(uint32_t attributeId) const
{
const PKCS11Attribute *attr = attribute(attributeId);
if (!attr)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
if (attr->size() != 4)
{
secdebug("pkcs11",
"attributeValueAsUint32: pkcs11 attribute: %08X size: %lu",
attributeId, attr->size());
CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
}
const uint8_t *data = attr->data();
return (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
}
void PKCS11Object::attributeValueAsData(uint32_t attributeId,
const uint8_t *&data, size_t &size) const
{
const PKCS11Attribute *attr = attribute(attributeId);
if (!attr)
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
size = attr->size();
data = attr->data();
}
#if defined(DEBUGDUMP)
void PKCS11Object::debugDump(const PKCS11Attribute &attribute)
{
Debug::dump("found pkcs11 attribute: %s size: %lu ",
attributeName(attribute.attributeId()), attribute.size());
Debug::dumpData(attribute.data(), attribute.size());
Debug::dump("\n");
}
const char *PKCS11Object::attributeName(uint32_t attributeId)
{
static char buffer[20];
switch (attributeId)
{
case CKA_CLASS: return "CLASS";
case CKA_TOKEN: return "TOKEN";
case CKA_PRIVATE: return "PRIVATE";
case CKA_LABEL: return "LABEL";
case CKA_APPLICATION: return "APPLICATION";
case CKA_VALUE: return "VALUE";
case CKA_OBJECT_ID: return "OBJECT_ID";
case CKA_CERTIFICATE_TYPE: return "CERTIFICATE_TYPE";
case CKA_ISSUER: return "ISSUER";
case CKA_SERIAL_NUMBER: return "SERIAL_NUMBER";
case CKA_AC_ISSUER: return "AC_ISSUER";
case CKA_OWNER: return "OWNER";
case CKA_ATTR_TYPES: return "ATTR_TYPES";
case CKA_TRUSTED: return "TRUSTED";
case CKA_KEY_TYPE: return "KEY_TYPE";
case CKA_SUBJECT: return "SUBJECT";
case CKA_ID: return "ID";
case CKA_SENSITIVE: return "SENSITIVE";
case CKA_ENCRYPT: return "ENCRYPT";
case CKA_DECRYPT: return "DECRYPT";
case CKA_WRAP: return "WRAP";
case CKA_UNWRAP: return "UNWRAP";
case CKA_SIGN: return "SIGN";
case CKA_SIGN_RECOVER: return "SIGN_RECOVER";
case CKA_VERIFY: return "VERIFY";
case CKA_VERIFY_RECOVER: return "VERIFY_RECOVER";
case CKA_DERIVE: return "DERIVE";
case CKA_START_DATE: return "START_DATE";
case CKA_END_DATE: return "END_DATE";
case CKA_MODULUS: return "MODULUS";
case CKA_MODULUS_BITS: return "MODULUS_BITS";
case CKA_PUBLIC_EXPONENT: return "PUBLIC_EXPONENT";
case CKA_PRIVATE_EXPONENT: return "PRIVATE_EXPONENT";
case CKA_PRIME_1: return "PRIME_1";
case CKA_PRIME_2: return "PRIME_2";
case CKA_EXPONENT_1: return "EXPONENT_1";
case CKA_EXPONENT_2: return "EXPONENT_2";
case CKA_COEFFICIENT: return "COEFFICIENT";
case CKA_PRIME: return "PRIME";
case CKA_SUBPRIME: return "SUBPRIME";
case CKA_BASE: return "BASE";
case CKA_PRIME_BITS: return "PRIME_BITS";
case CKA_SUB_PRIME_BITS: return "SUB_PRIME_BITS";
case CKA_VALUE_BITS: return "VALUE_BITS";
case CKA_VALUE_LEN: return "VALUE_LEN";
case CKA_EXTRACTABLE: return "EXTRACTABLE";
case CKA_LOCAL: return "LOCAL";
case CKA_NEVER_EXTRACTABLE: return "NEVER_EXTRACTABLE";
case CKA_ALWAYS_SENSITIVE: return "ALWAYS_SENSITIVE";
case CKA_KEY_GEN_MECHANISM: return "KEY_GEN_MECHANISM";
case CKA_MODIFIABLE: return "MODIFIABLE";
case CKA_EC_PARAMS: return "EC_PARAMS";
case CKA_EC_POINT: return "EC_POINT";
case CKA_SECONDARY_AUTH: return "SECONDARY_AUTH";
case CKA_AUTH_PIN_FLAGS: return "AUTH_PIN_FLAGS";
case CKA_HW_FEATURE_TYPE: return "HW_FEATURE_TYPE";
case CKA_RESET_ON_INIT: return "RESET_ON_INIT";
case CKA_HAS_RESET: return "HAS_RESET";
case CKA_VENDOR_DEFINED: return "VENDOR_DEFINED";
default:
snprintf(buffer, sizeof(buffer), "unknown(%0x08X)", attributeId);
return buffer;
}
}
#endif /* !defined(DEBUGDUMP) */
} // end namespace Tokend
--- NEW FILE PKCS11Object.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* PKCS11Object.h
* TokendMuscle
*/
#ifndef _TOKEND_PKCS11OBJECT_H_
#define _TOKEND_PKCS11OBJECT_H_
#include <stdint.h>
#include <map>
#include <security_utilities/debugging.h>
namespace Tokend
{
// This object doesn't copy it's data. It's assumed that the data will live at
// least as long as this object does.
class PKCS11Object
{
public:
PKCS11Object(const void *inData, size_t inSize);
bool attributeValueAsBool(uint32_t attributeId) const;
uint32_t attributeValueAsUint32(uint32_t attributeId) const;
void PKCS11Object::attributeValueAsData(uint32_t attributeId,
const uint8_t *&data, size_t &size) const;
private:
struct PKCS11ObjectHeader
{
uint8_t oh_type;
uint8_t oh_id[2];
uint8_t oh_next_id[2];
uint8_t oa_size[2];
uint8_t oh_data[0];
size_t size() const { return (oa_size[0] << 8) + oa_size[1]; }
const uint8_t *data() const { return oh_data; }
};
struct PKCS11Attribute
{
uint8_t oa_id[4]; // big endian attribute type
uint8_t oa_size[2]; // big endian attribute length
uint8_t oa_data[0];
uint32_t attributeId() const { return (oa_id[0] << 24)
+ (oa_id[1] << 16) + (oa_id[2] << 8) + oa_id[3]; }
size_t size() const { return (oa_size[0] << 8) + oa_size[1]; }
const uint8_t *data() const { return oa_data; }
};
const PKCS11Attribute *attribute(uint32_t attributeId) const;
#if defined(DEBUGDUMP)
void debugDump(const PKCS11Attribute &attribute);
static const char *attributeName(uint32_t attributeId);
#endif /* !defined(DEBUGDUMP) */
typedef std::map<uint32_t, const PKCS11Attribute *> AttributeMap;
AttributeMap mAttributeMap;
};
} // end namespace Tokend
#endif /* !_TOKEND_PKCS11OBJECT_H_ */
--- NEW FILE Record.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Record.cpp
* TokendMuscle
*/
#include "Record.h"
#include <security_cdsa_client/aclclient.h>
namespace Tokend
{
AutoAclOwnerPrototype Record::gNobodyAclOwner;
AutoAclEntryInfoList Record::gAnyReadAclEntries;
Record::Record()
{
}
Record::~Record()
{
for_each_delete(mAttributes.begin(), mAttributes.end());
}
bool
Record::hasAttributeAtIndex(uint32 attributeIndex) const
{
if (attributeIndex < mAttributes.size())
return mAttributes[attributeIndex] != NULL;
return false;
}
const Attribute &
Record::attributeAtIndex(uint32 attributeIndex) const
{
if (attributeIndex < mAttributes.size())
{
Attribute *attribute = mAttributes[attributeIndex];
if (attribute)
return *attribute;
}
CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
}
void Record::attributeAtIndex(uint32 attributeIndex, Attribute *attribute)
{
auto_ptr<Attribute> _(attribute);
if (attributeIndex >= mAttributes.size())
mAttributes.resize(attributeIndex + 1);
if (mAttributes[attributeIndex] != NULL)
CssmError::throwMe(CSSMERR_DL_INTERNAL_ERROR);
mAttributes[attributeIndex] = _.release();
}
void Record::getOwner(AclOwnerPrototype &owner)
{
// Normally nobody can change the acl of an object on a smartcard.
if (!gNobodyAclOwner)
{
Allocator &alloc = Allocator::standard();
gNobodyAclOwner.allocator(alloc);
gNobodyAclOwner = CssmClient::AclFactory::NobodySubject(alloc);
}
owner = gNobodyAclOwner;
}
void Record::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
// Normally anyone can read an object on a smartcard (subclasses might
// override this).
if (!gAnyReadAclEntries) {
gAnyReadAclEntries.allocator(Allocator::standard());
gAnyReadAclEntries.add(CssmClient::AclFactory::AnySubject(
gAnyReadAclEntries.allocator()),
AclAuthorizationSet(CSSM_ACL_AUTHORIZATION_DB_READ, 0));
}
count = gAnyReadAclEntries.size();
acls = gAnyReadAclEntries.entries();
}
void Record::changeOwner(const AclOwnerPrototype &owner)
{
// Default changeOwner on a record always fails.
CssmError::throwMe(CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED);
}
void Record::changeAcl(const AccessCredentials &cred, const AclEdit &edit)
{
// Default changeAcl on a record always fails.
CssmError::throwMe(CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED);
}
const char *Record::description()
{
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
Attribute *Record::getDataAttribute(TokenContext *tokenContext)
{
CssmError::throwMe(CSSMERR_DL_MISSING_VALUE);
}
} // end namespace Tokend
--- NEW FILE Record.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Record.h
* TokendMuscle
*/
#ifndef _TOKEND_RECORD_H_
#define _TOKEND_RECORD_H_
#include "AttributeCoder.h"
#include "MetaRecord.h"
#include "Attribute.h"
#include <security_utilities/refcount.h>
#include <security_utilities/adornments.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <SecurityTokend/SecTokend.h>
namespace Tokend
{
class Record : public RefCount, public Security::Adornable
{
NOCOPY(Record)
public:
Record();
virtual ~Record();
bool hasAttributeAtIndex(uint32 attributeIndex) const;
const Attribute &attributeAtIndex(uint32 attributeIndex) const;
void attributeAtIndex(uint32 attributeIndex, Attribute *attribute);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&aclList);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
virtual const char *description();
virtual Attribute *getDataAttribute(TokenContext *tokenContext);
protected:
typedef std::vector<Attribute *> Attributes;
typedef Attributes::iterator AttributesIterator;
typedef Attributes::const_iterator ConstAttributesIterator;
Attributes mAttributes;
// temporary ACL cache hack - to be removed
static AutoAclOwnerPrototype gNobodyAclOwner;
static AutoAclEntryInfoList gAnyReadAclEntries;
};
} // end namespace Tokend
#endif /* !_TOKEND_RECORD_H_ */
--- NEW FILE RecordHandle.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* RecordHandle.cpp
* TokendMuscle
*/
#include "RecordHandle.h"
#include "MetaRecord.h"
#include "Record.h"
namespace Tokend
{
RecordHandle::RecordHandle(const MetaRecord &metaRecord,
const RefPointer<Record> &record) :
mMetaRecord(metaRecord), mRecord(record)
{
}
RecordHandle::~RecordHandle()
{
}
void RecordHandle::get(TokenContext *tokenContext, TOKEND_RETURN_DATA &data)
{
mMetaRecord.get(tokenContext, *mRecord, data);
data.record = handle();
}
void RecordHandle::getOwner(AclOwnerPrototype &owner)
{
mRecord->getOwner(owner);
}
void RecordHandle::getAcl(const char *tag, uint32 &count, AclEntryInfo *&acls)
{
mRecord->getAcl(tag, count, acls);
}
void RecordHandle::changeOwner(const AclOwnerPrototype &owner)
{
mRecord->changeOwner(owner);
}
void RecordHandle::changeAcl(const AccessCredentials &cred,
const AclEdit &edit)
{
mRecord->changeAcl(cred, edit);
}
} // end namespace Tokend
--- NEW FILE RecordHandle.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* RecordHandle.h
* TokendMuscle
*/
#ifndef _TOKEND_RECORDHANDLE_H_
#define _TOKEND_RECORDHANDLE_H_
#include <security_cdsa_utilities/handleobject.h>
#include <security_utilities/refcount.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <SecurityTokend/SecTokend.h>
namespace Tokend
{
class MetaRecord;
class Record;
class TokenContext;
class RecordHandle: public HandleObject
{
NOCOPY(RecordHandle)
public:
RecordHandle(const MetaRecord &metaRecord,
const RefPointer<Record> &record);
virtual ~RecordHandle();
virtual void get(TokenContext *tokenContext, TOKEND_RETURN_DATA &data);
virtual void getOwner(AclOwnerPrototype &owner);
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&aclList);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
private:
const MetaRecord &mMetaRecord;
RefPointer<Record> mRecord;
};
} // end namespace Tokend
#endif /* !_TOKEND_RECORDHANDLE_H_ */
--- NEW FILE Relation.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Relation.cpp
* TokendMuscle
*/
#include "Relation.h"
namespace Tokend
{
// @@@ need to distinguish between records that exist at db open time, and
// those that are being added and must be written back to the card
#pragma mark ---------------- Relation methods --------------
Relation::~Relation()
{
delete mMetaRecord;
}
void Relation::insertRecord(const RefPointer<Record> &record)
{
push_back(record);
}
bool Relation::matchesId(RelationId inRelationId) const
{
RelationId anId = mMetaRecord->relationId();
if (inRelationId == CSSM_DL_DB_RECORD_ANY) // All non schema tables.
return !(CSSM_DB_RECORDTYPE_SCHEMA_START <= anId
&& anId < CSSM_DB_RECORDTYPE_SCHEMA_END);
if (inRelationId == CSSM_DL_DB_RECORD_ALL_KEYS) // All key tables.
return (anId == CSSM_DL_DB_RECORD_PUBLIC_KEY
|| anId == CSSM_DL_DB_RECORD_PRIVATE_KEY
|| anId == CSSM_DL_DB_RECORD_SYMMETRIC_KEY);
return inRelationId == anId; // Only if exact match.
}
} // end namespace Tokend
--- NEW FILE Relation.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Relation.h
* TokendMuscle
*/
#ifndef _TOKEND_RELATION_H_
#define _TOKEND_RELATION_H_
#include "Record.h"
#include <vector>
namespace Tokend
{
class MetaRecord;
class Record;
class Relation : public std::vector< RefPointer<Record> >
{
NOCOPY(Relation)
public:
Relation(MetaRecord *metaRecord) : mMetaRecord(metaRecord) { }
~Relation();
const MetaRecord &metaRecord() const { return *mMetaRecord; }
MetaRecord &metaRecord() { return *mMetaRecord; }
void insertRecord(const RefPointer<Record> &record);
bool matchesId(RelationId inRelationId) const;
protected:
MetaRecord *mMetaRecord;
};
} // end namespace Tokend
#endif /* !_TOKEND_RELATION_H_ */
--- NEW FILE SCardError.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* SCardError.cpp
* TokendMuscle
*/
#include "SCardError.h"
#include <Security/cssmerr.h>
namespace Tokend
{
/*
Excerpt from ISO/IEC 7816 part 3:
Status bytes (SW1=$6x or $9x, expect $60; SW2 any value)
--------------------------------------------------------
The end sequence SW1-SW2 gives the card status at the end of the command.
The normal ending is indicated by SW1-SW2 = $90-$00.
When the most significant half byte SW1 is $6, the meaning of SW1 is
independant of the application. The following five values are defined:
$6E The card does not support the instruction class.
$6D The instruction code is not programmed or is invalid.
$6B The reference is incorrect.
$67 The length is incorrect.
$6F No precise diagnostic is given.
Other values are reserved for future use by ISO7816. When SW1 is neither $6E
nor $6D, the card support the instruction. This part of ISO7816 does not
interprets neither $9X SW1 bytes, nor SW2
bytes; Their meaning relates to the application itself.
Supplement (were seen sometimes):
---------------------------------
SW1 SW2 Meaning
62 81 Returned data may be corrupted.
62 82 The end of the file has been reached before the end of reading.
62 84 Selected file is not valid.
65 01 Memory failure. There have been problems in writing or reading
the EEPROM. Other hardware problems may also bring this error.
68 00 The request function is not supported by the card.
6A 00 Bytes P1 and/or P2 are incorrect.
6A 80 The parameters in the data field are incorrect.
6A 82 File not found.
6A 83 Record not found.
6A 84 There is insufficient memory space in record or file.
6A 87 The P3 value is not consistent with the P1 and P2 values.
6A 88 Referenced data not found.
6C XX Incorrect P3 length.
Excerpt from ISO/IEC 7816 part 4:
Due to specifications in part 3 of ISO/IEC 7816, this part does not define the
following values of SW1-SW2 :
'60XX'
'67XX', '6BXX', '6DXX', '6EXX', '6FXX'; in each case if 'XX'!='00'
'9XXX', if 'XXX'!='000'
The following values of SW1-SW2 are defined whichever protocol is used (see
examples in annex A).
If a command is aborted with a response where SW1='6C', then SW2 indicates the
value to be given to the short Le field (exact length of requested data) when
re-issuing the same command before issuing any other command.
If a command (which may be of case 2 or 4, see table 4 and figure 4) is
processed with a response where SW1='61', then SW2 indicates the maximum value
to be given to the short Le field (length of extra data still available) in
a GET RESPONSE command issued before issuing any other command.
NOTE - A functionality similar to that offered by '61XX' may be offered at
application level by '9FXX'. However, applications may use '9FXX' for other
purposes.
Table 12 completed by tables 13 to 18 shows the general meanings of the values
of SW1-SW2 defined in this part of ISO/IEC 7816. For each command, an
appropriate clause provides more detailed meanings.
Tables 13 to 18 specify values of SW2 when SW1 is valued to '62', '63', '65',
'68', '69' and '6A'. The values of SW2 not defined in tables 13 to 18 are RFU,
except the values from 'F0' to 'FF' which are not defined in this part of
ISO/IEC 7816.
Table 12 - Coding of SW1-SW2
SW1-SW2 Meaning
Normal processing
'9000' No further qualification
'61XX' SW2 indicates the number of response bytes still available
(see text below)
Warning processings
'62XX' State of non-volatile memory unchanged (further qualification in SW2,
see table 13)
'63XX' State of non-volatile memory changed (further qualification in SW2,
see table 14)
Execution errors
'64XX' State of non-volatile memory unchanged (SW2='00', other values are RFU)
'65XX' State of non-volatile memory changed (further qualification in SW2,
see table 15)
'66XX' Reserved for security-related issues (not defined in this part of
ISO/IEC 7816)
Checking errors
'6700' Wrong length
'68XX' Functions in CLA not supported (further qualification in SW2, see
table 16)
'69XX' Command not allowed (further qualification in SW2, see table 17)
'6AXX' Wrong parameter(s) P1-P2 (further qualification in SW2, see table 18)
'6B00' Wrong parameter(s) P1-P2
'6CXX' Wrong length Le: SW2 indicates the exact length (see text below)
'6D00' Instruction code not supported or invalid
'6E00' Class not supported
'6F00' No precise diagnosis
Table 13 - Coding of SW2 when SW1='62'
SW2 Meaning
'00' No information given
'81' Part of returned data may be corrupted
'82' End of file/record reached before reading Le bytes
'83' Selected file invalidated
'84' FCI not formatted according to 1.1.5
Table 14 - Coding of SW2 when SW1='63'
SW2 Meaning
'00' No information given
'81' File filled up by the last write
'CX' Counter provided by 'X' (valued from 0 to 15) (exact meaning depending
on the command)
Table 15 - Coding of SW2 when SW1='65'
SW2 Meaning
'00' No information given
'81' Memory failure
Table 16 - Coding of SW2 when SW1='68'
SW2 Meaning
'00' No information given
'81' Logical channel not supported
'82' Secure messaging not supported
Table 17 - Coding of SW2 when SW1='69'
SW2 Meaning
'00' No information given
'81' Command incompatible with file structure
'82' Security status not satisfied
'83' Authentication method blocked
'84' Referenced data invalidated
'85' Conditions of use not satisfied
'86' Command not allowed (no current EF)
'87' Expected SM data objects missing
'88' SM data objects incorrect
Table 18 - Coding of SW2 when SW1='6A'
SW2 Meaning
'00' No information given
'80' Incorrect parameters in the data field
'81' Function not supported
'82' File not found
'83' Record not found
'84' Not enough memory space in the file
'85' Lc inconsistent with TLV structure
'86' Incorrect parameters P1-P2
'87' Lc inconsistent with P1-P2
'88' Referenced data not found
*/
//
// SCardError exceptions
//
SCardError::SCardError(uint16_t sw) : statusWord(sw)
{
IFDEBUG(debugDiagnose(this));
}
const char *SCardError::what() const throw ()
{ return "SCardError"; }
OSStatus SCardError::osStatus() const
{
switch (statusWord)
{
case SCARD_SUCCESS:
return 0;
case SCARD_FILE_FILLED:
case SCARD_MEMORY_FAILURE:
case SCARD_NO_MEMORY_LEFT:
return CSSM_ERRCODE_MEMORY_ERROR;
case SCARD_AUTHENTICATION_FAILED:
case SCARD_AUTHENTICATION_FAILED_0:
case SCARD_AUTHENTICATION_FAILED_1:
case SCARD_AUTHENTICATION_FAILED_2:
case SCARD_AUTHENTICATION_FAILED_3:
case SCARD_AUTHENTICATION_FAILED_4:
case SCARD_AUTHENTICATION_FAILED_5:
case SCARD_AUTHENTICATION_FAILED_6:
case SCARD_AUTHENTICATION_FAILED_7:
case SCARD_AUTHENTICATION_FAILED_8:
case SCARD_AUTHENTICATION_FAILED_9:
case SCARD_AUTHENTICATION_FAILED_10:
case SCARD_AUTHENTICATION_FAILED_11:
case SCARD_AUTHENTICATION_FAILED_12:
case SCARD_AUTHENTICATION_FAILED_13:
case SCARD_AUTHENTICATION_FAILED_14:
case SCARD_AUTHENTICATION_FAILED_15:
case SCARD_AUTHENTICATION_BLOCKED:
return CSSM_ERRCODE_OPERATION_AUTH_DENIED;
case SCARD_COMMAND_NOT_ALLOWED:
case SCARD_NOT_AUTHORIZED:
case SCARD_USE_CONDITIONS_NOT_MET:
return CSSM_ERRCODE_OBJECT_USE_AUTH_DENIED;
case SCARD_FUNCTION_NOT_SUPPORTED:
case SCARD_INSTRUCTION_CODE_INVALID:
return CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED;
case SCARD_FILE_NOT_FOUND:
case SCARD_RECORD_NOT_FOUND:
return CSSMERR_DL_RECORD_NOT_FOUND;
case SCARD_BYTES_LEFT_IN_SW2:
case SCARD_EXECUTION_WARNING:
case SCARD_RETURNED_DATA_CORRUPTED:
case SCARD_END_OF_FILE_REACHED:
case SCARD_FILE_INVALIDATED:
case SCARD_FCI_INVALID:
case SCARD_EXECUTION_ERROR:
case SCARD_CHANGED_ERROR:
case SCARD_LENGTH_INCORRECT:
case SCARD_CLA_UNSUPPORTED:
case SCARD_LOGICAL_CHANNEL_UNSUPPORTED:
case SCARD_SECURE_MESSAGING_UNSUPPORTED:
case SCARD_COMMAND_INCOMPATIBLE:
case SCARD_REFERENCED_DATA_INVALIDATED:
case SCARD_NO_CURRENT_EF:
case SCARD_SM_DATA_OBJECTS_MISSING:
case SCARD_SM_DATA_NOT_ALLOWED:
case SCARD_WRONG_PARAMETER:
case SCARD_DATA_INCORRECT:
case SCARD_LC_INCONSISTENT_TLV:
case SCARD_INCORRECT_P1_P2:
case SCARD_LC_INCONSISTENT_P1_P2:
case SCARD_REFERENCED_DATA_NOT_FOUND:
case SCARD_WRONG_PARAMETER_P1_P2:
case SCARD_LE_IN_SW2:
case SCARD_INSTRUCTION_CLASS_UNSUPPORTED:
case SCARD_UNSPECIFIED_ERROR:
default:
return CSSM_ERRCODE_INTERNAL_ERROR;
}
}
int SCardError::unixError() const
{
switch (statusWord)
{
default:
// cannot map this to errno space
return -1;
}
}
void SCardError::throwMe(uint16_t sw)
{ throw SCardError(sw); }
#if !defined(NDEBUG)
void SCardError::debugDiagnose(const void *id) const
{
secdebug("exception", "%p Error %s (%04hX)",
id, errorstr(statusWord), statusWord);
}
const char *SCardError::errorstr(uint16_t sw)
{
switch (sw)
{
case SCARD_SUCCESS:
return "Success";
case SCARD_BYTES_LEFT_IN_SW2:
return "SW2 indicates the number of response bytes still available";
case SCARD_EXECUTION_WARNING:
return "Execution warning, state of non-volatile memory unchanged";
case SCARD_RETURNED_DATA_CORRUPTED:
return "Part of returned data may be corrupted.";
case SCARD_END_OF_FILE_REACHED:
return "End of file/record reached before reading Le bytes.";
case SCARD_FILE_INVALIDATED:
return "Selected file invalidated.";
case SCARD_FCI_INVALID:
return "FCI not formatted according to 1.1.5.";
case SCARD_AUTHENTICATION_FAILED:
return "Authentication failed.";
case SCARD_FILE_FILLED:
return "File filled up by the last write.";
case SCARD_AUTHENTICATION_FAILED_0:
return "Authentication failed, 0 retries left.";
case SCARD_AUTHENTICATION_FAILED_1:
return "Authentication failed, 1 retry left.";
case SCARD_AUTHENTICATION_FAILED_2:
return "Authentication failed, 2 retries left.";
case SCARD_AUTHENTICATION_FAILED_3:
return "Authentication failed, 3 retries left.";
case SCARD_AUTHENTICATION_FAILED_4:
return "Authentication failed, 4 retries left.";
case SCARD_AUTHENTICATION_FAILED_5:
return "Authentication failed, 5 retries left.";
case SCARD_AUTHENTICATION_FAILED_6:
return "Authentication failed, 6 retries left.";
case SCARD_AUTHENTICATION_FAILED_7:
return "Authentication failed, 7 retries left.";
case SCARD_AUTHENTICATION_FAILED_8:
return "Authentication failed, 8 retries left.";
case SCARD_AUTHENTICATION_FAILED_9:
return "Authentication failed, 9 retries left.";
case SCARD_AUTHENTICATION_FAILED_10:
return "Authentication failed, 10 retries left.";
case SCARD_AUTHENTICATION_FAILED_11:
return "Authentication failed, 11 retries left.";
case SCARD_AUTHENTICATION_FAILED_12:
return "Authentication failed, 12 retries left.";
case SCARD_AUTHENTICATION_FAILED_13:
return "Authentication failed, 13 retries left.";
case SCARD_AUTHENTICATION_FAILED_14:
return "Authentication failed, 14 retries left.";
case SCARD_AUTHENTICATION_FAILED_15:
return "Authentication failed, 15 retries left.";
case SCARD_EXECUTION_ERROR:
return "Execution error, state of non-volatile memory unchanged.";
case SCARD_CHANGED_ERROR:
return "Execution error, state of non-volatile memory changed.";
case SCARD_MEMORY_FAILURE:
return "Memory failure.";
case SCARD_LENGTH_INCORRECT:
return "The length is incorrect.";
case SCARD_CLA_UNSUPPORTED:
return "Functions in CLA not supported.";
case SCARD_LOGICAL_CHANNEL_UNSUPPORTED:
return "Logical channel not supported.";
case SCARD_SECURE_MESSAGING_UNSUPPORTED:
return "Secure messaging not supported.";
case SCARD_COMMAND_NOT_ALLOWED:
return "Command not allowed.";
case SCARD_COMMAND_INCOMPATIBLE:
return "Command incompatible with file structure.";
case SCARD_NOT_AUTHORIZED:
return "Security status not satisfied.";
case SCARD_AUTHENTICATION_BLOCKED:
return "Authentication method blocked.";
case SCARD_REFERENCED_DATA_INVALIDATED:
return "Referenced data invalidated.";
case SCARD_USE_CONDITIONS_NOT_MET:
return "Conditions of use not satisfied.";
case SCARD_NO_CURRENT_EF:
return "Command not allowed (no current EF).";
case SCARD_SM_DATA_OBJECTS_MISSING:
return "Expected SM data objects missing.";
case SCARD_SM_DATA_NOT_ALLOWED:
return "SM data objects incorrect.";
case SCARD_WRONG_PARAMETER:
return "Wrong parameter.";
case SCARD_DATA_INCORRECT:
return "Incorrect parameters in the data field.";
case SCARD_FUNCTION_NOT_SUPPORTED:
return "Function not supported.";
case SCARD_FILE_NOT_FOUND:
return "File not found.";
case SCARD_RECORD_NOT_FOUND:
return "Record not found.";
case SCARD_NO_MEMORY_LEFT:
return "Not enough memory space in the file.";
case SCARD_LC_INCONSISTENT_TLV:
return "Lc inconsistent with TLV structure.";
case SCARD_INCORRECT_P1_P2:
return "Incorrect parameters P1-P2.";
case SCARD_LC_INCONSISTENT_P1_P2:
return "Lc inconsistent with P1-P2.";
case SCARD_REFERENCED_DATA_NOT_FOUND:
return "Referenced data not found.";
case SCARD_WRONG_PARAMETER_P1_P2:
return "Wrong parameter(s) P1-P2.";
case SCARD_LE_IN_SW2:
return "Wrong length Le: SW2 indicates the exact length";
case SCARD_INSTRUCTION_CODE_INVALID:
return "The instruction code is not programmed or is invalid.";
case SCARD_INSTRUCTION_CLASS_UNSUPPORTED:
return "The card does not support the instruction class.";
case SCARD_UNSPECIFIED_ERROR:
return "No precise diagnostic is given.";
default:
return "Unknown error";
}
}
#endif //NDEBUG
} // end namespace Tokend
--- NEW FILE SCardError.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* SCardError.h
* TokendMuscle
*/
#ifndef _TOKEND_SCARDERROR_H_
#define _TOKEND_SCARDERROR_H_
#include <security_utilities/debugging.h>
#include <security_utilities/errors.h>
/* ISO/IEC 7816 part 3 and 4 error codes. */
/** success */
#define SCARD_SUCCESS 0x9000
/* '61XX' SW2 indicates the number of response bytes still available. */
#define SCARD_BYTES_LEFT_IN_SW2 0x6100
/* '62XX' Warning processings - State of non-volatile memory unchanged. */
/** Execution warning, state of non-volatile memory unchanged */
#define SCARD_EXECUTION_WARNING 0x6200
/** Part of returned data may be corrupted. */
#define SCARD_RETURNED_DATA_CORRUPTED 0x6281
/** End of file/record reached before reading Le bytes. */
#define SCARD_END_OF_FILE_REACHED 0x6282
/** Selected file invalidated. */
#define SCARD_FILE_INVALIDATED 0x6283
/** FCI not formatted according to 1.1.5. */
#define SCARD_FCI_INVALID 0x6284
/* '62XX' Warning processings - State of non-volatile memory changed. */
/** Authentication failed. */
#define SCARD_AUTHENTICATION_FAILED 0x6300
/** File filled up by the last write. */
#define SCARD_FILE_FILLED 0x6381
/** Authentication failed, 0 retries left. */
#define SCARD_AUTHENTICATION_FAILED_0 0x63C0
/** Authentication failed, 1 retry left. */
#define SCARD_AUTHENTICATION_FAILED_1 0x63C1
/** Authentication failed, 2 retries left. */
#define SCARD_AUTHENTICATION_FAILED_2 0x63C2
/** Authentication failed, 3 retries left. */
#define SCARD_AUTHENTICATION_FAILED_3 0x63C3
/** Authentication failed, 4 retries left. */
#define SCARD_AUTHENTICATION_FAILED_4 0x63C4
/** Authentication failed, 5 retries left. */
#define SCARD_AUTHENTICATION_FAILED_5 0x63C5
/** Authentication failed, 6 retries left. */
#define SCARD_AUTHENTICATION_FAILED_6 0x63C6
/** Authentication failed, 7 retries left. */
#define SCARD_AUTHENTICATION_FAILED_7 0x63C7
/** Authentication failed, 8 retries left. */
#define SCARD_AUTHENTICATION_FAILED_8 0x63C8
/** Authentication failed, 9 retries left. */
#define SCARD_AUTHENTICATION_FAILED_9 0x63C9
/** Authentication failed, 10 retries left. */
#define SCARD_AUTHENTICATION_FAILED_10 0x63CA
/** Authentication failed, 11 retries left. */
#define SCARD_AUTHENTICATION_FAILED_11 0x63CB
/** Authentication failed, 12 retries left. */
#define SCARD_AUTHENTICATION_FAILED_12 0x63CC
/** Authentication failed, 13 retries left. */
#define SCARD_AUTHENTICATION_FAILED_13 0x63CD
/** Authentication failed, 14 retries left. */
#define SCARD_AUTHENTICATION_FAILED_14 0x63CE
/** Authentication failed, 15 retries left. */
#define SCARD_AUTHENTICATION_FAILED_15 0x63CF
/* '64XX' Execution errors - State of non-volatile memory unchanged. */
/** Execution error, state of non-volatile memory unchanged. */
#define SCARD_EXECUTION_ERROR 0x6400
/* '65XX' Execution errors - State of non-volatile memory changed. */
/** Execution error, state of non-volatile memory changed. */
#define SCARD_CHANGED_ERROR 0x6500
/** Memory failure. */
#define SCARD_MEMORY_FAILURE 0x6581
/* '66XX' Reserved for security-related issues. */
/* '6700' Wrong length. */
/** The length is incorrect. */
#define SCARD_LENGTH_INCORRECT 0x6700
/* '68XX' Functions in CLA not supported. */
/** No information given. */
#define SCARD_CLA_UNSUPPORTED 0x6800
/** Logical channel not supported. */
#define SCARD_LOGICAL_CHANNEL_UNSUPPORTED 0x6881
/** Secure messaging not supported. */
#define SCARD_SECURE_MESSAGING_UNSUPPORTED 0x6882
/* '69XX' Command not allowed. */
/** Command not allowed. */
#define SCARD_COMMAND_NOT_ALLOWED 0x6900
/** Command incompatible with file structure. */
#define SCARD_COMMAND_INCOMPATIBLE 0x6981
/** Security status not satisfied. */
#define SCARD_NOT_AUTHORIZED 0x6982
/** Authentication method blocked. */
#define SCARD_AUTHENTICATION_BLOCKED 0x6983
/** Referenced data invalidated. */
#define SCARD_REFERENCED_DATA_INVALIDATED 0x6984
/** Conditions of use not satisfied. */
#define SCARD_USE_CONDITIONS_NOT_MET 0x6985
/** Command not allowed (no current EF). */
#define SCARD_NO_CURRENT_EF 0x6986
/** Expected SM data objects missing. */
#define SCARD_SM_DATA_OBJECTS_MISSING 0x6987
/** SM data objects incorrect. */
#define SCARD_SM_DATA_NOT_ALLOWED 0x6988
/* '6AXX' Wrong parameter(s) P1-P2. */
/** Wrong parameter. */
#define SCARD_WRONG_PARAMETER 0x6A00
/** Incorrect parameters in the data field. */
#define SCARD_DATA_INCORRECT 0x6A80
/** Function not supported. */
#define SCARD_FUNCTION_NOT_SUPPORTED 0x6A81
/** File not found. */
#define SCARD_FILE_NOT_FOUND 0x6A82
/** Record not found. */
#define SCARD_RECORD_NOT_FOUND 0x6A83
/** Not enough memory space in the file. */
#define SCARD_NO_MEMORY_LEFT 0x6A84
/** Lc inconsistent with TLV structure. */
#define SCARD_LC_INCONSISTENT_TLV 0x6A85
/** Incorrect parameters P1-P2. */
#define SCARD_INCORRECT_P1_P2 0x6A86
/** Lc inconsistent with P1-P2. */
#define SCARD_LC_INCONSISTENT_P1_P2 0x6A87
/** Referenced data not found. */
#define SCARD_REFERENCED_DATA_NOT_FOUND 0x6A88
/* '6B00' Wrong parameter(s) P1-P2. */
/** Wrong parameter(s) P1-P2. */
#define SCARD_WRONG_PARAMETER_P1_P2 0x6B00
/* '6CXX' Wrong length Le: SW2 indicates the exact length */
#define SCARD_LE_IN_SW2 0x6C00
/* '6D00' Instruction code not supported or invalid. */
/** The instruction code is not programmed or is invalid. */
#define SCARD_INSTRUCTION_CODE_INVALID 0x6D00
/* '6E00' Class not supported. */
/** The card does not support the instruction class. */
#define SCARD_INSTRUCTION_CLASS_UNSUPPORTED 0x6E00
/* '6F00' No precise diagnosis. */
/** No precise diagnostic is given. */
#define SCARD_UNSPECIFIED_ERROR 0x6F00
namespace Tokend
{
class SCardError : public Security::CommonError
{
protected:
SCardError(uint16_t sw);
public:
const uint16_t statusWord;
virtual OSStatus osStatus() const;
virtual int unixError() const;
virtual const char *what () const throw ();
static void check(uint16_t sw) { if (sw != SCARD_SUCCESS) throwMe(sw); }
static void throwMe(uint16_t sw) __attribute__((noreturn));
protected:
IFDEBUG(void debugDiagnose(const void *id) const;)
IFDEBUG(static const char *errorstr(uint16_t sw);)
};
} // end namespace Tokend
#endif /* !_TOKEND_SCARDERROR_H_ */
--- NEW FILE Schema.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* Schema.cpp
* TokendMuscle
*/
#include "Schema.h"
#include "Attribute.h"
#include "MetaRecord.h"
#include "MetaAttribute.h"
#include <Security/SecKey.h>
#include <Security/SecCertificate.h>
#include <Security/SecKeychainItem.h>
#include <Security/SecKeychainItemPriv.h>
#include <Security/cssmapple.h>
namespace Tokend
{
#pragma mark ---------------- Schema --------------
Schema::Schema() :
mTrueCoder(true),
mFalseCoder(false),
mCertEncodingBERCoder(CSSM_CERT_ENCODING(CSSM_CERT_ENCODING_BER)),
mSdCSPDLGuidCoder(gGuidAppleSdCSPDL),
mPublicKeyClassCoder(CSSM_KEYCLASS(CSSM_KEYCLASS_PUBLIC_KEY)),
mPrivateKeyClassCoder(CSSM_KEYCLASS(CSSM_KEYCLASS_PRIVATE_KEY)),
mSessionKeyClassCoder(CSSM_KEYCLASS(CSSM_KEYCLASS_SESSION_KEY))
{
}
Schema::~Schema()
{
try
{
for_each_map_delete(mRelationMap.begin(), mRelationMap.end());
}
catch(...) {}
}
void Schema::create()
{
// Attribute names.
std::string
an_RelationID("RelationID"),
an_RelationName("RelationName"),
an_AttributeID("AttributeID"),
an_AttributeNameFormat("AttributeNameFormat"),
an_AttributeName("AttributeName"),
an_AttributeNameID("AttributeNameID"),
an_AttributeFormat("AttributeFormat"),
an_IndexID("IndexID"),
an_IndexType("IndexType"),
an_IndexedDataLocation("IndexedDataLocation");
// Record the attributeIndex of each created attribute for use by our
// register functions laster on.
// Create CSSM_DL_DB_SCHEMA_INFO relation.
MetaRecord *mrio = new MetaRecord(CSSM_DL_DB_SCHEMA_INFO);
io_rid = mrio->createAttribute(an_RelationID,
kAF_UINT32).attributeIndex();
io_rn = mrio->createAttribute(an_RelationName,
kAF_STRING).attributeIndex();
mInfo = createRelation(mrio);
// Create CSSM_DL_DB_SCHEMA_ATTRIBUTES relation
MetaRecord *mras = new MetaRecord(CSSM_DL_DB_SCHEMA_ATTRIBUTES);
as_rid = mras->createAttribute(an_RelationID,
kAF_UINT32).attributeIndex();
as_aid = mras->createAttribute(an_AttributeID,
kAF_UINT32).attributeIndex();
as_anf = mras->createAttribute(an_AttributeNameFormat,
kAF_UINT32).attributeIndex();
as_an = mras->createAttribute(an_AttributeName,
kAF_STRING).attributeIndex();
as_anid= mras->createAttribute(an_AttributeNameID,
kAF_BLOB ).attributeIndex();
as_af = mras->createAttribute(an_AttributeFormat,
kAF_UINT32).attributeIndex();
mAttributes = createRelation(mras);
// Create CSSM_DL_DB_SCHEMA_INDEXES relation
MetaRecord *mrix = new MetaRecord(CSSM_DL_DB_SCHEMA_INDEXES);
ix_rid = mrix->createAttribute(an_RelationID,
kAF_UINT32).attributeIndex();
ix_iid = mrix->createAttribute(an_IndexID,
kAF_UINT32).attributeIndex();
ix_aid = mrix->createAttribute(an_AttributeID,
kAF_UINT32).attributeIndex();
ix_it = mrix->createAttribute(an_IndexType,
kAF_UINT32).attributeIndex();
ix_idl = mrix->createAttribute(an_IndexedDataLocation,
kAF_UINT32).attributeIndex();
mIndices = createRelation(mrix);
#ifdef ADD_SCHEMA_PARSING_MODULE
// @@@ Skipping CSSM_DL_DB_SCHEMA_PARSING_MODULE relation since no one uses
// it and it's definition in CDSA is broken anyway
// Attribute names.
std::string
an_ModuleID("ModuleID"),
an_AddinVersion("AddinVersion"),
an_SSID("SSID"),
an_SubserviceType("SubserviceType");
// Create CSSM_DL_DB_SCHEMA_PARSING_MODULE Relation
MetaRecord *mr_parsing = new MetaRecord(CSSM_DL_DB_SCHEMA_PARSING_MODULE);
mr_parsing->createAttribute(an_AttributeID, kAF_UINT32);
mr_parsing->createAttribute(an_ModuleID, kAF_BLOB );
mr_parsing->createAttribute(an_AddinVersion, kAF_STRING);
mr_parsing->createAttribute(an_SSID, kAF_UINT32);
mr_parsing->createAttribute(an_SubserviceType, kAF_UINT32);
createRelation(mr_parsing);
#endif
#ifdef REGISTER_SCHEMA_RELATIONS
registerRelation("CSSM_DL_DB_SCHEMA_INFO", CSSM_DL_DB_SCHEMA_INFO)
registerAttribute(CSSM_DL_DB_SCHEMA_INFO, &an_RelationID, 0,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INFO, &an_RelationName, 1,
kAF_UINT32, false);
registerRelation("CSSM_DL_DB_SCHEMA_ATTRIBUTES",
CSSM_DL_DB_SCHEMA_ATTRIBUTES)
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_RelationID, 0,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeID, 2,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeNameFormat, 3,
kAF_UINT32, false);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeName, 4,
kAF_STRING, false);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeNameId, 5,
kAF_BLOB, false);
registerAttribute(CSSM_DL_DB_SCHEMA_ATTRIBUTES, &an_AttributeFormat, 6,
kAF_UINT32, false);
registerRelation("CSSM_DL_DB_SCHEMA_INDEXES", CSSM_DL_DB_SCHEMA_INDEXES)
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_RelationID, 0,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexID, 1,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_AttributeID, 2,
kAF_UINT32, true);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexType, 3,
kAF_UINT32, false);
registerAttribute(CSSM_DL_DB_SCHEMA_INDEXES, &an_IndexedDataLocation, 4,
kAF_UINT32, false);
#endif
}
// Create one of the standard relations conforming to what the SecKeychain
// layer expects.
Relation *Schema::createStandardRelation(RelationId relationId)
{
std::string relationName;
// Get the name based on the relation
switch (relationId)
{
case CSSM_DL_DB_RECORD_PRIVATE_KEY:
relationName = "CSSM_DL_DB_RECORD_PRIVATE_KEY"; break;
case CSSM_DL_DB_RECORD_PUBLIC_KEY:
relationName = "CSSM_DL_DB_RECORD_PUBLIC_KEY"; break;
case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
relationName = "CSSM_DL_DB_RECORD_SYMMETRIC_KEY"; break;
case CSSM_DL_DB_RECORD_X509_CERTIFICATE:
relationName = "CSSM_DL_DB_RECORD_X509_CERTIFICATE"; break;
case CSSM_DL_DB_RECORD_GENERIC:
relationName = "CSSM_DL_DB_RECORD_GENERIC"; break;
default: CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
}
Relation *rt = createRelation(relationName, relationId);
std::string
an_CertType = "CertType",
an_CertEncoding = "CertEncoding",
an_PrintName = "PrintName",
an_Alias = "Alias",
an_Subject = "Subject",
an_Issuer = "Issuer",
an_SerialNumber = "SerialNumber",
an_SubjectKeyIdentifier = "SubjectKeyIdentifier",
an_PublicKeyHash = "PublicKeyHash",
an_KeyClass = "KeyClass",
an_Permanent = "Permanent",
an_Private = "Private",
an_Modifiable = "Modifiable",
an_Label = "Label",
an_ApplicationTag = "ApplicationTag",
an_KeyCreator = "KeyCreator",
an_KeyType = "KeyType",
an_KeySizeInBits = "KeySizeInBits",
an_EffectiveKeySize = "EffectiveKeySize",
an_StartDate = "StartDate",
an_EndDate = "EndDate",
an_Sensitive = "Sensitive",
an_AlwaysSensitive = "AlwaysSensitive",
an_Extractable = "Extractable",
an_NeverExtractable = "NeverExtractable",
an_Encrypt = "Encrypt",
an_Decrypt = "Decrypt",
an_Derive = "Derive",
an_Sign = "Sign",
an_Verify = "Verify",
an_SignRecover = "SignRecover",
an_VerifyRecover = "VerifyRecover",
an_Wrap = "Wrap",
an_Unwrap = "Unwrap";
// @@@ HARDWIRED Based on what SecKeychain layer expects @@@
switch (relationId)
{
case CSSM_DL_DB_RECORD_GENERIC:
createAttribute(*rt, &an_PrintName, kSecLabelItemAttr, kAF_BLOB, false)
.attributeCoder(&mDescriptionCoder);
createAttribute(*rt, &an_Alias, kSecAlias, kAF_BLOB, false)
.attributeCoder(&mZeroCoder);
rt->metaRecord().attributeCoderForData(&mDataAttributeCoder);
break;
case CSSM_DL_DB_RECORD_X509_CERTIFICATE:
createAttribute(*rt, &an_CertType, kSecCertTypeItemAttr,
kAF_UINT32, true).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_CertEncoding, kSecCertEncodingItemAttr,
kAF_UINT32, false).attributeCoder(&mCertEncodingBERCoder);
createAttribute(*rt, &an_PrintName, kSecLabelItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_Alias, kSecAlias,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_Subject, kSecSubjectItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_Issuer, kSecIssuerItemAttr,
kAF_BLOB, true).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_SerialNumber, kSecSerialNumberItemAttr,
kAF_BLOB, true).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_SubjectKeyIdentifier,
kSecSubjectKeyIdentifierItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
createAttribute(*rt, &an_PublicKeyHash, kSecPublicKeyHashItemAttr,
kAF_BLOB, false).attributeCoder(&mCertificateCoder);
rt->metaRecord().attributeCoderForData(&mDataAttributeCoder);
// Initialize mPublicKeyHashCoder so it knows which attribute of a
// certificate to use to get the public key hash of a key.
mPublicKeyHashCoder.setCertificateMetaAttribute(&(rt->metaRecord()
.metaAttribute(kSecPublicKeyHashItemAttr)));
break;
case CSSM_DL_DB_RECORD_PUBLIC_KEY:
case CSSM_DL_DB_RECORD_PRIVATE_KEY:
case CSSM_DL_DB_RECORD_SYMMETRIC_KEY:
rt->metaRecord().attributeCoderForData(&mKeyDataCoder);
createAttribute(*rt, &an_KeyClass, kSecKeyKeyClass,
kAF_UINT32, false).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY
? &mPublicKeyClassCoder
: relationId == CSSM_DL_DB_RECORD_PRIVATE_KEY
? &mPrivateKeyClassCoder
: &mSessionKeyClassCoder);
createAttribute(*rt, &an_PrintName, kSecKeyPrintName,
kAF_BLOB, false).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_Alias, kSecKeyAlias,
kAF_BLOB, false).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_Permanent, kSecKeyPermanent,
kAF_UINT32, false).attributeCoder(&mTrueCoder);
createAttribute(*rt, &an_Private, kSecKeyPrivate,
kAF_UINT32, false).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY
? &mFalseCoder : &mTrueCoder);
createAttribute(*rt, &an_Modifiable, kSecKeyModifiable,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_Label, kSecKeyLabel,
kAF_BLOB, true).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PRIVATE_KEY
? &mPublicKeyHashCoder : NULL);
createAttribute(*rt, &an_ApplicationTag, kSecKeyApplicationTag,
kAF_BLOB, true).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_KeyCreator, kSecKeyKeyCreator,
kAF_BLOB, true).attributeCoder(&mSdCSPDLGuidCoder);
createAttribute(*rt, &an_KeyType, kSecKeyKeyType, kAF_UINT32, true);
createAttribute(*rt, &an_KeySizeInBits, kSecKeyKeySizeInBits,
kAF_UINT32, true);
createAttribute(*rt, &an_EffectiveKeySize, kSecKeyEffectiveKeySize,
kAF_UINT32, true);
createAttribute(*rt, &an_StartDate, kSecKeyStartDate,
kAF_TIME_DATE, true).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_EndDate, kSecKeyEndDate,
kAF_TIME_DATE, true).attributeCoder(&mZeroCoder);
createAttribute(*rt, &an_Sensitive, kSecKeySensitive,
kAF_UINT32, false).attributeCoder(
relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY
? &mFalseCoder : &mTrueCoder);
createAttribute(*rt, &an_AlwaysSensitive, kSecKeyAlwaysSensitive,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_Extractable, kSecKeyExtractable,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_NeverExtractable, kSecKeyNeverExtractable,
kAF_UINT32, false).attributeCoder(&mFalseCoder);
createAttribute(*rt, &an_Encrypt, kSecKeyEncrypt, kAF_UINT32, false);
createAttribute(*rt, &an_Decrypt, kSecKeyDecrypt, kAF_UINT32, false);
createAttribute(*rt, &an_Derive, kSecKeyDerive, kAF_UINT32, false);
createAttribute(*rt, &an_Sign, kSecKeySign, kAF_UINT32, false);
createAttribute(*rt, &an_Verify, kSecKeyVerify, kAF_UINT32, false);
createAttribute(*rt, &an_SignRecover, kSecKeySignRecover,
kAF_UINT32, false);
createAttribute(*rt, &an_VerifyRecover, kSecKeyVerifyRecover,
kAF_UINT32, false);
createAttribute(*rt, &an_Wrap, kSecKeyWrap, kAF_UINT32, false);
createAttribute(*rt, &an_Unwrap, kSecKeyUnwrap, kAF_UINT32, false);
// Initialize mPublicKeyHashCoder so it knows which attribute of a
// public key to use to get the public key hash of a key.
if (relationId == CSSM_DL_DB_RECORD_PUBLIC_KEY)
mPublicKeyHashCoder.setPublicKeyMetaAttribute(&(rt->metaRecord()
.metaAttribute(kSecKeyLabel)));
break;
}
return rt;
}
// Create a new relation using metaRecord. Does not register this in the
// CSSM_DL_DB_SCHEMA_INFO relation. This is used for creating the schema
// relations themselves only.
Relation *Schema::createRelation(MetaRecord *metaRecord)
{
auto_ptr<Relation> aRelation(new Relation(metaRecord));
if (!mRelationMap.insert(RelationMap::value_type(metaRecord->relationId(),
aRelation.get())).second)
{
// @@@ Should be CSSMERR_DL_DUPLICATE_RECORDTYPE. Since that
// doesn't exist we report that the meta-relation's unique index would
// no longer be valid
CssmError::throwMe(CSSMERR_DL_INVALID_UNIQUE_INDEX_DATA);
}
return aRelation.release();
}
// Create a new relation and register this in the CSSM_DL_DB_SCHEMA_INFO
// relation.
Relation *Schema::createRelation(const std::string &relationName,
RelationId relationId)
{
MetaRecord *mr = new MetaRecord(relationId);
Relation *rt = createRelation(mr);
registerRelation(relationName, relationId);
return rt;
}
// Create a new attribute and register this with the schema. Do not use this
// for creating schema relations.
MetaAttribute &Schema::createAttribute(Relation &relation,
const std::string *name, uint32 attributeId,
CSSM_DB_ATTRIBUTE_FORMAT attributeFormat, bool isIndex)
{
MetaRecord &mr = relation.metaRecord();
registerAttribute(mr.relationId(), name, attributeId, attributeFormat,
isIndex);
return mr.createAttribute(name, NULL, attributeId, attributeFormat);
}
// Insert a record containing a relationId and it's name into
// CSSM_DL_DB_SCHEMA_INFO relation
void Schema::registerRelation(const std::string &relationName,
RelationId relationId)
{
RefPointer<Record> record = new Record();
record->attributeAtIndex(io_rid, new Attribute(relationId));
record->attributeAtIndex(io_rn, new Attribute(relationName));
mInfo->insertRecord(record);
}
// Insert a record containing a relationId, attributeId and other meta
// information into the CSSM_DL_DB_SCHEMA_ATTRIBUTES relation. In addition, if
// isIndex is true insert a record into the CSSM_DL_DB_SCHEMA_INDEXES relation.
void Schema::registerAttribute(RelationId relationId, const std::string *name,
uint32 attributeId, CSSM_DB_ATTRIBUTE_FORMAT attributeFormat, bool isIndex)
{
CSSM_DB_ATTRIBUTE_NAME_FORMAT nameFormat = name
? CSSM_DB_ATTRIBUTE_NAME_AS_STRING : CSSM_DB_ATTRIBUTE_NAME_AS_INTEGER;
RefPointer<Record> rc_attribute = new Record();
rc_attribute->attributeAtIndex(as_rid, new Attribute(relationId));
rc_attribute->attributeAtIndex(as_aid, new Attribute(attributeId));
rc_attribute->attributeAtIndex(as_anf, new Attribute(nameFormat));
rc_attribute->attributeAtIndex(as_an, name
? new Attribute(*name) : new Attribute()); // AttributeName
rc_attribute->attributeAtIndex(as_anid, new Attribute());// AttributeNameId
rc_attribute->attributeAtIndex(as_af, new Attribute(attributeFormat));
mAttributes->insertRecord(rc_attribute);
if (isIndex)
{
RefPointer<Record> rc_index = new Record();
rc_index->attributeAtIndex(ix_rid, // RelationId
new Attribute(relationId));
rc_index->attributeAtIndex(ix_iid, // IndexId
new Attribute(uint32(0)));
rc_index->attributeAtIndex(ix_aid, // AttributeId
new Attribute(attributeId));
rc_index->attributeAtIndex(ix_it, // IndexType
new Attribute(uint32(CSSM_DB_INDEX_UNIQUE)));
rc_index->attributeAtIndex(ix_idl, // IndexedDataLocation
new Attribute(uint32(CSSM_DB_INDEX_ON_UNKNOWN)));
mIndices->insertRecord(rc_index);
}
}
#pragma mark ---------------- Utility methods --------------
const Relation &Schema::findRelation(RelationId inRelationId) const
{
RelationMap::const_iterator it = mRelationMap.find(inRelationId);
if (it == mRelationMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
return *it->second;
}
Relation &Schema::findRelation(RelationId inRelationId)
{
RelationMap::iterator it = mRelationMap.find(inRelationId);
if (it == mRelationMap.end())
CssmError::throwMe(CSSMERR_DL_INVALID_RECORDTYPE);
return *it->second;
}
MetaRecord &Schema::findMetaRecord(RelationId inRelationId)
{
return findRelation(inRelationId).metaRecord();
}
} // end namespace Tokend
--- NEW FILE Schema.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Schema.h
* TokendMuscle
*/
#ifndef _TOKEND_SCHEMA_H_
#define _TOKEND_SCHEMA_H_
#include <security_cdsa_utilities/cssmdata.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <map>
#include "MetaRecord.h"
#include "Relation.h"
#include "AttributeCoder.h"
namespace Tokend
{
class Relation;
//
// Schema
//
class Schema
{
NOCOPY(Schema)
public:
typedef std::map<RelationId, Relation *> RelationMap;
typedef RelationMap::const_iterator ConstRelationMapIterator;
Schema();
virtual ~Schema();
virtual void create();
const Relation &findRelation(RelationId inRelationId) const;
Relation &findRelation(RelationId inRelationId);
MetaRecord &findMetaRecord(RelationId inRelationId);
ConstRelationMapIterator begin() const { return mRelationMap.begin(); }
ConstRelationMapIterator end() const { return mRelationMap.end(); }
const LinkedRecordAttributeCoder &publicKeyHashCoder() const
{ return mPublicKeyHashCoder; }
protected:
Relation *createRelation(const std::string &relationName,
RelationId relationId);
Relation *createStandardRelation(RelationId relationId);
MetaAttribute &createAttribute(Relation &relation,
const std::string *name, uint32 attributeId,
CSSM_DB_ATTRIBUTE_FORMAT attributeFormat, bool isIndex);
private:
Relation *createRelation(MetaRecord *inMetaRecord);
void registerRelation(const std::string &relationName,
RelationId relationId);
void registerAttribute(RelationId relationId, const std::string *name,
uint32 attributeId, CSSM_DB_ATTRIBUTE_FORMAT attributeFormat,
bool isIndex);
private:
Relation *mInfo, *mAttributes, *mIndices;
RelationMap mRelationMap;
// AttributeIndices for attributes of CSSM_DL_DB_SCHEMA_INFO relation.
uint32 io_rid;
uint32 io_rn;
// AttributeIndices for attributes of CSSM_DL_DB_SCHEMA_ATTRIBUTES
// relation.
uint32 as_rid;
uint32 as_aid;
uint32 as_anf;
uint32 as_an;
uint32 as_anid;
uint32 as_af;
// AttributeIndices for attributes of CSSM_DL_DB_SCHEMA_INDEXES relation.
uint32 ix_rid;
uint32 ix_iid;
uint32 ix_aid;
uint32 ix_it;
uint32 ix_idl;
protected:
// Coders for some standard attributes
ConstAttributeCoder mTrueCoder;
ConstAttributeCoder mFalseCoder;
ConstAttributeCoder mCertEncodingBERCoder;
GuidAttributeCoder mSdCSPDLGuidCoder;
CertificateAttributeCoder mCertificateCoder;
ZeroAttributeCoder mZeroCoder;
ConstAttributeCoder mPublicKeyClassCoder;
ConstAttributeCoder mPrivateKeyClassCoder;
ConstAttributeCoder mSessionKeyClassCoder;
KeyDataAttributeCoder mKeyDataCoder;
LinkedRecordAttributeCoder mPublicKeyHashCoder;
DataAttributeCoder mDataAttributeCoder;
DescriptionAttributeCoder mDescriptionCoder;
};
} // end namespace Tokend
#endif /* !_TOKEND_SCHEMA_H_ */
--- NEW FILE SelectionPredicate.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* SelectionPredicate.cpp
* TokendMuscle
*/
#include "SelectionPredicate.h"
#include "MetaAttribute.h"
#include "MetaRecord.h"
#include "DbValue.h"
#include <Security/cssmerr.h>
namespace Tokend
{
SelectionPredicate::SelectionPredicate(const MetaRecord &inMetaRecord,
const CSSM_SELECTION_PREDICATE &inPredicate)
: mMetaAttribute(inMetaRecord.metaAttribute(inPredicate.Attribute.Info)),
mDbOperator(inPredicate.DbOperator)
{
// Make sure that the caller specified the attribute values in the correct
// format.
if (inPredicate.Attribute.Info.AttributeFormat
!= mMetaAttribute.attributeFormat())
CssmError::throwMe(CSSMERR_DL_INCOMPATIBLE_FIELD_FORMAT);
// @@@ See ISSUES
if (inPredicate.Attribute.NumberOfValues != 1)
CssmError::throwMe(CSSMERR_DL_UNSUPPORTED_QUERY);
mData = inPredicate.Attribute.Value[0];
mValue = mMetaAttribute.createValue(mData);
}
SelectionPredicate::~SelectionPredicate()
{
delete mValue;
}
bool SelectionPredicate::evaluate(TokenContext *tokenContext,
Record& record) const
{
return mMetaAttribute.evaluate(tokenContext, mValue, record, mDbOperator);
}
} // end namespace Tokend
--- NEW FILE SelectionPredicate.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* SelectionPredicate.h
* TokendMuscle
*/
#ifndef _TOKEND_SELECTIONPREDICATE_H_
#define _TOKEND_SELECTIONPREDICATE_H_
#include <security_cdsa_utilities/cssmdata.h>
namespace Tokend
{
class DbValue;
class MetaAttribute;
class MetaRecord;
class Record;
class TokenContext;
class SelectionPredicate
{
NOCOPY(SelectionPredicate)
public:
SelectionPredicate(const MetaRecord &inMetaRecord,
const CSSM_SELECTION_PREDICATE &inPredicate);
~SelectionPredicate();
bool evaluate(TokenContext *tokenContext, Record& record) const;
private:
const MetaAttribute &mMetaAttribute;
CSSM_DB_OPERATOR mDbOperator;
CssmDataContainer mData;
DbValue *mValue;
};
} // end namespace Tokend
#endif /* !_TOKEND_SELECTIONPREDICATE_H_ */
--- NEW FILE Token.cpp ---
/*
* Copyright (c) 2004,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@
*/
/*
* Token.cpp
* TokendMuscle
*/
#include "Token.h"
#include "Cursor.h"
#include "KeyHandle.h"
#include "RecordHandle.h"
#include "Schema.h"
#include <memory>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_utilities/unix++.h>
#include <security_utilities/logging.h>
//
// SPI wrapper macros
//
#define BEGIN try {
#define END(SS) \
return CSSM_OK; \
} catch (const CommonError &err) { \
return CssmError::cssmError(err, CSSM_##SS##_BASE_ERROR); \
} catch (...) { \
return CSSM_ERRCODE_INTERNAL_ERROR; \
}
//
// Singleton
//
Tokend::Token *token;
namespace Tokend
{
Token::Token() : mSchema(NULL), mTokenContext(NULL)
{
}
Token::~Token()
{
}
//
// Initial: Your first chance to do anything with the tokend framework
// initialized.
//
CSSM_RETURN Token::_initial()
{
BEGIN
token->initial();
secdebug("tokend", "using reader %s",
token->startupReaderInfo()->szReader);
END(CSSM)
}
//
// Probe:
// (1) See if we support this token. Return zero if not.
// Return a score if we do - the lower, the better. 1 beats everyone else.
// (2) Generate a unique id string for the token. This doesn't have to be
// human readable. If you REALLY can't make one up, leave tokenUid alone.
// But do try.
//
CSSM_RETURN Token::_probe(SecTokendProbeFlags flags, uint32 *score,
char tokenUid[TOKEND_MAX_UID])
{
BEGIN
*score = token->probe(flags, tokenUid);
secdebug("tokend", "flags=%d returning score=%d uid='%s'",
flags, *score, tokenUid);
END(CSSM)
}
//
// Establish:
// Okay, you're the one. The token is yours. Here's your GUID and subservice ID
// (in case you care); it'll get automatically inserted into your MDS unless
// you override it. If you can make up a nice, user-friendly print name for
// your token, return it in printName. If you can't, leave it alone and
// securityd will make something up for you.
//
CSSM_RETURN Token::_establish(const CSSM_GUID *guid, uint32 subserviceID,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
BEGIN
secdebug("tokend", "establish(%s,%d,0x%X)",
Guid::required(guid).toString().c_str(), subserviceID, flags);
token->establish(guid, subserviceID, flags, cacheDirectory, workDirectory,
mdsDirectory, printName);
// if printName is left alone, securityd will make one up
// if mdsDirectory is left alone, all MDS resources in the Resource bundle
// will be loaded
END(CSSM)
}
//
// Terminate() is called by security when it wants you to go away.
// This function does not (currently) return anything, so the CSSM_RETURN is
// effectively ignored. (It's still here for consistency's sake.)
//
CSSM_RETURN Token::_terminate(uint32 reason, uint32 options)
{
BEGIN
secdebug("tokend", "terminate(%d,0x%d)", reason, options);
token->terminate(reason, options);
END(CSSM)
}
CSSM_RETURN Token::_findFirst(const CSSM_QUERY *query,
TOKEND_RETURN_DATA *data, CSSM_HANDLE *hSearch)
{
BEGIN
std::auto_ptr<Cursor> curs(token->createCursor(query));
TokenContext *tokenContext = token->tokenContext();
std::auto_ptr<RecordHandle> rh(curs->next(tokenContext));
if (!rh.get())
{
#if 1
data->record = 0;
data->keyhandle = 0;
return 0;
#else
return CSSMERR_DL_ENDOFDATA;
#endif
}
rh->get(tokenContext, *data);
// Release the RecordHandle until the caller kills the handle we returned.
rh.release();
// We didn't throw so return a search handle and keep the Cursor around.
*hSearch = curs->handle();
curs.release();
END(DL)
}
CSSM_RETURN Token::_findNext(CSSM_HANDLE hSearch, TOKEND_RETURN_DATA *data)
{
BEGIN
Cursor& curs = Security::HandleObject::find<Cursor>(hSearch,
CSSMERR_DL_RECORD_NOT_FOUND);
TokenContext *tokenContext = token->tokenContext();
std::auto_ptr<RecordHandle> rh(curs.next(tokenContext));
if (!rh.get())
{
secdebug("tokend", "findNext(%ld) returning: CSSMERR_DL_ENDOFDATA",
hSearch);
#if 1
data->record = 0;
data->keyhandle = 0;
return 0;
#else
return CSSMERR_DL_ENDOFDATA;
#endif
}
rh->get(tokenContext, *data);
rh.release();
END(DL)
}
CSSM_RETURN Token::_findRecordHandle(CSSM_HANDLE hRecord,
TOKEND_RETURN_DATA *data)
{
BEGIN
secdebug("tokend", "findRecordHandle(%ld)", hRecord);
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.get(token->tokenContext(), *data);
END(DL)
}
CSSM_RETURN Token::_insertRecord(CSSM_DB_RECORDTYPE recordType,
const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, const CSSM_DATA *data,
CSSM_HANDLE *hRecord)
{
BEGIN
secdebug("tokend", "insertRecord");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(DL)
}
CSSM_RETURN Token::_modifyRecord(CSSM_DB_RECORDTYPE recordType,
CSSM_HANDLE *hRecord, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
const CSSM_DATA *data, CSSM_DB_MODIFY_MODE modifyMode)
{
BEGIN
secdebug("tokend", "modifyRecord");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(DL)
}
CSSM_RETURN Token::_deleteRecord(CSSM_HANDLE hRecord)
{
BEGIN
secdebug("tokend", "deleteRecord");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(DL)
}
CSSM_RETURN Token::_releaseSearch(CSSM_HANDLE hSearch)
{
BEGIN
secdebug("tokend", "releaseSearch(%ld)", hSearch);
Security::HandleObject::findAndKill<Cursor>(hSearch,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
END(DL)
}
CSSM_RETURN Token::_releaseRecord(CSSM_HANDLE hRecord)
{
BEGIN
secdebug("tokend", "releaseRecord(%ld)", hRecord);
Security::HandleObject::findAndKill<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
END(DL)
}
CSSM_RETURN Token::_freeRetrievedData(TOKEND_RETURN_DATA *data)
{
BEGIN
secdebug("tokend", "freeRetrievedData");
// Since we return pointers to our cached interal data this is also a noop
END(DL)
}
CSSM_RETURN Token::_releaseKey(CSSM_HANDLE hKey)
{
BEGIN
secdebug("tokend", "releaseKey(%ld)", hKey);
Security::HandleObject::findAndKill<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
END(CSP)
}
CSSM_RETURN Token::_getKeySize(CSSM_HANDLE hKey, CSSM_KEY_SIZE *size)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.getKeySize(Required(size));
END(CSP)
}
CSSM_RETURN Token::_getOutputSize(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, uint32 inputSize, CSSM_BOOL encrypting,
uint32 *outputSize)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
Required(outputSize) = key.getOutputSize(Context::required(context),
inputSize, encrypting);
END(CSP)
}
CSSM_RETURN Token::_generateSignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
CSSM_DATA *signature)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.generateSignature(Context::required(context), signOnly,
CssmData::required(input), CssmData::required(signature));
END(CSP)
}
CSSM_RETURN Token::_verifySignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
const CSSM_DATA *signature)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.verifySignature(Context::required(context), signOnly,
CssmData::required(input), CssmData::required(signature));
END(CSP)
}
CSSM_RETURN Token::_generateMac(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *input, CSSM_DATA *output)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.generateMac(Context::required(context), CssmData::required(input),
CssmData::required(output));
END(CSP)
}
CSSM_RETURN Token::_verifyMac(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *input, const CSSM_DATA *compare)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.verifyMac(Context::required(context), CssmData::required(input),
CssmData::required(compare));
END(CSP)
}
CSSM_RETURN Token::_encrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *clear, CSSM_DATA *cipher)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.encrypt(Context::required(context), CssmData::required(clear),
CssmData::required(cipher));
END(CSP)
}
CSSM_RETURN Token::_decrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *cipher, CSSM_DATA *clear)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.decrypt(Context::required(context), CssmData::required(cipher),
CssmData::required(clear));
END(CSP)
}
CSSM_RETURN Token::_generateKey(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attrs, CSSM_HANDLE *hKey, CSSM_KEY *header)
{
BEGIN
secdebug("tokend", "generateKey");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(CSP)
}
CSSM_RETURN Token::_generateKeyPair(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner,
CSSM_KEYUSE pubUsage, CSSM_KEYATTR_FLAGS pubAttrs,
CSSM_KEYUSE privUsage, CSSM_KEYATTR_FLAGS privAttrs,
CSSM_HANDLE *hPubKey, CSSM_KEY *pubHeader,
CSSM_HANDLE *hPrivKey, CSSM_KEY *privHeader)
{
BEGIN
secdebug("tokend", "generateKeyPair");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(CSP)
}
CSSM_RETURN Token::_wrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
CSSM_HANDLE hSubjectKey, const CSSM_KEY *subjectKey,
const CSSM_DATA *descriptiveData, CSSM_KEY *wrappedKey)
{
BEGIN
KeyHandle *subjectKeyHandle = hSubjectKey
? &Security::HandleObject::find<KeyHandle>(hSubjectKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE) : NULL;
KeyHandle *wrappingKeyHandle = hWrappingKey
? &Security::HandleObject::find<KeyHandle>(hWrappingKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE) : NULL;
if (subjectKeyHandle)
{
subjectKeyHandle->wrapUsingKey(Context::required(context),
AccessCredentials::optional(cred),
wrappingKeyHandle, CssmKey::optional(wrappingKey),
CssmData::optional(descriptiveData),
CssmKey::required(wrappedKey));
}
else if (wrappingKeyHandle)
{
wrappingKeyHandle->wrapKey(Context::required(context),
CssmKey::required(subjectKey),
CssmData::optional(descriptiveData),
CssmKey::required(wrappedKey));
}
else
{
secdebug("tokend",
"wrapKey without a reference subject or wrapping key not supported"
);
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
END(CSP)
}
CSSM_RETURN Token::_unwrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access,
CSSM_HANDLE hPublicKey, const CSSM_KEY *publicKey,
const CSSM_KEY *wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CSSM_DATA *descriptiveData,
CSSM_HANDLE *hUnwrappedKey, CSSM_KEY *unwrappedKey)
{
BEGIN
if (hWrappingKey)
{
KeyHandle &unwrappingKey =
Security::HandleObject::find<KeyHandle>(hWrappingKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
if (hPublicKey)
{
secdebug("tokend", "unwrapKey with a public key not supported");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
unwrappingKey.unwrapKey(Context::required(context),
AccessCredentials::optional(cred),
AclEntryPrototype::optional(access), CssmKey::required(wrappedKey),
usage, attributes, CssmData::optional(descriptiveData),
*hUnwrappedKey, CssmKey::required(unwrappedKey));
}
else
{
secdebug("tokend",
"unwrapKey without a wrapping key not supported (import)");
/* There is no key doing the unwrap so this is basically an import. */
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
END(CSP)
}
CSSM_RETURN Token::_deriveKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hSourceKey, const CSSM_KEY *sourceKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access, CSSM_DATA *parameters,
CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attributes,
CSSM_HANDLE *hKey, CSSM_KEY *key)
{
BEGIN
secdebug("tokend", "deriveKey");
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
END(CSP)
}
CSSM_RETURN Token::_getObjectOwner(CSSM_HANDLE hRecord,
CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "getObjectOwner");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.getOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_getObjectAcl(CSSM_HANDLE hRecord,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries)
{
BEGIN
secdebug("tokend", "getObjectAcl");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.getAcl(tag, Required(count), AclEntryInfo::overlayVar(*entries));
END(DL)
}
CSSM_RETURN Token::_getDatabaseOwner(CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
token->getOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_getDatabaseAcl(const char *tag, uint32 *count,
CSSM_ACL_ENTRY_INFO **entries)
{
BEGIN
token->getAcl(tag, *count, AclEntryInfo::overlayVar(*entries));
END(DL)
}
CSSM_RETURN Token::_getKeyOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.getOwner(AclOwnerPrototype::required(owner));
END(CSP)
}
CSSM_RETURN Token::_getKeyAcl(CSSM_HANDLE hKey,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries)
{
BEGIN
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.getAcl(tag, Required(count), AclEntryInfo::overlayVar(*entries));
END(CSP)
}
CSSM_RETURN Token::_freeOwnerData(CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
// @@@ Do something here based on how we return data above.
END(CSP)
}
CSSM_RETURN Token::_freeAclData(uint32 count, CSSM_ACL_ENTRY_INFO *entries)
{
BEGIN
#if 0
AutoAclEntryInfoList aclList(&Allocator::standard());
// Invoke braindead overloaded operators since there are no setters on
// AutoAclEntryInfoList
*static_cast<uint32 *>(aclList) = count;
*static_cast<CSSM_ACL_ENTRY_INFO_PTR *>(aclList) = entries;
#endif
END(CSP)
}
CSSM_RETURN Token::_authenticateDatabase(CSSM_DB_ACCESS_TYPE mode,
const CSSM_ACCESS_CREDENTIALS *cred)
{
BEGIN
secdebug("tokend", "authenticateDatabase");
token->authenticate(mode, AccessCredentials::overlay(cred));
END(DL)
}
CSSM_RETURN Token::_changeDatabaseOwner(const CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "changeDatabaseOwner");
token->changeOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_changeDatabaseAcl(const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_EDIT *edit)
{
BEGIN
secdebug("tokend", "changeDatabaseAcl");
token->changeAcl(AccessCredentials::required(cred),
AclEdit::required(edit));
END(DL)
}
CSSM_RETURN Token::_changeObjectOwner(CSSM_HANDLE hRecord,
const CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "changeObjectOwner");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.changeOwner(AclOwnerPrototype::required(owner));
END(DL)
}
CSSM_RETURN Token::_changeObjectAcl(CSSM_HANDLE hRecord,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit)
{
BEGIN
secdebug("tokend", "changeObjectAcl");
RecordHandle &rh = Security::HandleObject::find<RecordHandle>(hRecord,
CSSMERR_CSSM_INVALID_ADDIN_HANDLE);
rh.changeAcl(AccessCredentials::required(cred), AclEdit::required(edit));
END(DL)
}
CSSM_RETURN Token::_changeKeyOwner(CSSM_HANDLE hKey,
const CSSM_ACL_OWNER_PROTOTYPE *owner)
{
BEGIN
secdebug("tokend", "changeKeyOwner");
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.changeOwner(AclOwnerPrototype::required(owner));
END(CSP)
}
CSSM_RETURN Token::_changeKeyAcl(CSSM_HANDLE hKey,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit)
{
BEGIN
secdebug("tokend", "changeKeyAcl");
KeyHandle &key = Security::HandleObject::find<KeyHandle>(hKey,
CSSMERR_CSP_INVALID_KEY_REFERENCE);
key.changeAcl(AccessCredentials::required(cred), AclEdit::required(edit));
END(CSP)
}
CSSM_RETURN Token::_generateRandom(const CSSM_CONTEXT *context,
CSSM_DATA *result)
{
BEGIN
secdebug("tokend", "generateRandom");
token->generateRandom(Context::required(context),
CssmData::required(result));
END(CSP)
}
CSSM_RETURN Token::_getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS *result)
{
BEGIN
secdebug("tokend", "getStatistics");
token->getStatistics(Required(result));
END(CSP)
}
CSSM_RETURN Token::_getTime(CSSM_ALGORITHMS algorithm, CSSM_DATA *result)
{
BEGIN
secdebug("tokend", "getTime");
token->getTime(algorithm, CssmData::required(result));
END(CSP)
}
CSSM_RETURN Token::_getCounter(CSSM_DATA *result)
{
BEGIN
secdebug("tokend", "getCounter");
token->getCounter(CssmData::required(result));
END(CSP)
}
CSSM_RETURN Token::_selfVerify()
{
BEGIN
secdebug("tokend", "selfVerify");
token->selfVerify();
END(CSP)
}
CSSM_RETURN Token::_cspPassThrough(uint32 id, const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_KEY *key, const CSSM_DATA *input,
CSSM_DATA *output)
{
BEGIN
secdebug("tokend", "cspPassThrough");
CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID);
END(CSP)
}
CSSM_RETURN Token::_dlPassThrough(uint32 id, const CSSM_DATA *input,
CSSM_DATA *output)
{
BEGIN
secdebug("tokend", "dlPassThrough");
CssmError::throwMe(CSSM_ERRCODE_INVALID_PASSTHROUGH_ID);
END(DL)
}
CSSM_RETURN Token::_isLocked(uint32 *locked)
{
BEGIN
secdebug("tokend", "_isLocked");
Required(locked) = token->isLocked();
secdebug("tokend", "_isLocked: ", *locked);
END(DL)
}
//
// Callback vector into SecTokendMain
//
const SecTokendCallbacks Token::mCallbacks = {
kSecTokendCallbackVersion,
kSecTokendCallbacksDefault,
_initial, _probe, _establish, _terminate,
_findFirst, _findNext, _findRecordHandle,
_insertRecord, _modifyRecord, _deleteRecord,
_releaseSearch, _releaseRecord,
_freeRetrievedData,
_releaseKey, _getKeySize, _getOutputSize,
_generateSignature, _verifySignature,
_generateMac, _verifyMac,
_encrypt, _decrypt,
_generateKey, _generateKeyPair,
_wrapKey, _unwrapKey, _deriveKey,
_getDatabaseOwner, _getDatabaseAcl,
_getObjectOwner, _getObjectAcl,
_getKeyOwner, _getKeyAcl,
_freeOwnerData, _freeAclData,
_authenticateDatabase,
_changeDatabaseOwner, _changeDatabaseAcl,
_changeObjectOwner, _changeObjectAcl,
_changeKeyOwner, _changeKeyAcl,
_generateRandom, _getStatistics,
_getTime, _getCounter,
_selfVerify,
_cspPassThrough, _dlPassThrough,
_isLocked
};
const SecTokendCallbacks *Token::callbacks()
{
return &mCallbacks;
}
SecTokendSupport *Token::support()
{
return this;
}
void Token::initial()
{
}
void Token::terminate(uint32 reason, uint32 options)
{
}
void Token::establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
secdebug("establish", "cacheDirectory %s", cacheDirectory);
mGuid = *guid;
mSubserviceId = subserviceId;
mCacheDirectory = cacheDirectory;
}
bool Token::cachedObject(CSSM_DB_RECORDTYPE relationId,
const std::string &name, CssmData &object) const
{
try
{
UnixPlusPlus::AutoFileDesc fd(cachedObjectPath(relationId, name));
object.Length = fd.fileSize();
object.Data = reinterpret_cast<uint8 *>(malloc(object.Length));
object.Length = fd.readAll(object.Data, object.Length);
}
catch (const UnixError &error)
{
return false;
}
return true;
}
void Token::cacheObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
const CssmData &object) const
{
std::string path(cachedObjectPath(relationId, name));
try
{
UnixPlusPlus::AutoFileDesc fd(path, O_WRONLY|O_CREAT|O_TRUNC);
fd.writeAll(object.Data, object.Length);
}
catch (const UnixError &e)
{
Syslog::error("error writing cache file: %s: %s\n", path.c_str(),
strerror(e.unixError()));
::unlink(path.c_str());
}
}
std::string Token::cachedObjectPath(CSSM_DB_RECORDTYPE relationId,
const std::string &name) const
{
char buffer[9];
sprintf(buffer, "%X", relationId);
return mCacheDirectory + "/" + buffer + "-" + name;
}
Cursor *Token::createCursor(const CSSM_QUERY *inQuery)
{
if (!inQuery || inQuery->RecordType == CSSM_DL_DB_RECORD_ANY
|| inQuery->RecordType == CSSM_DL_DB_RECORD_ALL_KEYS)
{
return new MultiCursor(inQuery, *mSchema);
}
const Relation &relation = mSchema->findRelation(inQuery->RecordType);
return new LinearCursor(inQuery, relation);
}
//
// Authenticate to the token
//
void Token::authenticate(CSSM_DB_ACCESS_TYPE mode,
const AccessCredentials *cred)
{
int pinNum = pinFromAclTag(cred->EntryTag);
if (!pinNum || !cred)
pinNum = -1; // No PIN in tag.
if (mode == CSSM_DB_ACCESS_RESET)
{
// A mode of CSSM_DB_ACCESS_RESET is a request to deauthenticate
// the card completely.
secdebug("authenticate", "unverifying PIN%d", pinNum);
return unverifyPIN(pinNum);
}
else if (cred && pinNum > 0)
{ // tag="PINk"; unlock a PIN
if (cred->size() != 1) // just one, please
CssmError::throwMe(CSSM_ERRCODE_INVALID_SAMPLE_VALUE);
const TypedList &sample = (*cred)[0];
switch (sample.type())
{
case CSSM_SAMPLE_TYPE_PASSWORD:
case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD:
case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD:
{
CssmData &pin = sample[1].data();
return verifyPIN(pinNum, pin.Data, pin.Length);
}
default:
break;
}
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
else
secdebug("authenticate", "ignoring non-PIN authentication request");
}
void Token::changeOwner(const AclOwnerPrototype &owner)
{
// Default changeOwner on a token always fails.
CssmError::throwMe(CSSM_ERRCODE_OBJECT_MANIP_AUTH_DENIED);
}
void Token::changeAcl(const AccessCredentials &cred, const AclEdit &edit)
{
// We don't allow adding or deleting of acls currently
switch (edit.mode())
{
case CSSM_ACL_EDIT_MODE_DELETE:
CssmError::throwMe(CSSM_ERRCODE_ACL_DELETE_FAILED);
case CSSM_ACL_EDIT_MODE_REPLACE:
break;
case CSSM_ACL_EDIT_MODE_ADD:
CssmError::throwMe(CSSM_ERRCODE_ACL_ADD_FAILED);
default:
CssmError::throwMe(CSSM_ERRCODE_INVALID_ACL_EDIT_MODE);
}
#if 0
// edit.handle() is the offset in mAclEntries of the acl we are replacing
uint32 ix = edit.handle();
if (ix >= mAclEntries.size())
CssmError::throwMe(CSSM_ERRCODE_ACL_REPLACE_FAILED);
// Now we have the actual AclEntryPrototype being changed
const AclEntryPrototype &oldProto = mAclEntries.at(ix).proto();
#endif
// Now get the new AclEntryPrototype for this entry.
const AclEntryInput *newEntry = edit.newEntry();
if (!newEntry)
CssmError::throwMe(CSSM_ERRCODE_INVALID_INPUT_POINTER);
const AclEntryPrototype &newProto = newEntry->proto();
unsigned int pinNum = pinFromAclTag(newProto.EntryTag);
if (!pinNum)
CssmError::throwMe(CSSM_ERRCODE_OBJECT_ACL_NOT_SUPPORTED);
const TypedList &subject = newProto.subject();
switch (subject.type())
{
case CSSM_ACL_SUBJECT_TYPE_PASSWORD:
case CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD:
case CSSM_ACL_SUBJECT_TYPE_PROTECTED_PASSWORD:
break;
default:
CssmError::throwMe(CSSM_ERRCODE_ACL_SUBJECT_TYPE_NOT_SUPPORTED);
}
const CssmData &newPin = subject[1].data();
if (cred.size() != 1)
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
const TypedList &value = cred[0].value();
switch (value.type())
{
case CSSM_SAMPLE_TYPE_PASSWORD:
case CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD:
case CSSM_SAMPLE_TYPE_PROTECTED_PASSWORD:
break;
default:
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
const CssmData &oldPin = value[1].data();
secdebug("tokend", "CHANGE PIN%d from \"%.*s\" to \"%.*s\"",
pinNum, static_cast<int>(oldPin.Length), oldPin.Data,
static_cast<int>(newPin.Length), newPin.Data);
changePIN(pinNum, oldPin.Data, oldPin.Length, newPin.Data, newPin.Length);
}
void Token::generateRandom(const Context &context, CssmData &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::getTime(CSSM_ALGORITHMS algorithm, CssmData &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::getCounter(CssmData &result)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::selfVerify()
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength)
{
// Default changePIN on a token always fails.
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
uint32_t Token::pinStatus(int pinNum)
{
CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
}
void Token::verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength)
{
CssmError::throwMe(CSSM_ERRCODE_SAMPLE_VALUE_NOT_SUPPORTED);
}
void Token::unverifyPIN(int pinNum)
{
}
bool Token::isLocked()
{
// Check pin1 by default. Subclasses may override.
return pinStatus(1) != 0x9000;
}
//
// ISO7816Token
//
ISO7816Token::ISO7816Token()
{
mPrintName[0]=0;
}
ISO7816Token::~ISO7816Token()
{
}
uint32 ISO7816Token::probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID])
{
const SCARD_READERSTATE &readerState = *(*startupReaderInfo)();
connect(mSession, readerState.szReader);
return 0;
}
void ISO7816Token::establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX])
{
secdebug("establish", "cacheDirectory %s, workDirectory: %s, name: %s",
cacheDirectory, workDirectory, mPrintName);
if (mPrintName[0])
::strlcpy(printName, mPrintName, PATH_MAX);
Token::establish(guid, subserviceId, flags, cacheDirectory,
workDirectory, mdsDirectory, printName);
if (!isConnected())
{
const SCARD_READERSTATE &readerState = *(*startupReaderInfo)();
connect(mSession, readerState.szReader);
}
}
uint16_t ISO7816Token::transmitAPDU(uint8_t cla, uint8_t ins, uint8_t p1,
uint8_t p2, size_t dataSize, const uint8_t *data,
size_t outputLength, std::vector<uint8_t> *output)
{
std::vector<uint8_t> apdu;
uint32_t lc = data ? dataSize : 0;
// Worst case we need this much
apdu.reserve(10 + lc);
apdu.push_back(cla);
apdu.push_back(ins);
apdu.push_back(p1);
apdu.push_back(p2);
if (lc > 0)
{
if (lc < 0x100)
{
// Normal length Lc
apdu.push_back(lc);
}
else if (lc < 0x10000)
{
// Extended length Lc
apdu.push_back(0);
apdu.push_back(lc >> 8);
apdu.push_back(lc);
}
else
{
// Lc too big.
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
}
apdu.insert(apdu.end(), data, data + dataSize);
}
if (output && outputLength > 0)
{
if (outputLength < 0x100)
{
// Normal length Le
apdu.push_back(outputLength);
}
else if (outputLength < 0x10000)
{
// Extended length Le
apdu.push_back(0);
apdu.push_back(outputLength >> 8);
apdu.push_back(outputLength);
}
else
{
// Le too big
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
}
// Append the response to what's already in output.
size_t oldSize = output->size();
// Make enough room for the data we are requesting plus the sw
output->resize(oldSize + outputLength + 2);
uint8_t *response = &output->at(oldSize);
size_t responseLength = outputLength + 2;
transmit(&apdu[0], apdu.size(), response, responseLength);
if (responseLength < 2)
{
output->resize(oldSize + responseLength);
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
}
uint16_t sw = (response[responseLength - 2] << 8)
+ response[responseLength - 1];
// Remove the sw from the output.
output->resize(oldSize + responseLength - 2);
return sw;
}
else
{
uint8_t response[2];
size_t responseLength = sizeof(response);
transmit(&apdu[0], apdu.size(), response, responseLength);
if (responseLength < 2)
PCSC::Error::throwMe(SCARD_E_PROTO_MISMATCH);
return (response[responseLength - 2] << 8)
+ response[responseLength - 1];
}
}
void ISO7816Token::name(const char *printName)
{
// Set the printName
::strlcpy(mPrintName,printName,min(1+strlen(printName),size_t(PATH_MAX)));
}
} // end namespace Tokend
--- NEW FILE Token.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* Token.h
* TokendMuscle
*/
#ifndef _TOKEND_TOKEN_H_
#define _TOKEND_TOKEN_H_
#include <SecurityTokend/SecTokend.h>
#include <security_utilities/osxcode.h>
#include <security_cdsa_utilities/context.h>
#include <security_cdsa_utilities/cssmpods.h>
#include <security_cdsa_utilities/cssmbridge.h>
#include <security_cdsa_utilities/cssmdb.h>
#include <security_cdsa_utilities/cssmaclpod.h>
#include <security_cdsa_utilities/cssmcred.h>
#include <security_utilities/debugging.h>
#include <security_utilities/pcsc++.h>
#include <string>
#include "TokenContext.h"
namespace Tokend
{
class Cursor;
class Schema;
class TokenContext;
//
// "The" token
//
class Token : public SecTokendSupport
{
NOCOPY(Token)
public:
Token();
virtual ~Token();
bool cachedObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
CssmData &data) const;
void cacheObject(CSSM_DB_RECORDTYPE relationId, const std::string &name,
const CssmData &object) const;
virtual const SecTokendCallbacks *callbacks();
virtual SecTokendSupport *support();
virtual void initial();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]) = 0;
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
virtual void terminate(uint32 reason, uint32 options);
virtual void authenticate(CSSM_DB_ACCESS_TYPE mode,
const AccessCredentials *cred);
virtual void getOwner(AclOwnerPrototype &owner) = 0;
virtual void getAcl(const char *tag, uint32 &count,
AclEntryInfo *&acls) = 0;
virtual Cursor *createCursor(const CSSM_QUERY *inQuery);
virtual void changeOwner(const AclOwnerPrototype &owner);
virtual void changeAcl(const AccessCredentials &cred, const AclEdit &edit);
virtual void generateRandom(const Context &context, CssmData &result);
virtual void getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS &result);
virtual void getTime(CSSM_ALGORITHMS algorithm, CssmData &result);
virtual void getCounter(CssmData &result);
virtual void selfVerify();
virtual void changePIN(int pinNum,
const unsigned char *oldPin, size_t oldPinLength,
const unsigned char *newPin, size_t newPinLength);
virtual uint32_t pinStatus(int pinNum);
virtual void verifyPIN(int pinNum,
const unsigned char *pin, size_t pinLength);
virtual void unverifyPIN(int pinNum);
virtual bool isLocked();
TokenContext *tokenContext() { return mTokenContext; }
protected:
std::string cachedObjectPath(CSSM_DB_RECORDTYPE relationId,
const std::string &name) const;
static CSSM_RETURN _initial();
static CSSM_RETURN _probe(SecTokendProbeFlags flags, uint32 *score,
char tokenUid[TOKEND_MAX_UID]);
static CSSM_RETURN _establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
static CSSM_RETURN _terminate(uint32 reason, uint32 options);
static CSSM_RETURN _findFirst(const CSSM_QUERY *query,
TOKEND_RETURN_DATA *data, CSSM_HANDLE *hSearch);
static CSSM_RETURN _findNext(CSSM_HANDLE hSearch,
TOKEND_RETURN_DATA *data);
static CSSM_RETURN _findRecordHandle(CSSM_HANDLE hRecord,
TOKEND_RETURN_DATA *data);
static CSSM_RETURN _insertRecord(CSSM_DB_RECORDTYPE recordType,
const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes, const CSSM_DATA *data,
CSSM_HANDLE *hRecord);
static CSSM_RETURN _modifyRecord(CSSM_DB_RECORDTYPE recordType,
CSSM_HANDLE *hRecord, const CSSM_DB_RECORD_ATTRIBUTE_DATA *attributes,
const CSSM_DATA *data, CSSM_DB_MODIFY_MODE modifyMode);
static CSSM_RETURN _deleteRecord(CSSM_HANDLE hRecord);
static CSSM_RETURN _releaseSearch(CSSM_HANDLE hSearch);
static CSSM_RETURN _releaseRecord(CSSM_HANDLE hRecord);
static CSSM_RETURN _freeRetrievedData(TOKEND_RETURN_DATA *data);
static CSSM_RETURN _releaseKey(CSSM_HANDLE hKey);
static CSSM_RETURN _getKeySize(CSSM_HANDLE hKey, CSSM_KEY_SIZE *size);
static CSSM_RETURN _getOutputSize(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, uint32 inputSize, CSSM_BOOL encrypting,
uint32 *outputSize);
static CSSM_RETURN _generateSignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
CSSM_DATA *signature);
static CSSM_RETURN _verifySignature(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, CSSM_ALGORITHMS signOnly, const CSSM_DATA *input,
const CSSM_DATA *signature);
static CSSM_RETURN _generateMac(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_DATA *input, CSSM_DATA *mac);
static CSSM_RETURN _verifyMac(const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_DATA *input, const CSSM_DATA *mac);
static CSSM_RETURN _encrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *clear, CSSM_DATA *cipher);
static CSSM_RETURN _decrypt(const CSSM_CONTEXT *context, CSSM_HANDLE hKey,
const CSSM_DATA *cipher, CSSM_DATA *clear);
static CSSM_RETURN _generateKey(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attrs, CSSM_HANDLE *hKey, CSSM_KEY *header);
static CSSM_RETURN _generateKeyPair(const CSSM_CONTEXT *context,
const CSSM_ACCESS_CREDENTIALS *creds,
const CSSM_ACL_ENTRY_PROTOTYPE *owner,
CSSM_KEYUSE pubUsage, CSSM_KEYATTR_FLAGS pubAttrs,
CSSM_KEYUSE privUsage, CSSM_KEYATTR_FLAGS privAttrs,
CSSM_HANDLE *hPubKey, CSSM_KEY *pubHeader,
CSSM_HANDLE *hPrivKey, CSSM_KEY *privHeader);
static CSSM_RETURN _wrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred, CSSM_HANDLE hSubjectKey,
const CSSM_KEY *subjectKey, const CSSM_DATA *descriptiveData,
CSSM_KEY *wrappedKey);
static CSSM_RETURN _unwrapKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hWrappingKey, const CSSM_KEY *wrappingKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access,
CSSM_HANDLE hPublicKey, const CSSM_KEY *publicKey,
const CSSM_KEY *wrappedKey, CSSM_KEYUSE usage,
CSSM_KEYATTR_FLAGS attributes, CSSM_DATA *descriptiveData,
CSSM_HANDLE *hUnwrappedKey, CSSM_KEY *unwrappedKey);
static CSSM_RETURN _deriveKey(const CSSM_CONTEXT *context,
CSSM_HANDLE hSourceKey, const CSSM_KEY *sourceKey,
const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_ENTRY_PROTOTYPE *access, CSSM_DATA *parameters,
CSSM_KEYUSE usage, CSSM_KEYATTR_FLAGS attributes,
CSSM_HANDLE *hKey, CSSM_KEY *hKey);
static CSSM_RETURN _getObjectOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getObjectAcl(CSSM_HANDLE hKey,
const char *tag, uint32 *count, CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _getDatabaseOwner(CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getDatabaseAcl(const char *tag, uint32 *count,
CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _getKeyOwner(CSSM_HANDLE hKey,
CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _getKeyAcl(CSSM_HANDLE hKey, const char *tag,
uint32 *count, CSSM_ACL_ENTRY_INFO **entries);
static CSSM_RETURN _freeOwnerData(CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _freeAclData(uint32 count,
CSSM_ACL_ENTRY_INFO *entries);
static CSSM_RETURN _authenticateDatabase(CSSM_DB_ACCESS_TYPE mode,
const CSSM_ACCESS_CREDENTIALS *cred);
static CSSM_RETURN _changeDatabaseOwner(const CSSM_ACL_OWNER_PROTOTYPE *
owner);
static CSSM_RETURN _changeDatabaseAcl(const CSSM_ACCESS_CREDENTIALS *cred,
const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _changeObjectOwner(CSSM_HANDLE hRecord,
const CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _changeObjectAcl(CSSM_HANDLE hRecord,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _changeKeyOwner(CSSM_HANDLE key,
const CSSM_ACL_OWNER_PROTOTYPE *owner);
static CSSM_RETURN _changeKeyAcl(CSSM_HANDLE key,
const CSSM_ACCESS_CREDENTIALS *cred, const CSSM_ACL_EDIT *edit);
static CSSM_RETURN _generateRandom(const CSSM_CONTEXT *context,
CSSM_DATA *result);
static CSSM_RETURN _getStatistics(CSSM_CSP_OPERATIONAL_STATISTICS *result);
static CSSM_RETURN _getTime(CSSM_ALGORITHMS algorithm, CSSM_DATA *result);
static CSSM_RETURN _getCounter(CSSM_DATA *result);
static CSSM_RETURN _selfVerify();
static CSSM_RETURN _cspPassThrough(uint32 id, const CSSM_CONTEXT *context,
CSSM_HANDLE hKey, const CSSM_KEY *key, const CSSM_DATA *input,
CSSM_DATA *output);
static CSSM_RETURN _dlPassThrough(uint32 id, const CSSM_DATA *input,
CSSM_DATA *output);
static CSSM_RETURN _isLocked(uint32 *locked);
private:
static const SecTokendCallbacks mCallbacks;
protected:
Schema *mSchema;
TokenContext *mTokenContext;
Guid mGuid;
uint32 mSubserviceId;
std::string mCacheDirectory;
};
class ISO7816Token : public Token, public TokenContext, public PCSC::Card
{
NOCOPY(ISO7816Token)
public:
ISO7816Token();
virtual ~ISO7816Token();
virtual uint32 probe(SecTokendProbeFlags flags,
char tokenUid[TOKEND_MAX_UID]);
virtual void establish(const CSSM_GUID *guid, uint32 subserviceId,
SecTokendEstablishFlags flags, const char *cacheDirectory,
const char *workDirectory, char mdsDirectory[PATH_MAX],
char printName[PATH_MAX]);
uint16_t transmitAPDU(uint8_t cla, uint8_t ins, uint8_t p1, uint8_t p2,
size_t dataSize = 0, const uint8_t *data = NULL,
size_t outputLength = 0, std::vector<uint8_t> *output = NULL);
protected:
PCSC::Session mSession;
char mPrintName[PATH_MAX];
virtual void name(const char *printName);
};
} // end namespace Tokend
//
// Singleton
//
extern Tokend::Token *token;
#endif /* !_TOKEND_TOKEN_H_ */
--- NEW FILE TokenContext.cpp ---
/*
* Copyright (c) 2004 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@
*/
/*
* TokenContext.cpp
* TokendMuscle
*/
#include "TokenContext.h"
namespace Tokend
{
TokenContext::~TokenContext()
{
}
} // end namespace Tokend
--- NEW FILE TokenContext.h ---
/*
* Copyright (c) 2004 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@
*/
/*
* TokenContext.h
* TokendMuscle
*/
#ifndef _TOKEND_TOKENCONTEXT_H_
#define _TOKEND_TOKENCONTEXT_H_
#include <security_utilities/utilities.h>
namespace Tokend
{
class TokenContext
{
NOCOPY(TokenContext)
public:
TokenContext() {}
virtual ~TokenContext() = 0;
};
} // end namespace Tokend
#endif /* !_TOKEND_TOKENCONTEXT_H_ */
14 years