[SmartcardServices-Changes] [141] trunk/SmartCardServices/src/PKCS11dotNetV2

source_changes at macosforge.org source_changes at macosforge.org
Mon Feb 20 06:26:33 PST 2012


Revision: 141
          http://trac.macosforge.org/projects/smartcardservices/changeset/141
Author:   ludovic.rousseau at gmail.com
Date:     2012-02-20 06:26:10 -0800 (Mon, 20 Feb 2012)
Log Message:
-----------
Resync with version 2.2.0.10

Modified Paths:
--------------
    trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Except.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am
    trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/autogen.sh
    trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/c-mac.sh
    trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/configure.in
    trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/des.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/util.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h

Added Paths:
-----------
    trunk/SmartCardServices/src/PKCS11dotNetV2/Application.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Application.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Array.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Digest.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/DigestMD5.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA1.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA256.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/IDeviceMonitorListener.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Log.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Log.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverException.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Module.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/PCSCMissing.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Exception.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Session.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Session.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReaderException.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Template.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Template.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Token.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/Token.hpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cardmod.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/cryptoki.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/pbbase.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs-11v2-20a3.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/version.hpp

Removed Paths:
-------------
    trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/acx_pthread.m4
    trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/application.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/error.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/event.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/log.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/session.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/template.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h
    trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp
    trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Application.cpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Application.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Application.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,601 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+#ifndef WIN32
+#include <stdlib.h>
+#endif
+#include <memory>
+#include <string>
+#include <boost/foreach.hpp>
+#include <boost/filesystem.hpp>
+#include "Application.hpp"
+#include "Configuration.hpp"
+#include "PKCS11Exception.hpp"
+#include "Log.hpp"
+#ifdef WIN32 
+#include <shlobj.h> // For SHGetFolderPath
+#else
+#endif
+
+
+// Determine Processor Endianess
+#include <limits.h>
+#if (UINT_MAX == 0xffffffffUL)
+   typedef unsigned int _u4;
+#else
+#  if (ULONG_MAX == 0xffffffffUL)
+     typedef unsigned long _u4;
+#  else
+#    if (USHRT_MAX == 0xffffffffUL)
+       typedef unsigned short _u4;
+#    endif
+#  endif
+#endif
+
+_u4 endian = 1;
+
+bool IS_LITTLE_ENDIAN = (*((unsigned char *)(&endian))) ? true  : false;
+bool IS_BIG_ENDIAN    = (*((unsigned char *)(&endian))) ? false : true;
+
+#ifdef MACOSX_LEOPARD
+#define SCardIsValidContext(x) SCARD_S_SUCCESS
+#endif
+
+extern boost::condition_variable g_WaitForSlotEventCondition;
+
+/*
+*/
+Application::Application( ) {
+
+    Log::start( );
+	std::string stConfigurationDirectoryPath;
+
+#ifdef WIN32 
+    
+    // For each user (roaming) data, use the CSIDL_APPDATA value. 
+    // This defaults to the following path: "\Documents and Settings\All Users\Application Data" 
+    TCHAR szPath[MAX_PATH];
+
+    SHGetFolderPath( NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath );
+
+    stConfigurationDirectoryPath = std::string( szPath ) + std::string( "/Gemalto/DotNet PKCS11/" );
+
+#else
+	char *home = getenv("HOME");
+	if (home)
+		stConfigurationDirectoryPath = std::string( home ) + std::string( "/.config/Gemalto/DotNet PKCS11/" );
+	else
+		stConfigurationDirectoryPath = std::string( "/tmp/Gemalto/DotNet PKCS11/" );
+#endif
+
+    std::string stConfigurationFilePath = stConfigurationDirectoryPath + std::string( "Gemalto.NET.PKCS11.ini" );
+
+    Log::log( "Application::Application - stConfigurationFilePath <%s>", stConfigurationFilePath.c_str( ) );
+    boost::filesystem::path configurationDirectoryPath( stConfigurationFilePath );
+
+    if( ! boost::filesystem::exists( configurationDirectoryPath ) ) {
+    
+        Log::s_bEnableLog = false;
+        
+        Device::s_bEnableCache = true;
+    
+    } else {
+
+        // Initialize the configuration 
+	    Configuration c;
+	    try {
+
+		    c.load( stConfigurationFilePath );
+
+            const std::string stCacheSectionName( "Cache" );
+            const std::string stCacheParameterEnable( "Enable" );
+            const std::string stLogSectionName( "Log" );
+            const std::string stLogParameterEnable( "Enable" );
+            const std::string stLogParameterPath( "Path" );
+
+		    // Read the flag in the configuration to enable/disable the log
+		    std::string stResult = "";
+
+		    c.getValue( stLogSectionName, stLogParameterEnable, stResult );
+		
+            if( 0 == stResult.compare( "1" ) ) {
+	
+			    Log::s_bEnableLog = true;
+
+		        // Read the flag in the configuration for the log filepath
+		        stResult = "";
+		
+                c.getValue( stLogSectionName, stLogParameterPath, stResult );
+		
+                if( stResult.size( ) > 0 ) {
+	
+			        Log::setLogPath( stResult );
+		        
+                } else {
+#ifdef WIN32
+                    Log::setLogPath( stConfigurationDirectoryPath );
+#endif
+                }
+		    }
+
+		    // Read the flag in the configuration to enable/disable the cache on disk
+		    stResult = "";
+		
+            c.getValue( stCacheSectionName, stCacheParameterEnable, stResult );
+		
+            if( 0 == stResult.compare( "1" ) ) {
+
+			    Device::s_bEnableCache = true;
+
+		    } else {
+
+			    Device::s_bEnableCache = false;
+		    }
+	    } catch( ... ) {
+
+		    // Unable to find the configuration file
+		    // Use default settings instead
+            Log::error( "Application::Application", "No configuration file found. Use default settings" );
+	    }
+    }
+
+    Log::log( "" );
+    Log::log( "" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( " PKCS11 STARTS" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( "" );
+
+    m_DeviceMonitor.reset( new DeviceMonitor( ) );
+
+	// Initialise the PCSC devices listener
+	m_DeviceMonitor->addListener( this );
+
+    Log::stop( "Application::Application" );
+}
+
+
+/*
+*/
+Application::~Application( ) {
+
+    if( m_DeviceMonitor.get( ) ) {
+
+	    // Remove the application from the PCSC devices listener list
+	    m_DeviceMonitor->removeListener( this ); 
+    }
+
+    finalize( );
+
+    Log::log( "" );
+    Log::log( "" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( " PKCS11 STOPS" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( "######   ######   ######   ######   ######   ######   ######   ######   ######" );
+    Log::log( "" );
+}
+
+
+/*
+*/
+void Application::notifyReaderInserted( const std::string& a_stReaderName ) {
+
+	BOOST_FOREACH( boost::shared_ptr< Device >& d, m_DeviceMonitor->getDeviceList( ) ) {
+	    
+        // Search the device associated to this new reader
+		if( d.get( ) && ( 0 == d->getReaderName( ).compare( a_stReaderName ) ) ) {
+            
+            // Create the PKCS11 slot associated to this new reader
+			addSlot( d );
+			
+			return;
+		}
+	}
+}
+
+
+/*
+*/
+void Application::notifyReaderRemoved( const std::string& a_stReaderName ) {
+
+    unsigned char ucSlotId = 0;
+
+	BOOST_FOREACH( boost::shared_ptr< Slot >& s, m_Slots ) {
+	
+		// If the slot exists and the the names are the same
+		if( s.get( ) && !s->getReaderName( ).compare( a_stReaderName ) ) {
+
+            s->tokenDelete( );
+
+            s->setEvent( true, ucSlotId );
+
+			return;
+		}
+
+        ++ucSlotId;
+	}
+}
+
+
+/*
+*/
+void Application::notifySmartCardRemoved( const std::string& a_stReaderName ) {
+
+    unsigned char ucSlotId = 0;
+
+	BOOST_FOREACH( boost::shared_ptr< Slot >& s, m_Slots ) {
+	
+		// If the slot exists and the the names are the same
+		if( s.get( ) && !s->getReaderName( ).compare( a_stReaderName ) ) {
+
+			s->tokenDelete( );
+            
+            s->setEvent( true, ucSlotId );
+			
+            return;
+		}
+
+        ++ucSlotId;
+	}
+}
+
+
+/*
+*/
+void Application::notifySmartCardInserted( const std::string& a_stReaderName ) {
+
+    unsigned char ucSlotId = 0;
+
+    BOOST_FOREACH( boost::shared_ptr< Slot >& s, m_Slots ) {
+	
+		// If the slot exists and the names are the same
+		if( s.get( ) && !s->getReaderName( ).compare( a_stReaderName ) ) {
+
+// LCA: Not create token on event but register insertion in slot
+//			s->tokenCreate( );
+            s->tokenInserted();
+
+            s->setEvent( true, ucSlotId );
+
+			return;
+		}
+
+        ++ucSlotId;
+	}
+
+
+}
+
+
+/*
+*/
+void Application::notifySmartCardChanged( const std::string& a_stReaderName ) {
+	
+    unsigned char ucSlotId = 0;
+
+    BOOST_FOREACH( boost::shared_ptr< Slot >& s, m_Slots ) {
+	
+		// If the slot exists and the the names are the same
+		if( s.get( ) && !s->getReaderName( ).compare( a_stReaderName ) ) {
+
+			s->tokenUpdate( );
+
+            s->setEvent( true, ucSlotId );
+
+			return;
+		}
+
+        ++ucSlotId;
+	}
+}
+
+
+///*
+//*/
+//void Application::getSlotList( const CK_BBOOL& a_bTokenPresent, CK_SLOT_ID_PTR a_pSlotList, CK_ULONG_PTR a_pulCount ) {
+//
+//    *a_pulCount = 1;
+//
+//    if( a_pSlotList ) {
+//     
+//        a_pSlotList[ 0 ] = 1;
+//    }
+//
+///*
+//	CK_ULONG ulCountSlot = 0;
+//	
+//	CK_ULONG ulCountSlotWithToken = 0;
+//
+//	CK_SLOT_ID iIndex = 0;
+//
+//    CK_RV rv = CKR_OK;
+//
+//	// Build the slot list
+//    size_t l = m_Slots.size( );
+//
+//	for( size_t i = 0; i < l ; ++i ) {
+//
+//		if( m_Slots[ i ].get( ) ) {
+//
+//			if( !a_bTokenPresent ) {
+//
+//				// Found a valid slot
+//				++ulCountSlot;
+//
+//				if( a_pSlotList ) {
+//					
+//                    if ( ulCountSlot > *a_pulCount ) {
+//                 
+//                        rv  = CKR_BUFFER_TOO_SMALL;
+//                    
+//                    } else {
+//
+//					    a_pSlotList[ iIndex ] = i;
+//					
+//                        ++iIndex;
+//                    }
+//				}
+//
+//			} else if( m_Slots[ i ]->getToken( ).get( ) ) { //isCardPresent( ) ) {
+//			
+//				// Found a slot within a token
+//				++ulCountSlotWithToken;
+// 
+//				if( a_pSlotList ) {
+//					
+//                   if ( ulCountSlotWithToken > *a_pulCount ) {
+//                 
+//                        rv = CKR_BUFFER_TOO_SMALL;
+//                    }
+//
+//                   a_pSlotList[ iIndex ] = i;
+//					
+//                   ++iIndex;
+//				}
+//			}
+//		}
+//	}
+//
+//	// Return the slot count
+//	if( a_bTokenPresent ) {
+//	
+//		*a_pulCount = ulCountSlotWithToken;	
+//	
+//    } else {
+//	
+//		*a_pulCount = ulCountSlot;
+//	}
+//
+//    if ( CKR_OK != rv ) {
+//                 
+//        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+//    }
+//*/
+//}
+
+
+/*
+*/
+void Application::getSlotList( const CK_BBOOL& a_bTokenPresent, CK_SLOT_ID_PTR a_pSlotList, CK_ULONG_PTR a_pulCount ) {
+
+	CK_ULONG ulCountSlot = 0;
+	
+	CK_ULONG ulCountSlotWithToken = 0;
+
+	CK_SLOT_ID iIndex = 0;
+
+    CK_RV rv = CKR_OK;
+
+	// Build the slot list
+    size_t l = m_Slots.size( );
+
+	for( size_t i = 0; i < l ; ++i ) {
+
+        Slot* s = m_Slots[ i ].get( );
+
+		if( s ) {
+
+			if( !a_bTokenPresent ) {
+
+				// Found a valid slot
+				++ulCountSlot;
+
+				if( a_pSlotList ) {
+					
+                    if ( ulCountSlot > *a_pulCount ) {
+                 
+                        rv  = CKR_BUFFER_TOO_SMALL;
+                    
+                    } else {
+
+					    a_pSlotList[ iIndex ] = i;
+					
+                        ++iIndex;
+                    }
+				}
+			
+//            } else if( m_Slots[ i ]->getToken( ).get( ) ) { //isCardPresent( ) ) {
+            } else if( /*s->isTokenInserted( ) ||*/ s->isCardPresent( ) ) {
+			
+				// Found a slot within a token
+				++ulCountSlotWithToken;
+ 
+				if( a_pSlotList ) {
+					
+                   if ( ulCountSlotWithToken > *a_pulCount ) {
+                 
+                        rv = CKR_BUFFER_TOO_SMALL;
+                    }
+
+                   a_pSlotList[ iIndex ] = i;
+					
+                   ++iIndex;
+				}
+			}
+		}
+	}
+
+	// Return the slot count
+	if( a_bTokenPresent ) {
+	
+		*a_pulCount = ulCountSlotWithToken;	
+	
+    } else {
+	
+		*a_pulCount = ulCountSlot;
+	}
+
+    if ( CKR_OK != rv ) {
+                 
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+}
+
+
+/*
+*/
+const boost::shared_ptr< Slot >& Application::getSlot( const CK_SLOT_ID& a_slotId ) {
+
+    if( a_slotId >= m_Slots.size( ) ) {
+    
+        throw PKCS11Exception( CKR_SLOT_ID_INVALID );
+    }
+    
+    boost::shared_ptr< Slot >& s = m_Slots.at( a_slotId );
+    
+    if( !s.get( ) ) {
+    
+        throw PKCS11Exception( CKR_SLOT_ID_INVALID );
+    }
+
+    return s;
+}
+
+
+/* Initialize the slot list from the device list
+*/
+void Application::getDevices( void ) {
+
+	BOOST_FOREACH( boost::shared_ptr< Device >& d, m_DeviceMonitor->getDeviceList( ) ) {
+	
+		if( d.get( ) ) {
+
+			unsigned char ucDeviceId = d->getDeviceID( );
+
+            m_Slots[ ucDeviceId ].reset( new Slot( d ) );
+		}
+	}
+}
+
+
+/*
+*/
+void Application::addSlot( const boost::shared_ptr< Device >& a_pDevice ) {
+
+    if( !a_pDevice ) {
+    
+        return;
+    }
+
+    Log::begin( "Application::addSlot" ); 
+
+    unsigned char ucDeviceId = a_pDevice->getDeviceID( );
+
+    m_Slots[ ucDeviceId ].reset( new Slot( a_pDevice ) );
+
+    m_Slots[ ucDeviceId ]->setEvent( true, ucDeviceId );
+
+    Log::end( "Application::addSlot" ); 
+}
+
+
+/*
+*/
+const boost::shared_ptr< Slot >& Application::getSlotFromSession( const CK_SESSION_HANDLE& a_hSession ) {
+
+	BOOST_FOREACH( boost::shared_ptr< Slot >& s, m_Slots ) {
+	
+		if( s.get( ) && s->isSessionOwner( a_hSession ) ) {
+
+			return s;
+		}	
+	}
+
+	throw PKCS11Exception( CKR_SESSION_HANDLE_INVALID );
+}
+
+
+/*
+*/
+void Application::initialize( ) {
+
+	// Start the PCSC devices listener
+	if( m_DeviceMonitor.get( ) ) {
+        
+        m_DeviceMonitor->start( );
+    }
+
+  	// Get the known PCSC devices
+	getDevices( );
+}
+
+//extern boost::mutex g_WaitForSlotEventMutex;
+
+/*
+*/
+void Application::finalize( void ) {
+
+    g_WaitForSlotEventCondition.notify_all( );
+  
+    long rv = SCardIsValidContext( DeviceMonitor::m_hContext );
+
+
+    if( SCARD_S_SUCCESS == rv ) {
+
+        // Call the finalize method for all managed device
+	    BOOST_FOREACH( boost::shared_ptr< Slot >& s, m_Slots ) {
+	
+		    if( s.get( ) ) {
+
+               
+
+			    s->finalize( );
+		    }	
+	    }
+
+        
+
+  	    // Stop the PCSC devices listenening thread
+	    if( m_DeviceMonitor.get( ) ) {
+
+            //g_WaitForSlotEventMutex.unlock( );
+
+            //DeviceMonitor::m_bAlive = false;
+
+            m_DeviceMonitor->stop( );
+
+            SCardReleaseContext( DeviceMonitor::m_hContext );
+        }
+    }
+}

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Application.hpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/application.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Application.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Application.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,88 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_APPLICATION__
+#define __GEMALTO_APPLICATION__
+
+
+#include <string>
+#include "cryptoki.h"
+#include "DeviceMonitor.hpp"
+#include "IDeviceMonitorListener.hpp"
+#include "Slot.hpp"
+#include <boost/array.hpp>
+
+
+const int g_iMaxSlot = 5;
+
+class DeviceMonitor;
+class Device;
+class Slot;
+
+
+/*
+*/
+class Application : public IDeviceMonitorListener {
+
+public:
+
+	typedef boost::array< boost::shared_ptr< Slot >, g_iMaxSlot > ARRAY_SLOTS;
+
+	Application( );
+
+	virtual ~Application( );
+
+	inline ARRAY_SLOTS getSlotList( void ) { return m_Slots; }
+
+	void getSlotList( const CK_BBOOL& tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount );
+
+	const boost::shared_ptr< Slot >& getSlot( const CK_SLOT_ID& );
+
+	const boost::shared_ptr< Slot >& getSlotFromSession( const CK_SESSION_HANDLE& );
+
+    void initialize( void );
+
+    void finalize( void );
+
+
+private:
+
+	void getDevices( void );
+
+	void notifyReaderInserted( const std::string& );
+	
+	void notifyReaderRemoved( const std::string& );
+
+	void notifySmartCardRemoved( const std::string& );
+	
+	void notifySmartCardInserted( const std::string& );
+	
+	void notifySmartCardChanged( const std::string& );
+
+	void addSlot( const boost::shared_ptr< Device >& );
+
+	ARRAY_SLOTS m_Slots;
+	
+	boost::shared_ptr< DeviceMonitor > m_DeviceMonitor;
+
+};
+
+#endif // __GEMALTO_APPLICATION__

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,22 +18,15 @@
  *
  */
 
+#include <cstring>
+#include <memory>
 #ifdef WIN32
 #include <Windows.h>
 #pragma warning(push)
 #pragma warning(disable:4201)
 #endif
 
-#include <string.h>
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include <stdexcept>
-#include "MarshallerCfg.h"
-#include "Except.h"
-#include "Array.h"
+#include "Array.hpp"
 
 // Determine Processor Endianess
 #include <limits.h>
@@ -53,54 +46,62 @@
 
 bool isLittleEndian = (*((unsigned char *)(&_endian))) ? true  : false;
 bool isBigEndian    = (*((unsigned char *)(&_endian))) ? false : true;
+
+
+const size_t g_sizeU1 = sizeof( u1 );
+const size_t g_sizeU2 = sizeof( u2 );
+const size_t g_sizeU4 = sizeof( u4 );
+const size_t g_sizeU8 = sizeof( u8 );
+
+
 MARSHALLER_NS_BEGIN
 
 
-static u4 ToBigEndian(u4 val)
+static u4 ToBigEndian(u4 v)
 {
     if (isBigEndian)
     {
-	    return val;
+	    return v;
     }
     else
     {
         u4 res;
-        res =  val << 24;
-        res |= (val << 8) & 0x00FF0000;
-        res |= (val >> 8) & 0x0000FF00;
-        res |= val >> 24;
+        res =  v << 24;
+        res |= (v << 8) & 0x00FF0000;
+        res |= (v >> 8) & 0x0000FF00;
+        res |= v >> 24;
 
         return res;
     }
 }
 
-static u2 ToBigEndian(u2 val)
+static u2 ToBigEndian(u2 v)
 {
     if (isBigEndian)
     {
-    	return val;
+    	return v;
     }
     else
     {
-        return (u2)((val << 8) | (val >> 8));
+        return (u2)((v << 8) | (v >> 8));
     }
 }
 
-static u8 ToBigEndian(u8 val)
+static u8 ToBigEndian(u8 v)
 {
     if (isBigEndian)
     {
-    	return val;
+    	return v;
     }
     else
     {
-	    u4 val1 = (u4)(val >> 32);
-	    u4 val2 = (u4)val;
+	    u4 v1 = (u4)(v >> 32);
+	    u4 v2 = (u4)v;
 
-        val1 = ToBigEndian(val1);
-        val2 = ToBigEndian(val2);
+        v1 = ToBigEndian(v1);
+        v2 = ToBigEndian(v2);
 
-	    return (u8)(((u8)val2 << 32) | val1);
+	    return (u8)(((u8)v2 << 32) | v1);
     }
 }
 
@@ -137,7 +138,7 @@
             goto error;
 		}
 
-        // Encode the character pair value.
+        // Encode the character pair vue.
 		if (pair < (u4)0x0080) {
             count++;
 		} else if (pair < (u4)0x0800) {
@@ -166,12 +167,12 @@
     u4 nCharProcessed = 0;
     u4 pair;
     u2 leftOver;
-    u1* bytes = utf8Data.GetBuffer();
+    u1* bytes = utf8Data.GetBuffer( );
     u4 byteCount;
     u4 byteIndex = 0;
     u4 charIndex = 0;
 
-    byteCount = utf8Data.GetLength();
+    byteCount = utf8Data.GetLength( );
 
     leftOver = 0;
 
@@ -196,7 +197,7 @@
             goto error;
 		}
 
-        // Encode the character pair value.
+        // Encode the character pair vue.
 		if (pair < (u4)0x0080) {
             if (byteIndex >= byteCount) {
                 goto end;
@@ -246,7 +247,7 @@
 
 u2 ComputeLPSTRLength(u1Array &array, u4 offset, u4 len)
 {
-	if ((u8)(offset + len) > (u8)array.GetLength()) {
+	if ((u8)(offset + len) > (u8)array.GetLength( ) ) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	} else {
 		u2 charlen = 0;
@@ -274,7 +275,7 @@
 
 void UTF8Decode(u1Array &array, u4 offset, u4 len, M_SAL_INOUT lpCharPtr &charData)
 {
-	if ((u8)(offset + len) > (u8)array.GetLength()) {
+	if ((u8)(offset + len) > (u8)array.GetLength( )) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	} else {
 		u4 i = 0;
@@ -302,368 +303,314 @@
 	}
 }
 
+
+
+
 // *******************
-// String Array class
+// Byte Array class
 // *******************
-StringArray::StringArray(s4 nelement)
-{
-    this->_length = nelement;
 
-	if (nelement < 0) {
-        nelement = 0;
-    }
 
-	this->buffer = new std::string*[nelement];
+/* 1 byte add
+*/
+u1Array& u1Array::operator +( const u1& v ) {
 
-	// we need to initialize the buffer to zeros
-	for(s4 i=0;i<nelement;i++)
-		this->buffer[i] = NULL;
+    u1Array* newArray = new u1Array( _length + g_sizeU1 );
 
+    memcpy( newArray->buffer, buffer, _length );
+    
+    memcpy( &newArray->buffer[ _length ], &v, g_sizeU1 );
+    
+    return *newArray;
 }
 
-StringArray::StringArray(const StringArray &rhs)
-{
-	s4 len = rhs._length;
-    this->_length = len;
-    if (len < 0) {
-        len = 0;
-    }
 
-	this->buffer = new std::string*[len];
+/*
+*/
+u1Array& u1Array::operator +=( const u1& v ) {
 
-	for(s4 i=0;i<len;i++)
-		this->buffer[i] = rhs.buffer[i];
+    u1* t = new u1[ _length + g_sizeU1 ];
 
+    memcpy( t, buffer, _length );
+    
+    memcpy(&t[ _length ], &v, g_sizeU1 );
+    
+    delete[ ] buffer;
+    
+    buffer = t;
+    
+    _length += g_sizeU1;
+    
+    return *this;
 }
 
-StringArray::~StringArray(void)
-{
-    // delete the strings in the StringArray
-    for(u4 i = 0; i < GetLength(); i++){
-        if (buffer[i] != NULL) {
-            delete buffer[i];
-            buffer[i] = NULL;
-        }
-    }
 
-	delete[] buffer;
-}
+/* 2 bytes add
+*/
+u1Array& u1Array::operator +( const u2& v ) {
 
-u1 StringArray::IsNull(void)
-{
-    return (this->_length < 0);
-}
+    u2 vbe = ToBigEndian( v );
 
-u4 StringArray::GetLength(void)
-{
-    if (IsNull()) {
-        return (u4)0;
-    } else {
-        return (u4)this->_length;
-    }
+    u1Array* newArray = new u1Array( _length + g_sizeU2 );
+    
+    memcpy( newArray->buffer, buffer, _length );
+    
+    memcpy( &newArray->buffer[ _length ], &vbe, g_sizeU2 );
+    
+    return *newArray;
 }
 
-std::string* StringArray::GetStringAt(u4 index)
-{
-	if (index >= GetLength()) {
-		throw ArgumentOutOfRangeException((lpCharPtr)"");
-	}
-    return this->buffer[index];
-}
 
-void StringArray::SetStringAt(u4 index, M_SAL_IN std::string* str)
-{
-	if (index >= GetLength()) {
-		throw ArgumentOutOfRangeException((lpCharPtr)"");
-	}
-	this->buffer[index] = str;
-}
+/*
+*/
+u1Array& u1Array::operator +=( const u2& v ) {
 
-// *******************
-// Byte Array class
-// *******************
+    u2 vbe = ToBigEndian( v );
+    
+    u1* t = new u1[ _length + g_sizeU2 ];
 
-u1Array::u1Array()
-{
-  this->_length = 0;
-// JCD
-  this->buffer = NULL;//new u1[0];
-// JCD
-}
+    memcpy( t, buffer, _length );
 
-u1Array::u1Array(s4 nelement)
-{
-	this->_length = nelement;
-    if (nelement < 0) {
-        nelement = 0;
-    }
-    this->buffer = new u1[nelement];
+    memcpy( &t[ _length ], &vbe, g_sizeU2 );
+    
+    delete[] buffer;
+    
+    buffer = t;
+    
+    _length += g_sizeU2;
+    
+    return *this;
 }
 
-u1Array::u1Array(const u1Array &rhs)
-{
-    s4 len = rhs._length;
-    this->_length = len;
-    if (len < 0) {
-        len = 0;
-    }
-    this->buffer = new u1[len];
-    memcpy(this->buffer, rhs.buffer, len);
-}
 
-u1Array::u1Array(u1Array &array, u4 offset, u4 len)
-{
-	if ((u8)(offset + len) > array.GetLength()) {
-		throw ArgumentOutOfRangeException((lpCharPtr)"");
-	} else {
-		this->_length = len;
-		this->buffer = new u1[len];
-		memcpy(this->buffer, array.buffer + offset, len);
-	}
-}
+/* 4 bytes add
+*/
+u1Array& u1Array::operator +( const u4& v ) {
 
-u1Array::~u1Array(void)
-{
-    if (this->buffer != NULL) {
-        delete[] this->buffer;
-        this->buffer = NULL;
-    }
-}
+    u4 vbe = ToBigEndian( v );
 
-u1 u1Array::IsNull(void) const
-{
-    return (this->_length < 0);
+    u1Array* a = new u1Array( _length + g_sizeU4 );
+    
+    memcpy( a->buffer, buffer, _length );
+    
+    memcpy( &a->buffer[ _length ], &vbe, g_sizeU4 );
+    
+    return *a;
 }
 
-void u1Array::SetU1At(u4 pos, u1 val)
-{
-	if (pos >= GetLength()) {
-		throw ArgumentOutOfRangeException((lpCharPtr)"");
-	}
-    this->buffer[pos] = val;
-}
 
+/*
+*/
+u1Array& u1Array::operator +=(const u4& v ) {
 
-u1 u1Array::ReadU1At(u4 pos) const
-{
-	if (pos >= GetLength()) {
-		throw ArgumentOutOfRangeException((lpCharPtr)"");
-	}
-    return this->buffer[pos];
-}
+    u4 vbe = ToBigEndian( v );
 
-u4 u1Array::GetLength(void) const
-{
-    if (IsNull()) {
-        return (u4)0;
-    } else {
-        return (u4)this->_length;
-    }
-}
+    u1* t = new u1[ _length + g_sizeU4 ];
+    
+    memcpy( t, buffer, _length );
 
-void u1Array::SetBuffer(const u1* buffer)
-{
-    memcpy(this->buffer, buffer, this->GetLength());
-}
+    memcpy( &t[ _length ], &vbe, g_sizeU4);
 
-const u1* u1Array::GetBuffer(void) const
-{
-    return this->buffer;
-}
+    delete[ ] buffer;
 
-u1* u1Array::GetBuffer(void)
-{
-    return this->buffer;
-}
+    buffer = t;
 
-// 1 byte add
-u1Array& u1Array::operator +(u1 val)
-{
-    u1Array* newArray = new u1Array(this->GetLength() + sizeof(u1));
-    memcpy(newArray->buffer, this->buffer, this->GetLength());
-    memcpy(&newArray->buffer[this->GetLength()], &val, sizeof(u1));
-    return *newArray;
-}
+    _length += g_sizeU4;
 
-u1Array& u1Array::operator +=(u1 val)
-{
-    u1* tempBuffer = new u1[this->GetLength() + sizeof(u1)];
-    memcpy(tempBuffer, this->buffer, this->GetLength());
-    memcpy(&tempBuffer[this->GetLength()], &val, sizeof(u1));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + sizeof(u1);
     return *this;
 }
 
-// 2 bytes add
-u1Array& u1Array::operator +(u2 val)
-{
-    val = ToBigEndian(val);
-    u1Array* newArray = new u1Array(this->GetLength() + sizeof(u2));
-    memcpy(newArray->buffer, this->buffer, this->GetLength());
-    memcpy(&newArray->buffer[this->GetLength()], &val, sizeof(u2));
-    return *newArray;
+
+/* 8 bytes add
+*/
+u1Array& u1Array::operator +( const u8& v ) {
+
+	u8 vbe = ToBigEndian( v );
+
+    u1Array* n = new u1Array( _length + g_sizeU8 );
+    
+    memcpy( n->buffer, buffer, _length );
+
+    memcpy( &n->buffer[ _length ], &vbe, g_sizeU8 );
+
+    return *n;
 }
 
-u1Array& u1Array::operator +=(u2 val)
-{
-    val = ToBigEndian(val);
-    u1* tempBuffer = new u1[this->GetLength() + sizeof(u2)];
-    memcpy(tempBuffer, this->buffer, this->GetLength());
-    memcpy(&tempBuffer[this->GetLength()], &val, sizeof(u2));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + sizeof(u2);
+
+/*
+*/
+u1Array& u1Array::operator +=(const u8& v ) {
+
+	u8 vbe = ToBigEndian( v );
+
+	u1* t = new u1[ _length + g_sizeU8 ];
+    
+    memcpy( t, buffer, _length);
+    
+    memcpy( &t[ _length ], &vbe, g_sizeU8 );
+    
+    delete[ ] buffer;
+    
+    buffer = t;
+    
+    _length += g_sizeU8;
+    
     return *this;
 }
 
-// 4 bytes add
-u1Array& u1Array::operator +(u4 val)
-{
-    val = ToBigEndian(val);
-    u1Array* newArray = new u1Array(this->GetLength() + sizeof(u4));
-    memcpy(newArray->buffer, this->buffer, this->GetLength());
-    memcpy(&newArray->buffer[this->GetLength()], &val, sizeof(u4));
-    return *newArray;
-}
 
-u1Array& u1Array::operator +=(u4 val)
-{
-    val = ToBigEndian(val);
-    u1* tempBuffer = new u1[this->GetLength() + sizeof(u4)];
-    memcpy(tempBuffer, this->buffer, this->GetLength());
-    memcpy(&tempBuffer[this->GetLength()], &val, sizeof(u4));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + sizeof(u4);
+/* bytes array add
+*/
+u1Array& u1Array::operator =( const u1Array& a ) {
+
+    delete[ ] buffer; 
+    
+    _length = a._length;
+    
+    buffer = new u1[ _length ];
+
+    memcpy( buffer, a.buffer, _length );
+
     return *this;
 }
 
-// 8 bytes add
-u1Array& u1Array::operator +(u8 val)
-{
-	val = ToBigEndian(val);
-    u1Array* newArray = new u1Array(this->GetLength() + sizeof(u8));
-    memcpy(newArray->buffer, this->buffer, this->GetLength());
-    memcpy(&newArray->buffer[this->GetLength()], &val, sizeof(u8));
-    return *newArray;
-}
 
-u1Array& u1Array::operator +=(u8 val)
-{
-	val = ToBigEndian(val);
-	u1* tempBuffer = new u1[this->GetLength() + sizeof(u8)];
-    memcpy(tempBuffer, this->buffer, this->GetLength());
-    memcpy(&tempBuffer[this->GetLength()], &val, sizeof(u8));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + sizeof(u8);
-    return *this;
+/*
+*/
+u1Array& u1Array::operator +( const u1Array& a ) {
+    
+    u1Array* n = new u1Array( _length + a._length );
+    
+    memcpy( n->buffer, buffer, _length );
+    
+    memcpy( &n->buffer[ _length ], a.buffer, a._length );
+    
+    return *n;
 }
 
 
-// bytes array add
-u1Array& u1Array::operator =(const u1Array &bArray)
-{
-    delete[] buffer; buffer = 0;
-    _length = bArray._length;
-    buffer = new u1[_length > 0 ? _length : 0];
-    if(_length>0)
-        memcpy(buffer, bArray.buffer, _length);
+/*
+*/
+u1Array& u1Array::operator +=( const u1Array& a ) {
+
+    u1* t = new u1[ _length + a._length ];
+
+    memcpy( t, buffer, _length );
+    
+    memcpy( &t[ _length ], a.buffer, a._length );
+
+    delete[ ] buffer;
+
+    buffer = t;
+	
+    _length += a._length;
+
     return *this;
 }
 
-u1Array& u1Array::operator +(u1Array &bArray)
-{
-    s4 len;
-    if (IsNull() && bArray.IsNull()) {
-        len = -1;
-    } else {
-        len = this->GetLength() + bArray.GetLength();
-    }
-    u1Array* newArray = new u1Array(len);
-    memcpy(newArray->buffer, this->buffer, this->GetLength());
-    memcpy(&newArray->buffer[this->GetLength()], bArray.buffer, bArray.GetLength());
-    return *newArray;
-}
 
-u1Array& u1Array::operator +=(u1Array &bArray)
-{
-    u1* tempBuffer = new u1[this->GetLength() + bArray.GetLength()];
-    memcpy(tempBuffer, this->buffer, this->GetLength());
-    memcpy(&tempBuffer[this->GetLength()], bArray.buffer, bArray.GetLength());
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-	if (IsNull() && bArray.IsNull()) {
-        this->_length = -1;
+/*
+*/
+u1Array& u1Array::Append( std::string* s ) {
+
+	if( !s ) {
+
+        *this += (u2)0xFFFF; // ?????
+    
     } else {
-        this->_length = this->GetLength() + bArray.GetLength();
+	
+        u2 strLen = ComputeUTF8Length( (lpCharPtr)s->c_str( ) );
+        
+        *this += strLen;
+        
+        u1Array strArray( strLen );
+		
+        UTF8Encode( (lpCharPtr)s->c_str( ), strArray );
+        
+        *this += strArray;
     }
+
     return *this;
 }
 
-u1Array& u1Array::Append(std::string* str)
-{
-	if (str == NULL) {
-        *this += (u2)0xFFFF;
+
+
+/*
+*/
+u1Array& u1Array::Append( const char * s ) {
+
+	if( !s ) {
+
+        *this += (u2)0xFFFF; // ?????
+    
     } else {
-		u2 strLen = ComputeUTF8Length((lpCharPtr)str->c_str());
+	
+        u2 strLen = strlen(s);
+        
         *this += strLen;
-        u1Array strArray(strLen);
-		UTF8Encode((lpCharPtr)str->c_str(), strArray);
+        
+        u1Array strArray( strLen );
+		
+        UTF8Encode( (char *)s, strArray );
+        
         *this += strArray;
     }
+
     return *this;
 }
 
+
+
+
+
+
 // *******************
 // UShort Array class
 // *******************
 u2Array::u2Array(s4 nelement)
 {
-	this->_length = nelement;
+	_length = nelement;
     if (nelement < 0) {
         nelement = 0;
     }
-    this->buffer = new u2[nelement];
+    buffer = new u2[nelement];
 }
 
 u2Array::u2Array(const u2Array &rhs)
 {
     s4 len = rhs._length;
-    this->_length = len;
+    _length = len;
     if (len < 0) {
         len = 0;
     }
-    this->buffer = new u2[len];
-    memcpy(this->buffer, rhs.buffer, len * sizeof(u2));
+    buffer = new u2[len];
+    memcpy(buffer, rhs.buffer, len * g_sizeU2);
 }
 
 u2Array::~u2Array(void)
 {
-    delete[] this->buffer;
+    delete[] buffer;
 }
 
 u1 u2Array::IsNull(void)
 {
-    return (this->_length < 0);
+    return (_length < 0);
 }
 
-void u2Array::SetU2At(u4 pos, u2 val)
+void u2Array::SetU2At(u4 pos, u2 v)
 {
-	if (pos >= GetLength()) {
+	if (pos >= (u4)_length) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	}
-    this->buffer[pos] = val;
+    buffer[pos] = v;
 }
 
 u2 u2Array::ReadU2At(u4 pos)
 {
-	if (pos >= GetLength()) {
+	if (pos >= (u4)_length) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	}
-    return this->buffer[pos];
+    return buffer[pos];
 }
 
 u4 u2Array::GetLength(void)
@@ -671,37 +618,37 @@
     if (IsNull()) {
         return (u4)0;
     } else {
-        return (u4)this->_length;
+        return (u4)_length;
     }
 }
 
-void u2Array::SetBuffer(u2* buffer)
+void u2Array::SetBuffer(u2* a_buffer)
 {
-    memcpy(this->buffer, buffer, this->GetLength() * sizeof(u2));
+    memcpy(buffer, a_buffer, _length * g_sizeU2);
 }
 
 u2* u2Array::GetBuffer(void)
 {
-    return this->buffer;
+    return buffer;
 }
 
 // 2 bytes add
-u2Array& u2Array::operator +(u2 val)
+u2Array& u2Array::operator +(u2 v)
 {
-    u2Array* newArray = new u2Array(this->GetLength() + 1);
-    memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u2));
-	newArray->buffer[this->GetLength()] = val;
+    u2Array* newArray = new u2Array(_length + 1);
+    memcpy(newArray->buffer, buffer, _length * g_sizeU2);
+	newArray->buffer[_length] = v;
     return *newArray;
 }
 
-u2Array& u2Array::operator +=(u2 val)
+u2Array& u2Array::operator +=(u2 v)
 {
-    u2* tempBuffer = new u2[this->GetLength() + 1];
-    memcpy(tempBuffer, this->buffer, this->GetLength() * sizeof(u2));
-	tempBuffer[this->GetLength()] = val;
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + 1;
+    u2* tempBuffer = new u2[_length + 1];
+    memcpy(tempBuffer, buffer, _length * g_sizeU2);
+	tempBuffer[_length] = v;
+    delete[] buffer;
+    buffer = tempBuffer;
+    _length = _length + 1;
     return *this;
 }
 
@@ -712,25 +659,25 @@
 	if (IsNull() && cArray.IsNull()) {
         len = -1;
     } else {
-        len = this->GetLength() + cArray.GetLength();
+        len = _length + cArray._length;
     }
     u2Array* newArray = new u2Array(len);
-    memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u2));
-    memcpy(&newArray->buffer[this->GetLength() * sizeof(u2)], cArray.buffer, cArray.GetLength() * sizeof(u2));
+    memcpy(newArray->buffer, buffer, _length * g_sizeU2);
+    memcpy(&newArray->buffer[_length * g_sizeU2], cArray.buffer, cArray._length * g_sizeU2);
     return *newArray;
 }
 
 u2Array& u2Array::operator +=(u2Array &cArray)
 {
-    u2* tempBuffer = new u2[this->GetLength() + cArray.GetLength()];
-    memcpy(tempBuffer, this->buffer, this->GetLength() * sizeof(u2));
-    memcpy(&tempBuffer[this->GetLength() * sizeof(u2)], cArray.buffer, cArray.GetLength() * sizeof(u2));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
+    u2* tempBuffer = new u2[_length + cArray._length];
+    memcpy(tempBuffer, buffer, _length * g_sizeU2);
+    memcpy(&tempBuffer[_length * g_sizeU2], cArray.buffer, cArray._length * g_sizeU2);
+    delete[] buffer;
+    buffer = tempBuffer;
 	if (IsNull() && cArray.IsNull()) {
-        this->_length = -1;
+        _length = -1;
     } else {
-        this->_length = this->GetLength() + cArray.GetLength();
+        _length = _length + cArray._length;
     }
     return *this;
 }
@@ -740,48 +687,48 @@
 // *******************
 u4Array::u4Array(s4 nelement)
 {
-	this->_length = nelement;
+	_length = nelement;
     if (nelement < 0) {
         nelement = 0;
     }
-    this->buffer = new u4[nelement];
+    buffer = new u4[nelement];
 }
 
 u4Array::u4Array(const u4Array &rhs)
 {
     s4 len = rhs._length;
-    this->_length = len;
+    _length = len;
     if (len < 0) {
         len = 0;
     }
-    this->buffer = new u4[len];
-    memcpy(this->buffer, rhs.buffer, len * sizeof(u4));
+    buffer = new u4[len];
+    memcpy(buffer, rhs.buffer, len * g_sizeU4);
 }
 
 u4Array::~u4Array(void)
 {
-    delete[] this->buffer;
+    delete[] buffer;
 }
 
 u1 u4Array::IsNull(void)
 {
-    return (this->_length < 0);
+    return (_length < 0);
 }
 
-void u4Array::SetU4At(u4 pos, u4 val)
+void u4Array::SetU4At(u4 pos, u4 v)
 {
-	if (pos >= GetLength()) {
+	if (pos >= (u4)_length) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	}
-    this->buffer[pos] = val;
+    buffer[pos] = v;
 }
 
 u4 u4Array::ReadU4At(u4 pos)
 {
-	if (pos >= GetLength()) {
+	if (pos >= (u4)_length) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	}
-    return this->buffer[pos];
+    return buffer[pos];
 }
 
 u4 u4Array::GetLength(void)
@@ -789,37 +736,37 @@
     if (IsNull()) {
         return (u4)0;
     } else {
-        return (u4)this->_length;
+        return (u4)_length;
     }
 }
 
-void u4Array::SetBuffer(u4* buffer)
+void u4Array::SetBuffer(u4* a_buffer)
 {
-    memcpy(this->buffer, buffer, this->GetLength() * sizeof(u4));
+    memcpy(buffer, a_buffer, _length * g_sizeU4);
 }
 
 u4* u4Array::GetBuffer(void)
 {
-    return this->buffer;
+    return buffer;
 }
 
 // 4 bytes add
-u4Array& u4Array::operator +(u4 val)
+u4Array& u4Array::operator +(u4 v)
 {
-    u4Array* newArray = new u4Array(this->GetLength() + 1);
-    memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u4));
-	newArray->buffer[this->GetLength()] = val;
+    u4Array* newArray = new u4Array(_length + 1);
+    memcpy(newArray->buffer, buffer, _length * g_sizeU4);
+	newArray->buffer[_length] = v;
     return *newArray;
 }
 
-u4Array& u4Array::operator +=(u4 val)
+u4Array& u4Array::operator +=(u4 v)
 {
-    u4* tempBuffer = new u4[this->GetLength() + 1];
-    memcpy(tempBuffer, this->buffer, this->GetLength() * sizeof(u4));
-	tempBuffer[this->GetLength()] = val;
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + 1;
+    u4* tempBuffer = new u4[_length + 1];
+    memcpy(tempBuffer, buffer, _length * g_sizeU4);
+	tempBuffer[_length] = v;
+    delete[] buffer;
+    buffer = tempBuffer;
+    _length = _length + 1;
     return *this;
 }
 
@@ -830,25 +777,25 @@
 	if (IsNull() && iArray.IsNull()) {
         len = -1;
     } else {
-        len = this->GetLength() + iArray.GetLength();
+        len = _length + iArray._length;
     }
     u4Array* newArray = new u4Array(len);
-    memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u4));
-    memcpy(&newArray->buffer[this->GetLength() * sizeof(u4)], iArray.buffer, iArray.GetLength() * sizeof(u4));
+    memcpy(newArray->buffer, buffer, _length * g_sizeU4);
+    memcpy(&newArray->buffer[_length * g_sizeU4], iArray.buffer, iArray._length * g_sizeU4);
     return *newArray;
 }
 
 u4Array& u4Array::operator +=(u4Array &iArray)
 {
-    u4* tempBuffer = new u4[this->GetLength() + iArray.GetLength()];
-    memcpy(tempBuffer, this->buffer, this->GetLength() * sizeof(u4));
-    memcpy(&tempBuffer[this->GetLength() * sizeof(u4)], iArray.buffer, iArray.GetLength() * sizeof(u4));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
+    u4* tempBuffer = new u4[_length + iArray._length];
+    memcpy(tempBuffer, buffer, _length * g_sizeU4);
+    memcpy(&tempBuffer[_length * g_sizeU4], iArray.buffer, iArray._length * g_sizeU4);
+    delete[] buffer;
+    buffer = tempBuffer;
 	if (IsNull() && iArray.IsNull()) {
-        this->_length = -1;
+        _length = -1;
     } else {
-        this->_length = this->GetLength() + iArray.GetLength();
+        _length = _length + iArray._length;
     }
     return *this;
 }
@@ -859,48 +806,48 @@
 // *******************
 u8Array::u8Array(s4 nelement)
 {
-	this->_length = nelement;
+	_length = nelement;
     if (nelement < 0) {
         nelement = 0;
     }
-    this->buffer = new u8[nelement];
+    buffer = new u8[nelement];
 }
 
 u8Array::u8Array(const u8Array &rhs)
 {
     s4 len = rhs._length;
-    this->_length = len;
+    _length = len;
     if (len < 0) {
         len = 0;
     }
-    this->buffer = new u8[len];
-    memcpy(this->buffer, rhs.buffer, len * sizeof(u8));
+    buffer = new u8[len];
+    memcpy(buffer, rhs.buffer, len * g_sizeU8);
 }
 
 u8Array::~u8Array(void)
 {
-    delete[] this->buffer;
+    delete[] buffer;
 }
 
 u1 u8Array::IsNull(void)
 {
-    return (this->_length < 0);
+    return (_length < 0);
 }
 
-void u8Array::SetU8At(u4 pos, u8 val)
+void u8Array::SetU8At(u4 pos, u8 v)
 {
-	if (pos >= GetLength()) {
+	if (pos >= (u4)_length) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	}
-    this->buffer[pos] = val;
+    buffer[pos] = v;
 }
 
 u8 u8Array::ReadU8At(u4 pos)
 {
-	if (pos >= GetLength()) {
+	if (pos >= (u4)_length) {
 		throw ArgumentOutOfRangeException((lpCharPtr)"");
 	}
-    return this->buffer[pos];
+    return buffer[pos];
 }
 
 u4 u8Array::GetLength(void)
@@ -908,36 +855,36 @@
     if (IsNull()) {
         return (u4)0;
     } else {
-        return (u4)this->_length;
+        return (u4)_length;
     }
 }
 
-void u8Array::SetBuffer(u8* buffer)
+void u8Array::SetBuffer(u8* a_buffer)
 {
-    memcpy(this->buffer, buffer, this->GetLength() * sizeof(u8));
+    memcpy(buffer, a_buffer, _length * g_sizeU8);
 }
 
 u8* u8Array::GetBuffer(void)
 {
-    return this->buffer;
+    return buffer;
 }
 
-u8Array& u8Array::operator +(u8 val)
+u8Array& u8Array::operator +(u8 v)
 {
-    u8Array* newArray = new u8Array(this->GetLength() + 1);
-    memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u8));
-	newArray->buffer[this->GetLength()] = val;
+    u8Array* newArray = new u8Array(_length + 1);
+    memcpy(newArray->buffer, buffer, _length * g_sizeU8);
+	newArray->buffer[_length] = v;
     return *newArray;
 }
 
-u8Array& u8Array::operator +=(u8 val)
+u8Array& u8Array::operator +=(u8 v)
 {
-    u8* tempBuffer = new u8[this->GetLength() + 1];
-    memcpy(tempBuffer, this->buffer, this->GetLength() * sizeof(u8));
-	tempBuffer[this->GetLength()] = val;
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
-    this->_length = this->GetLength() + 1;
+    u8* tempBuffer = new u8[_length + 1];
+    memcpy(tempBuffer, buffer, _length * g_sizeU8);
+	tempBuffer[_length] = v;
+    delete[] buffer;
+    buffer = tempBuffer;
+    _length = _length + 1;
     return *this;
 }
 
@@ -947,25 +894,25 @@
 	if (IsNull() && iArray.IsNull()) {
         len = -1;
     } else {
-        len = this->GetLength() + iArray.GetLength();
+        len = _length + iArray._length;
     }
     u8Array* newArray = new u8Array(len);
-    memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u8));
-    memcpy(&newArray->buffer[this->GetLength() * sizeof(u8)], iArray.buffer, iArray.GetLength() * sizeof(u8));
+    memcpy(newArray->buffer, buffer, _length * g_sizeU8);
+    memcpy(&newArray->buffer[_length * g_sizeU8], iArray.buffer, iArray._length * g_sizeU8);
     return *newArray;
 }
 
 u8Array& u8Array::operator +=(u8Array &iArray)
 {
-    u8* tempBuffer = new u8[this->GetLength() + iArray.GetLength()];
-    memcpy(tempBuffer, this->buffer, this->GetLength() * sizeof(u8));
-    memcpy(&tempBuffer[this->GetLength() * sizeof(u8)], iArray.buffer, iArray.GetLength() * sizeof(u8));
-    delete[] this->buffer;
-    this->buffer = tempBuffer;
+    u8* tempBuffer = new u8[_length + iArray._length];
+    memcpy(tempBuffer, buffer, _length * g_sizeU8);
+    memcpy(&tempBuffer[_length * g_sizeU8], iArray.buffer, iArray._length * g_sizeU8);
+    delete[] buffer;
+    buffer = tempBuffer;
 	if (IsNull() && iArray.IsNull()) {
-        this->_length = -1;
+        _length = -1;
     } else {
-        this->_length = this->GetLength() + iArray.GetLength();
+        _length = _length + iArray._length;
     }
     return *this;
 }

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,180 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_marshaller_array_h
-#define _include_marshaller_array_h
-
-MARSHALLER_NS_BEGIN
-
-class SMARTCARDMARSHALLER_DLLAPI StringArray
-{
-
-private:
-	std::string** buffer;
-    s4 _length;
-
-public:
-    StringArray(s4 nelement);
-    StringArray(const StringArray &rhs);
-    ~StringArray(void);
-
-    u1 IsNull(void);
-    u4 GetLength(void);
-
-	std::string* GetStringAt(u4 index);
-	void  SetStringAt(u4 index,M_SAL_IN std::string* str);
-};
-
-#define s8Array u8Array
-class SMARTCARDMARSHALLER_DLLAPI u8Array
-{
-
-private:
-    u8* buffer;
-    s4 _length;
-
-public:
-    u8Array(s4 nelement);
-    u8Array(const u8Array &rhs);
-    ~u8Array(void);
-
-    u1 IsNull(void);
-    u4 GetLength(void);
-
-    void  SetBuffer(u8* buffer);
-    u8*   GetBuffer(void);
-
-	u8 ReadU8At(u4 pos);
-    void SetU8At(u4 pos, u8 val);
-
-    u8Array& operator +(u8 val);
-    u8Array& operator +=(u8 val);
-    u8Array& operator +(u8Array &cArray);
-    u8Array& operator +=(u8Array &cArray);
-
-};
-
-#define s4Array u4Array
-class SMARTCARDMARSHALLER_DLLAPI u4Array
-{
-
-private:
-    u4* buffer;
-    s4 _length;
-
-public:
-    u4Array(s4 nelement);
-    u4Array(const u4Array &rhs);
-    ~u4Array(void);
-
-    u1 IsNull(void);
-    u4 GetLength(void);
-
-    void  SetBuffer(u4* buffer);
-    u4*   GetBuffer(void);
-
-	u4 ReadU4At(u4 pos);
-    void SetU4At(u4 pos, u4 val);
-
-    u4Array& operator +(u4 val);
-    u4Array& operator +=(u4 val);
-    u4Array& operator +(u4Array &cArray);
-    u4Array& operator +=(u4Array &cArray);
-};
-
-#define s2Array u2Array
-#define charArray u2Array
-class SMARTCARDMARSHALLER_DLLAPI u2Array
-{
-
-private:
-    u2* buffer;
-    s4 _length;
-
-public:
-    u2Array(s4 nelement);
-    u2Array(const u2Array &rhs);
-    ~u2Array(void);
-
-    u1    IsNull(void);
-    u4    GetLength(void);
-
-    void  SetBuffer(u2* buffer);
-    u2*   GetBuffer(void);
-
-	u2    ReadU2At(u4 pos);
-    void  SetU2At(u4 pos, u2 val);
-
-    u2Array& operator +(u2 val);
-    u2Array& operator +=(u2 val);
-    u2Array& operator +(u2Array &cArray);
-    u2Array& operator +=(u2Array &cArray);
-};
-
-#define s1Array u1Array
-#define MemoryStream u1Array
-class SMARTCARDMARSHALLER_DLLAPI u1Array
-{
-
-private:
-    u1* buffer;
-    s4 _length;
-
-public:
-    u1Array();
-    u1Array(s4 nelement);
-    u1Array(const u1Array &rhs);
-	u1Array(u1Array &array, u4 offset, u4 len);
-    ~u1Array(void);
-
-    u1  IsNull(void) const;
-    u4  GetLength(void) const;
-
-    void  SetBuffer(const u1* buffer);
-    const u1*  GetBuffer(void) const;
-    u1*  GetBuffer(void);
-
-    u1   ReadU1At(u4 pos) const;
-	void SetU1At(u4 pos, u1 val);
-
-	u1Array& Append(std::string* str);
-
-    u1Array& operator +(u1 val);
-    u1Array& operator +=(u1 val);
-    u1Array& operator +(u2 val);
-    u1Array& operator +=(u2 val);
-    u1Array& operator +(u4 val);
-    u1Array& operator +=(u4 val);
-	u1Array& operator +(u8 val);
-    u1Array& operator +=(u8 val);
-    u1Array& operator =(const u1Array &bArray);
-    u1Array& operator +(u1Array &bArray);
-    u1Array& operator +=(u1Array &bArray);
-};
-
-extern u2 ComputeUTF8Length(M_SAL_IN lpCharPtr str);
-extern void UTF8Encode(M_SAL_IN lpCharPtr str, u1Array &utf8Data);
-extern u2 ComputeLPSTRLength(u1Array &array, u4 offset, u4 len);
-extern void UTF8Decode(u1Array &array, u4 offset, u4 len, M_SAL_INOUT lpCharPtr &charData);
-
-MARSHALLER_NS_END
-
-#endif
-

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Array.hpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Array.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Array.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,291 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_ARRAY__
+#define __GEMALTO_ARRAY__
+
+
+#include <string>
+#include <string.h>
+#include <vector>
+#include <boost/serialization/split_member.hpp>
+#include <boost/serialization/version.hpp>
+#include "MarshallerCfg.h"
+#include "Except.h"
+
+
+MARSHALLER_NS_BEGIN
+
+
+/*
+*/
+class SMARTCARDMARSHALLER_DLLAPI StringArray
+{
+
+private:
+	
+    std::string** buffer;
+	
+    unsigned int _length;
+
+public:
+	
+    inline StringArray( ) { _length = 0; buffer = NULL; }
+
+    inline StringArray( const unsigned int& n ) { _length = n; buffer = new std::string*[ _length ]; for( unsigned int i = 0 ; i < _length ; ++i ) { buffer[ i ] = NULL; } }
+
+    inline StringArray( const StringArray& a ) { _length = a._length; buffer = new std::string*[ _length ]; for( unsigned int i = 0 ; i < _length ; ++i ) { buffer[ i ] = a.buffer[ i ]; } }
+
+    inline virtual ~StringArray( ) { for( unsigned int i = 0 ; i < _length; ++i ) { delete buffer[ i ]; } delete[ ] buffer; }
+
+   	inline bool IsNull( void ) const { return !_length; }
+
+    inline unsigned int GetLength( void ) const { return _length; }
+ 
+	inline std::string* GetStringAt( const unsigned int& i ) { if( i >= _length ) { throw ArgumentOutOfRangeException((lpCharPtr)""); } return buffer[ i ]; }
+
+    inline void SetStringAt( const unsigned int& i, std::string* s ) { if( i >= _length ) { throw ArgumentOutOfRangeException((lpCharPtr)""); } buffer[ i ] = s; }
+
+};
+
+
+
+
+
+#define s8Array u8Array
+class SMARTCARDMARSHALLER_DLLAPI u8Array
+{
+
+private:
+	u8* buffer;
+	s4 _length;
+
+public:
+	u8Array(s4 nelement);
+	u8Array(const u8Array &rhs);
+	~u8Array(void);
+
+	u1 IsNull(void);
+	u4 GetLength(void);
+
+	void  SetBuffer(u8* buffer);
+	u8*   GetBuffer(void);
+
+	u8 ReadU8At(u4 pos);
+	void SetU8At(u4 pos, u8 val);
+
+	u8Array& operator +(u8 val);
+	u8Array& operator +=(u8 val);
+	u8Array& operator +(u8Array &cArray);
+	u8Array& operator +=(u8Array &cArray);
+
+};
+
+
+
+
+
+
+#define s4Array u4Array
+class SMARTCARDMARSHALLER_DLLAPI u4Array
+{
+
+private:
+	u4* buffer;
+	s4 _length;
+
+public:
+	u4Array(s4 nelement);
+	u4Array(const u4Array &rhs);
+	~u4Array(void);
+
+	u1 IsNull(void);
+	u4 GetLength(void);
+
+	void  SetBuffer(u4* buffer);
+	u4*   GetBuffer(void);
+
+	u4 ReadU4At(u4 pos);
+	void SetU4At(u4 pos, u4 val);
+
+	u4Array& operator +(u4 val);
+	u4Array& operator +=(u4 val);
+	u4Array& operator +(u4Array &cArray);
+	u4Array& operator +=(u4Array &cArray);
+};
+
+
+
+
+
+#define s2Array u2Array
+#define charArray u2Array
+class SMARTCARDMARSHALLER_DLLAPI u2Array
+{
+
+private:
+	u2* buffer;
+	s4 _length;
+
+public:
+	u2Array(s4 nelement);
+	u2Array(const u2Array &rhs);
+	~u2Array(void);
+
+	u1    IsNull(void);
+	u4    GetLength(void);
+
+	void  SetBuffer(u2* buffer);
+	u2*   GetBuffer(void);
+
+	u2    ReadU2At(u4 pos);
+	void  SetU2At(u4 pos, u2 val);
+
+	u2Array& operator +(u2 val);
+	u2Array& operator +=(u2 val);
+	u2Array& operator +(u2Array &cArray);
+	u2Array& operator +=(u2Array &cArray);
+};
+
+
+
+
+
+#define s1Array u1Array
+#define MemoryStream u1Array
+class SMARTCARDMARSHALLER_DLLAPI u1Array
+{
+
+private:
+	
+    unsigned char* buffer;
+
+	unsigned int _length;
+
+public:
+	
+    inline u1Array( ) { _length = 0; buffer = 0; }
+
+	inline u1Array( const unsigned int& n ) { _length = n; buffer = new unsigned char[ _length ]; memset( buffer, 0, _length ); }
+
+    inline u1Array( const u1Array& a ) { _length = a._length; buffer = new unsigned char[ _length ]; memcpy( buffer, a.buffer, _length ); }
+
+    inline u1Array( const u1Array &a, const unsigned int& o, const unsigned int& l ) { if( (o + l) > a.GetLength( ) ) { throw ArgumentOutOfRangeException((lpCharPtr)" u1Array constructor (1)"); } _length = l; buffer = new unsigned char[ _length ]; memcpy( buffer, a.buffer + o, _length ); }
+
+    inline u1Array( const std::vector< unsigned char >& a ) { _length = a.size( ); buffer = new unsigned char[ _length ]; for( unsigned int i = 0 ; i < _length ; ++i ) { buffer[ i ] = a.at( i ); } }
+
+	inline virtual ~u1Array( ) { delete[ ] buffer; }
+
+	inline bool IsNull( void ) const { return !_length; }
+
+    inline unsigned int GetLength( void ) const { return _length; }
+    
+    inline void SetBuffer( const unsigned char* b ) { if( b ) { memcpy( buffer, b, _length ); } }
+
+	inline unsigned char ReadU1At( const unsigned int& p ) const { if( p >= _length ) { throw ArgumentOutOfRangeException((lpCharPtr)"u1Array::ReadU1At"); } return buffer[ p ]; }
+
+    inline void SetU1At( const unsigned int& p, const unsigned char& v ) { if( p >= _length ) { throw ArgumentOutOfRangeException((lpCharPtr)"u1Array::SetU1At"); } buffer[ p ] = v; }
+
+	u1Array& Append( std::string* );
+
+	u1Array& Append( const char* );
+
+    inline unsigned char* GetBuffer( void ) { return buffer; }
+
+    inline const unsigned char* GetBuffer( void ) const { return buffer; }
+
+    u1Array& operator +( const unsigned char& );
+
+	u1Array& operator +=( const unsigned char& );
+
+	u1Array& operator +( const u2& );
+
+	u1Array& operator +=( const u2& );
+
+	u1Array& operator +( const u4& );
+
+	u1Array& operator +=( const u4& );
+
+	u1Array& operator +( const u8& );
+
+	u1Array& operator +=( const u8& );
+
+	u1Array& operator =( const u1Array& );
+
+	u1Array& operator +( const u1Array& );
+
+	u1Array& operator +=( const u1Array& );
+
+	inline void reset( void ) { delete[ ] buffer; buffer = NULL; _length = 0; }
+
+    inline void reset( unsigned int a_uiLength ) { delete[ ] buffer; _length = a_uiLength; buffer = new unsigned char[ a_uiLength ]; memset( buffer, 0, _length ); }
+
+    inline void reset( Marshaller::u1Array* a_pArray ) { delete[ ] buffer; _length = 0; if( a_pArray ) { _length = a_pArray->_length; buffer = new unsigned char[ _length ]; memcpy( buffer, a_pArray->buffer, _length ); } }
+
+	// Boost serialization of the array
+
+	friend class boost::serialization::access;
+
+	template< class Archive > void save( Archive& ar, const unsigned int /*version*/ ) const {
+
+		ar << _length;
+
+		//Log::log( "Array::save - length <%ld>", _length );
+
+		ar.save_binary( buffer, _length );
+
+        //Log::logCK_UTF8CHAR_PTR( "Array::save - buffer", buffer, _length );
+	}
+
+	template< class Archive > void load( Archive& ar, const unsigned int /*version*/ ) {
+
+		ar >> _length;
+		        
+        //Log::log( "Array::load - length <%ld>", _length );
+        buffer = 0;
+
+        if( _length > 0 ) {
+
+		    buffer = new unsigned char[ _length ];
+		
+		    ar.load_binary( buffer, _length );
+        }
+
+        //Log::logCK_UTF8CHAR_PTR( "Array::load - buffer", buffer, _length );
+	}
+
+	BOOST_SERIALIZATION_SPLIT_MEMBER( )
+};
+
+
+extern u2 ComputeUTF8Length(M_SAL_IN lpCharPtr str);
+
+extern void UTF8Encode(M_SAL_IN lpCharPtr str, u1Array &utf8Data);
+
+extern u2 ComputeLPSTRLength(u1Array &array, u4 offset, u4 len);
+
+extern void UTF8Decode(u1Array &array, u4 offset, u4 len, M_SAL_INOUT lpCharPtr &charData);
+
+MARSHALLER_NS_END
+
+BOOST_CLASS_VERSION( Marshaller::u1Array, 1 )
+
+#endif // __GEMALTO_ARRAY__

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.cpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,762 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <boost/shared_ptr.hpp>
+#include "CardModuleService.hpp"
+#include "Log.hpp"
+#include "MiniDriverException.hpp"
+#ifdef __APPLE__
+#include <PCSC/winscard.h>
+#include <PCSC/wintypes.h>
+#else
+#include <winscard.h>
+#endif
+
+#include "PCSCMissing.h"
+
+const char* ERROR_MEMORY = "Persistent";
+const unsigned char CARD_PROPERTY_AUTHENTICATED_ROLES = 0x09;
+const unsigned int LOW_FREE_MEMORY_ALLOWED = 30000;
+
+#define TIMER_DURATION 2.0
+
+
+CardModuleService::SMARTCARD_TYPE CardModuleService::getVersion( void ) { 
+    
+    Timer t; 
+    t.start( ); 
+    
+    m_ucSmartCardType = SMART_CARD_TYPE_V2PLUS; 
+
+    try {
+
+        std::auto_ptr< Marshaller::u1Array > s( getCardProperty( CARD_VERSION_INFO, 0 ) );
+
+        if( s.get( )  ) { 
+      
+            Log::log( "CardModuleService::getVersion - %d.%d.%d.%d", s->ReadU1At( 0 ), s->ReadU1At( 1 ), s->ReadU1At( 2 ), s->ReadU1At( 3 ) );
+
+            if( s->ReadU1At( 0 ) != 0x07) {
+
+                m_ucSmartCardType = SMART_CARD_TYPE_V2; 
+            }
+        }
+    
+    } catch( ... ) { 
+    
+        m_ucSmartCardType = SMART_CARD_TYPE_V2;
+    }
+
+    //try { 
+    //    // Call the V5 get version method
+    //    Invoke( 0, 0xDEEC, MARSHALLER_TYPE_RET_STRING, &s );  
+    //
+    //} catch( Marshaller::Exception& x ) { 
+    //    
+    //    checkException( x ); 
+    //} 
+    
+    switch( m_ucSmartCardType ) {
+
+    case SMART_CARD_TYPE_V2:
+        Log::log( "CardModuleService::getVersion - V2" );
+        break;
+
+    case SMART_CARD_TYPE_V2PLUS:
+        Log::log( "CardModuleService::getVersion - V2+" );
+        break;
+
+    case SMART_CARD_TYPE_V1:
+        Log::log( "CardModuleService::getVersion - V1" );
+        break;
+
+    default:
+        Log::log( "CardModuleService::getVersion - unknown" );
+        break;
+    }
+
+    t.stop( ">> CardModuleService::getVersion" ); 
+    
+    return m_ucSmartCardType; 
+}
+
+
+/* checkException
+*/
+void CardModuleService::checkException( Marshaller::Exception &x ) {
+
+    if( x.what( ) ) {
+
+        if( 0 == strcmp( x.what( ), ERROR_MEMORY ) ) {
+
+            Log::error( "CardModuleService::checkException", "Memory Error" );
+
+            forceGarbageCollector( );
+
+            // Not enough memory available to complete this command.
+            throw MiniDriverException( SCARD_E_NO_MEMORY );
+        }
+    }
+
+    if( dynamic_cast< Marshaller::UnauthorizedAccessException* >( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " UnauthorizedAccessException" );
+
+        // No PIN was presented to the smart card.
+        throw MiniDriverException( SCARD_W_CARD_NOT_AUTHENTICATED );
+    }
+
+    if( dynamic_cast< Marshaller::OutOfMemoryException* >( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " OutOfMemoryException" );
+
+        // Not enough memory available to complete this command.
+        throw MiniDriverException( SCARD_E_NO_MEMORY );
+    }
+
+    if( dynamic_cast< Marshaller::DirectoryNotFoundException* >( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " DirectoryNotFoundException" );
+
+        // The identified directory does not exist in the smart card.
+        throw MiniDriverException( SCARD_E_DIR_NOT_FOUND );
+    }
+
+    if( dynamic_cast< Marshaller::FileNotFoundException * >( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " FileNotFoundException" );
+
+        // The identified file does not exist in the smart card.
+        throw MiniDriverException( SCARD_E_FILE_NOT_FOUND );
+    }
+
+    if( dynamic_cast< Marshaller::IOException * >( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " IOException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_WRITE_TOO_MANY );
+    }
+
+    if( dynamic_cast< Marshaller::TypeLoadException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " TypeLoadException" );
+
+        //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNSUPPORTED_FEATURE );
+    }
+
+    if( dynamic_cast< Marshaller::VerificationException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " VerificationException" );
+
+        // The supplied PIN is incorrect.
+        throw MiniDriverException( SCARD_E_INVALID_CHV );
+    }
+
+    if( dynamic_cast< Marshaller::RemotingException * >( &x ) ) {
+
+        // Can occur after when the computer wakes up after sleep
+        Log::error( "CardModuleService::checkException", " RemotingException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+        // Other possibilities: SCARD_F_COMM_ERROR SCARD_E_COMM_DATA_LOST SCARD_W_REMOVED_CARD
+    }
+
+    if( dynamic_cast< Marshaller::CryptographicException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " CryptographicException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::SystemException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " SystemException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::ArgumentException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ArgumentException" );
+
+        // One or more of the supplied parameters could not be properly interpreted.
+        throw MiniDriverException( SCARD_E_INVALID_PARAMETER );
+    }
+
+    if( dynamic_cast< Marshaller::ArgumentNullException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ArgumentNullException" );
+
+        // One or more of the supplied parameters could not be properly interpreted.
+        throw MiniDriverException( SCARD_E_INVALID_PARAMETER );
+    }
+
+    if( dynamic_cast< Marshaller::ArgumentOutOfRangeException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ArgumentOutOfRangeException" );
+
+        // A communications error with the smart card has been detected. Retry the operation.
+        throw MiniDriverException( SCARD_E_COMM_DATA_LOST );
+    }
+
+    if( dynamic_cast< Marshaller::IndexOutOfRangeException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " IndexOutOfRangeException" );
+
+        // One or more of the supplied parameters could not be properly interpreted.
+        throw MiniDriverException( SCARD_E_INVALID_PARAMETER );
+    }
+
+    if( dynamic_cast< Marshaller::InvalidCastException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " InvalidCastException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::InvalidOperationException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " InvalidOperationException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::NotImplementedException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " NotImplementedException" );
+
+        // This smart card does not support the requested feature.
+        throw MiniDriverException( SCARD_E_UNSUPPORTED_FEATURE );
+    }
+
+    if( dynamic_cast< Marshaller::NotSupportedException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " NotSupportedException" );
+
+        // This smart card does not support the requested feature.
+        throw MiniDriverException( SCARD_E_UNSUPPORTED_FEATURE );
+    }
+
+    if( dynamic_cast< Marshaller::NullReferenceException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " NullReferenceException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::ObjectDisposedException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ObjectDisposedException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::ApplicationException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ApplicationException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::ArithmeticException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ArithmeticException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::ArrayTypeMismatchException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " ArrayTypeMismatchException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::BadImageFormatException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " BadImageFormatException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::DivideByZeroException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " DivideByZeroException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::FormatException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " FormatException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::RankException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " RankException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::StackOverflowException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " StackOverflowException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::MemberAccessException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " MemberAccessException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::MissingFieldException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " MissingFieldException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::MissingMemberException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " MissingMemberException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::MissingMethodException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " MissingMethodException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::OverflowException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " OverflowException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::SecurityException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " SecurityException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    if( dynamic_cast< Marshaller::SerializationException *>( &x ) ) {
+
+        Log::error( "CardModuleService::checkException", " SerializationException" );
+
+        // An unexpected card error has occurred.
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+    }
+
+    // An unexpected card error has occurred.
+    throw MiniDriverException( SCARD_E_UNEXPECTED );
+}
+
+
+/*
+*/
+void CardModuleService::forceGarbageCollector( void ) { 
+
+    if( SMART_CARD_TYPE_V2PLUS != m_ucSmartCardType ) { 
+
+        return; 
+    } 
+
+    Timer t; 
+    t.start( ); 
+
+    try { 
+
+        Invoke( 0, 0x3D38, MARSHALLER_TYPE_RET_VOID ); 
+
+        Log::log( "_______________  _______________ !!!!!!! CardModuleService::forceGarbageCollector - force garbage !!!!!" );
+
+    //} catch( Marshaller::Exception& x ) { 
+
+    //    if( dynamic_cast< Marshaller::TypeLoadException *>( &x ) ) {
+
+    //        Log::log( "CardModuleService::forceGarbageCollector - force garbage collection not supported" );
+
+    //        m_ucSmartCardType = SMART_CARD_TYPE_V2;
+    //    }
+
+    } catch( ... ) {
+
+    }
+
+    m_Timer.start( ); 
+    t.stop( ">> CardModuleService::forceGarbageCollector"); 
+}
+
+
+/*
+*/
+void CardModuleService::manageGarbageCollector( void ) {
+
+    if( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ) {
+
+        if( m_Timer.getCurrentDuration( ) < TIMER_DURATION ) {
+
+            return;
+        }
+
+        try {
+            int i = getMemory( );
+
+            //Log::log( "CardModuleService::manageGarbageCollector - memory <%ld>", i );
+
+            if( i < LOW_FREE_MEMORY_ALLOWED ) {
+
+                Log::error( "CardModuleService::manageGarbageCollector", "Low memory" );
+
+                forceGarbageCollector( );
+            }
+
+        } catch( ... ) {
+
+            //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+        }
+
+        m_Timer.start( );
+    }
+}
+
+
+/*
+*/
+unsigned int CardModuleService::getMemory( void ) { 
+
+    Timer t; 
+    t.start( ); 
+
+    u4 uiRemainingMemory = 0;
+
+    if( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ) {
+
+        try {
+
+            // Try the "getMemory" command
+            Invoke( 0, 0x1DB4, MARSHALLER_TYPE_RET_S4, &uiRemainingMemory) ;
+
+        } catch( Marshaller::Exception& ) {
+
+            //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+
+            // Try the "getFreeSpace" command
+            try { 
+
+                std::auto_ptr< Marshaller::s4Array > a;
+
+                Invoke(0, 0x00E5, MARSHALLER_TYPE_RET_S4ARRAY, &a ); 
+
+                if( a.get( ) && ( a->GetLength( ) > 2 ) ) {
+
+                    uiRemainingMemory = a->ReadU4At( 2 );
+                }
+
+            } catch( Marshaller::Exception& x ) { 
+
+                checkException( x ); 
+            }
+        }
+
+    } else if( SMART_CARD_TYPE_V2 == m_ucSmartCardType ) {
+
+        try { 
+
+            std::auto_ptr< Marshaller::s4Array > a;
+
+            Invoke(0, 0x00E5, MARSHALLER_TYPE_RET_S4ARRAY, &a ); 
+
+            if( a.get( ) && ( a->GetLength( ) > 2 ) ) {
+
+                uiRemainingMemory = a->ReadU4At( 2 );
+            }
+
+        } catch( Marshaller::Exception& x ) { 
+
+            checkException( x ); 
+        }
+    }
+
+    Log::log( ">> CardModuleService::getMemory - memory <%ld>", uiRemainingMemory );
+    t.stop( ">> CardModuleService::getMemory" );
+
+    return uiRemainingMemory; 
+}
+
+
+/*
+*/
+bool CardModuleService::isAuthenticated( const unsigned char& a_ucRole ) { 
+
+    Timer t; 
+    t.start( ); 
+
+    bool bIsAuthenticated = false;
+
+    if( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ) {
+
+        // Try to get the flag using the card properties
+        try {
+
+            boost::shared_ptr< Marshaller::u1Array > p( getCardProperty( CARD_PROPERTY_AUTHENTICATED_ROLES, 0 ) );
+
+            Log::log( "MiniDriverAuthentication - isAuthenticated <%#02x>", p->ReadU1At( 0 ) );
+
+            bIsAuthenticated = ( ( (unsigned char)( p->ReadU1At( 0 ) & a_ucRole ) ) == a_ucRole ); 
+
+        } catch( Marshaller::Exception& ) {
+
+            //// The card properties are not supported
+            //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+
+            // Try the get the flag from a command
+            try {
+
+                Invoke(1, 0x9B0B, MARSHALLER_TYPE_IN_U1, a_ucRole, MARSHALLER_TYPE_RET_BOOL, &bIsAuthenticated ); 
+
+            } catch( Marshaller::Exception& x ) { 
+
+                checkException( x ); 
+            }
+        }
+
+    } else if( SMART_CARD_TYPE_V2 == m_ucSmartCardType ) {
+
+        // Try the get the flag from a command
+        try {
+
+            Invoke(1, 0x9B0B, MARSHALLER_TYPE_IN_U1, a_ucRole, MARSHALLER_TYPE_RET_BOOL, &bIsAuthenticated ); 
+
+        } catch( Marshaller::Exception& x ) { 
+
+            checkException( x ); 
+        }
+    }
+
+    t.stop( ">> CardModuleService::isAuthenticated" );
+
+    return bIsAuthenticated; 
+}
+
+
+/*
+*/
+void CardModuleService::verifyPin( const unsigned char& a_ucRole, Marshaller::u1Array* a_pPin ) { 
+
+    Timer t; 
+    t.start( ); 
+
+    if( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ) {
+
+        // Try to authentication using authenticateEx
+        try {
+
+            authenticateEx( 0, a_ucRole, a_pPin ); 
+
+        } catch( Marshaller::Exception& ) {
+
+            //// The authenticaqteEx is not supported
+            //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+
+            // Try the authentication using verify PIN
+            try {
+
+                Invoke( 2, 0x506B, MARSHALLER_TYPE_IN_U1, a_ucRole, MARSHALLER_TYPE_IN_U1ARRAY, a_pPin, MARSHALLER_TYPE_RET_VOID );
+
+            } catch( Marshaller::Exception& x ) { 
+
+                checkException( x ); 
+            }  
+        }
+
+    } else if( SMART_CARD_TYPE_V2 == m_ucSmartCardType ) {
+
+        // Try the get the flag from a command
+        try {
+
+            Invoke( 2, 0x506B, MARSHALLER_TYPE_IN_U1, a_ucRole, MARSHALLER_TYPE_IN_U1ARRAY, a_pPin, MARSHALLER_TYPE_RET_VOID );
+
+        } catch( Marshaller::Exception& x ) { 
+
+            checkException( x ); 
+        }
+    }
+
+    t.stop( ">> CardModuleService::verifyPin" );
+}
+
+
+/*
+*/
+void CardModuleService::logOut( const unsigned char& a_ucRole ) {
+
+    Timer t; 
+    t.start( ); 
+
+    if( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ) {
+
+        // Try to deauthentication using deauthenticateEx
+        try {
+
+            deauthenticateEx( a_ucRole );
+
+        } catch( Marshaller::Exception& ) {
+
+            //// The authenticaqteEx is not supported
+            //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+
+            // Try the deauthentication using logout
+            try {
+
+                Invoke( 1, 0xC4E4, MARSHALLER_TYPE_IN_U1, a_ucRole, MARSHALLER_TYPE_RET_VOID );
+
+            } catch( Marshaller::Exception& x ) { 
+
+                checkException( x ); 
+            }  
+        }
+
+    } else if( SMART_CARD_TYPE_V2 == m_ucSmartCardType ) {
+
+        // Try the get the flag from a command
+        try {
+
+            Invoke( 1, 0xC4E4, MARSHALLER_TYPE_IN_U1, a_ucRole, MARSHALLER_TYPE_RET_VOID );
+
+        } catch( Marshaller::Exception& x ) { 
+
+            checkException( x ); 
+        }
+    }
+
+    t.stop( ">> CardModuleService::logOut" );
+}    
+
+
+/*
+*/
+Marshaller::u1Array* CardModuleService::getCardProperty( const unsigned char& a_ucProperty, const unsigned char& a_ucFlags ) {
+
+    if( SMART_CARD_TYPE_V2PLUS != m_ucSmartCardType ) { 
+
+        return NULL; 
+    } 
+
+    Log::log( ">> CardModuleService::getCardProperty - property <%#02x>", a_ucProperty ); 
+
+    if( ( CARD_FREE_SPACE != a_ucProperty ) && ( CARD_AUTHENTICATED_ROLES != a_ucProperty ) && ( CARD_CHANGE_PIN_FIRST != a_ucProperty ) ) {
+
+        PROPERTIES::iterator i = m_Properties.find( a_ucProperty );
+
+        if( m_Properties.end( ) != i ) {
+
+            return i->second;
+        }
+    }
+
+    Timer t; 
+    t.start( ); 
+
+    boost::shared_ptr< Marshaller::u1Array > p( new Marshaller::u1Array( ) );
+
+    try {  
+
+        Invoke( 2, 0x8187, MARSHALLER_TYPE_IN_U1, a_ucProperty, MARSHALLER_TYPE_IN_U1, a_ucFlags, MARSHALLER_TYPE_RET_U1ARRAY, &p ); 
+
+        m_Properties[ a_ucProperty ] = *p;
+
+    } catch( Marshaller::Exception& x ) {
+        
+        //m_ucSmartCardType = SMART_CARD_TYPE_V2;
+
+        p.reset( );
+
+        checkException( x );
+    } 
+
+    t.stop( ">> CardModuleService::getCardProperty"); 
+
+    return p.get( ); 
+}
+
+
+/*
+*/
+void CardModuleService::setCardProperty( const unsigned char& a_ucProperty, Marshaller::u1Array* a_pData, const unsigned char& a_ucFlags ) {
+
+    if( SMART_CARD_TYPE_V2PLUS != m_ucSmartCardType ) { return; }
+
+    Log::log( ">> CardModuleService::setCardProperty - property <%#02x>", a_ucProperty );
+
+    Timer t; 
+    t.start( ); 
+
+    try {
+
+        Invoke( 3, 0xB0E4, MARSHALLER_TYPE_IN_U1, a_ucProperty, MARSHALLER_TYPE_IN_U1ARRAY, a_pData, MARSHALLER_TYPE_IN_U1, a_ucFlags, MARSHALLER_TYPE_RET_VOID );
+
+        boost::shared_ptr< Marshaller::u1Array > p( new Marshaller::u1Array( *a_pData ) );
+
+        m_Properties[ a_ucProperty ] = *p;
+
+    } catch( Marshaller::Exception& x ) { 
+
+        checkException( x );
+    }
+
+    t.stop( ">> CardModuleService::setCardProperty" );
+}

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.hpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/CardModuleService.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,163 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_CARD_MODULE_SERVICE__
+#define __GEMALTO_CARD_MODULE_SERVICE__
+
+
+#include <string>
+#include <boost/ptr_container/ptr_map.hpp>
+#include "MarshallerCfg.h"
+#include "Array.hpp"
+#include "Marshaller.h"
+#include "Except.h"
+#include "Timer.hpp"
+#include "Log.hpp"
+
+
+const unsigned char CARD_FREE_SPACE  = 0x00; //Returns a byte array blob of 12 bytes
+const unsigned char CARD_KEYSIZES = 0x02; // Returns a byte array blob of 16 bytes 
+const unsigned char CARD_READ_ONLY = 0x03; // Returns a byte array blob of 1 byte
+const unsigned char CARD_CACHE_MODE = 0x04; // Returns a byte array blob of 1 byte
+const unsigned char CARD_GUID = 0x05; // Returns a byte array blob of 16 bytes
+const unsigned char CARD_SERIAL_NUMBER = 0x06; // Returns a byte array blob of 12 bytes
+const unsigned char CARD_PIN_INFO = 0x07; // Returns a byte array blob of 12 bytes
+const unsigned char CARD_ROLES_LIST = 0x08; // Returns a byte array blob of 1 byte
+const unsigned char CARD_AUTHENTICATED_ROLES = 0x09; // Returns a byte array blob of 1 byte 
+const unsigned char CARD_PIN_STRENGTH = 0x0A; // Returns a byte array blob of 1 byte
+const unsigned char CARD_X509_ENROLL = 0x0D; // Returns a byte array blob of 1 byte
+const unsigned char CARD_PIN_POLICY = 0x80; // Returns a byte array blob of 14 bytes
+const unsigned char CARD_CHANGE_PIN_FIRST = 0xFA; // Returns a byte array blob of 1 byte
+const unsigned char CARD_VERSION_INFO = 0xFF; // Returns a byte array blob of 4 bytes
+
+/*
+*/
+class CardModuleService : public Marshaller::SmartCardMarshaller {
+
+public:
+
+    typedef boost::ptr_map< unsigned char, Marshaller::u1Array > PROPERTIES;
+
+    typedef enum { SMART_CARD_TYPE_V1 = 0x00, SMART_CARD_TYPE_V2 = 0x01, SMART_CARD_TYPE_V2PLUS = 0x02 } SMARTCARD_TYPE;
+
+    inline CardModuleService( const std::string& readerName, u2 portNumber = 5, std::string uri = "MSCM" ) : Marshaller::SmartCardMarshaller( readerName, portNumber, uri, (u4)0xC04B4E, (u2)0x7FBD, 0 ) { Timer t; t.start( ); m_Timer.start( ); getVersion( ); t.stop( ">> CardModuleService::CardModuleService" ); }
+
+    inline bool isV2Plus( void ) { return ( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ); }
+
+    void manageGarbageCollector( void );
+
+    inline void updateCardHandle( SCARDHANDLE a_CardHandle ) { UpdatePCSCCardHandle( a_CardHandle ); }
+
+    inline std::string& getReader( void ) { return GetReaderName( ); }
+
+    inline SCARDHANDLE getCardHandle( void ) { return GetCardHandle( ); }
+
+    inline void doSCardTransact( bool& flag ) { DoTransact( flag ); }
+
+    inline void createContainer( const unsigned char& i, const unsigned char& keyImport, const unsigned char& keySpec, const int& keySize, Marshaller::u1Array* keyValue ) { Log::log( ">> CardModuleService::createContainer - index <%#02x>", i ); Timer t; t.start( ); try { Invoke( 5, 0x0234, MARSHALLER_TYPE_IN_U1, i, MARSHALLER_TYPE_IN_BOOL, keyImport, MARSHALLER_TYPE_IN_U1, keySpec, MARSHALLER_TYPE_IN_S4, keySize, MARSHALLER_TYPE_IN_U1ARRAY, keyValue, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } forceGarbageCollector( ); t.stop( ">> CardModuleService::createContainer" ); }
+
+    inline void deleteContainer( const unsigned char& i ) { Log::log( ">> CardModuleService::deleteContainer - index <%#02x>", i ); Timer t; t.start( ); try { Invoke( 1, 0xF152, MARSHALLER_TYPE_IN_U1, i, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } forceGarbageCollector( ); t.stop( ">> CardModuleService::deleteContainer" ); }
+
+    inline Marshaller::u1Array* getContainer( const unsigned char& i ) { Log::log( ">> CardModuleService::getContainer - index <%#02x>", i ); Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke( 1, 0x9B2E, MARSHALLER_TYPE_IN_U1, i, MARSHALLER_TYPE_RET_U1ARRAY, &a ); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getContainer"); return a; }
+
+    inline Marshaller::u1Array* getContainerProperty( const unsigned char& i, const unsigned char& p, const unsigned char& f ) { Log::log( ">> CardModuleService::getContainerProperty - index <%#02x>", i ); Timer t; t.start( ); Marshaller::u1Array* a = 0; if( SMART_CARD_TYPE_V2PLUS == m_ucSmartCardType ) { try {  Invoke( 3, 0x279C, MARSHALLER_TYPE_IN_U1, i, MARSHALLER_TYPE_IN_U1, p, MARSHALLER_TYPE_IN_U1, f, MARSHALLER_TYPE_RET_U1ARRAY, &a );  } catch( Marshaller::Exception& x ) { checkException( x ); } } t.stop( ">> CardModuleService::getContainerProperty"); return a; }
+
+    inline void setContainerProperty( const unsigned char& i, const unsigned char& p, Marshaller::u1Array* d, const unsigned char& f ) { Log::log( ">> CardModuleService::setContaineProperty - index <%#02x>", i ); Timer t; t.start( ); try {  Invoke(4, 0x98D1, MARSHALLER_TYPE_IN_U1, i, MARSHALLER_TYPE_IN_U1, p, MARSHALLER_TYPE_IN_U1ARRAY, d, MARSHALLER_TYPE_IN_U1, f, MARSHALLER_TYPE_RET_VOID); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::setContainerProperty" ); }
+
+    inline Marshaller::u1Array* privateKeyDecrypt( const unsigned char& i, const unsigned char& k, Marshaller::u1Array* d ) { Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke( 3, 0x6144, MARSHALLER_TYPE_IN_U1, i, MARSHALLER_TYPE_IN_U1, k, MARSHALLER_TYPE_IN_U1ARRAY, d, MARSHALLER_TYPE_RET_U1ARRAY, &a ); } catch( Marshaller::Exception& x ) { checkException( x ); } manageGarbageCollector( ); t.stop( ">> CardModuleService::privateKeyDecrypt"); return a; }
+
+    inline void createFile( std::string* p, Marshaller::u1Array* a, const int& z ) { Log::log( ">> CardModuleService::createFile - path <%s>", p->c_str( ) ); Timer t; t.start( ); try {  Invoke( 3, 0xBEF1, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_IN_U1ARRAY, a, MARSHALLER_TYPE_IN_S4, z, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } manageGarbageCollector( ); t.stop( ">> CardModuleService::createFile" ); }
+
+    inline void createDirectory( std::string* p, Marshaller::u1Array* a ) { Log::log( ">> CardModuleService::createDirectory - path <%s>", p->c_str( ) ); Timer t; t.start( ); try {  Invoke( 2, 0xACE9, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_IN_U1ARRAY, a, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } manageGarbageCollector( ); t.stop( ">> CardModuleService::createDirectory" ); }
+
+    inline void writeFile( std::string* p, Marshaller::u1Array* a ) { Log::log( ">> CardModuleService::writeFile - path <%s>", p->c_str( ) ); Timer t; t.start( ); try { Invoke( 2, 0xF20E, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_IN_U1ARRAY, a, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } manageGarbageCollector( ); t.stop( ">> CardModuleService::writeFile" ); }
+
+    inline Marshaller::u1Array* readFile( std::string* p ) { Log::log( ">> CardModuleService::readFile - path <%s>", p->c_str( ) ); Marshaller::u1Array* a = readFileWithoutMemoryCheck( p ); manageGarbageCollector( ); Log::end( ">> CardModuleService::readFile" ); return a; }
+
+    inline Marshaller::u1Array* readFileWithoutMemoryCheck( std::string* p ) { Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke( 2, 0x744C, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_IN_S4, 0, MARSHALLER_TYPE_RET_U1ARRAY, &a ); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::readFileWithoutMemoryCheck" ); return a; }
+
+    inline void deleteFile( std::string* p ) { Log::log( ">> CardModuleService::deleteFile - path <%s>", p->c_str( ) ); Timer t; t.start( ); try { Invoke( 1, 0x6E2B, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } forceGarbageCollector( ); t.stop( ">> CardModuleService::deleteFile" ); }
+
+    inline void deleteDirectory( std::string* p ){ Log::log( ">> CardModuleService::deleteDirectory - path <%s>", p->c_str( ) ); Timer t; t.start( ); try { Invoke( 1, 0x9135, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } forceGarbageCollector( ); t.stop( ">> CardModuleService::deleteDirectory" ); }
+
+    inline Marshaller::StringArray* getFiles( std::string* p ) { Log::log( ">> CardModuleService::getFiles - path <%s>", p->c_str( ) ); Timer t; t.start( ); Marshaller::StringArray* a = 0; try {  Invoke( 1, 0xE72B, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_RET_STRINGARRAY, &a ); } catch( Marshaller::Exception& x ) { t.stop( ">> CardModuleService::getFiles"); checkException( x ); } t.stop( ">> CardModuleService::getFiles"); return a; }
+
+    inline Marshaller::u1Array* getFileProperties( std::string* p ) { Log::log( ">> CardModuleService::getFileProperty - path <%s>", p->c_str( ) ); Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke( 1, 0xA01B, MARSHALLER_TYPE_IN_STRING, p->c_str( ), MARSHALLER_TYPE_RET_U1ARRAY, &a ); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getFileProperties"); return a; }
+
+    inline int getTriesRemaining( const unsigned char& r) { Timer t; t.start( ); int i = 0; try {  Invoke( 1, 0x6D08, MARSHALLER_TYPE_IN_U1, r, MARSHALLER_TYPE_RET_S4, &i ); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getTriesRemaining"); return i; }
+
+    inline void changeReferenceData( const unsigned char& m, const unsigned char& r, Marshaller::u1Array* oldPin, Marshaller::u1Array* newPin, const int& maxTries ) { Timer t; t.start( ); try {  Invoke( 5, 0xE08A, MARSHALLER_TYPE_IN_U1, m, MARSHALLER_TYPE_IN_U1, r, MARSHALLER_TYPE_IN_U1ARRAY, oldPin, MARSHALLER_TYPE_IN_U1ARRAY, newPin, MARSHALLER_TYPE_IN_S4, maxTries, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::changeReferenceData" ); }
+
+    inline void changeAuthenticatorEx( const unsigned char& m, const unsigned char& orole, Marshaller::u1Array* op, const unsigned char& nr, Marshaller::u1Array* np, const int& t ) { Timer time; time.start( ); try {  Invoke( 6, 0x9967, MARSHALLER_TYPE_IN_U1, m, MARSHALLER_TYPE_IN_U1, orole, MARSHALLER_TYPE_IN_U1ARRAY, op, MARSHALLER_TYPE_IN_U1, nr, MARSHALLER_TYPE_IN_U1ARRAY, np, MARSHALLER_TYPE_IN_S4, t, MARSHALLER_TYPE_RET_VOID ); } catch( Marshaller::Exception& x ) { checkException( x ); } time.stop( ">> CardModuleService::changeAuthenticatorEx" ); }
+
+    bool isAuthenticated( const unsigned char& );
+
+    Marshaller::u1Array* getCardProperty( const unsigned char& p, const unsigned char& f );
+
+    void setCardProperty( const unsigned char& p, Marshaller::u1Array* d, const unsigned char& f );
+
+    unsigned int getMemory( void );
+
+    void verifyPin( const unsigned char& r, Marshaller::u1Array* p );
+
+    void logOut( const unsigned char& );
+
+    void forceGarbageCollector( void );
+
+    inline Marshaller::u1Array* getChallenge( void ) { Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke(0, 0xFA3B, MARSHALLER_TYPE_RET_U1ARRAY, &a); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getChallenge"); return a; }
+
+    inline void externalAuthenticate( Marshaller::u1Array* a ) { Timer t; t.start( ); try {  Invoke(1, 0x24FE, MARSHALLER_TYPE_IN_U1ARRAY, a, MARSHALLER_TYPE_RET_VOID); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::externalAuthenticate" ); }
+
+    inline Marshaller::s4Array* getKeySizes( void ) { Timer t; t.start( ); Marshaller::s4Array* a = 0; try {  Invoke(0, 0x5EE4, MARSHALLER_TYPE_RET_S4ARRAY, &a); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getKeySizes"); return a; }
+
+    inline Marshaller::u1Array* getSerialNumber( void ) { Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke(0, 0xD017, MARSHALLER_TYPE_RET_U1ARRAY, &a); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getSerialNumber"); return a; }
+
+    inline Marshaller::u1Array* getBioHeader( const unsigned char& r ) { Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke(1, 0x4838, MARSHALLER_TYPE_IN_U1, r, MARSHALLER_TYPE_RET_U1ARRAY, &a); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getBioHeader"); return a; }
+
+    inline unsigned char matchBio( const unsigned char& r, Marshaller::u1Array* verificationData ) { Timer t; t.start( ); unsigned char u = 0; try {  Invoke(2, 0x2D3D, MARSHALLER_TYPE_IN_U1, r, MARSHALLER_TYPE_IN_U1ARRAY, verificationData, MARSHALLER_TYPE_RET_BOOL, &u ); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::matchBio"); return u; }
+
+    inline Marshaller::u1Array* getBioRoles( void ) { Timer t; t.start( ); Marshaller::u1Array* a = 0; try {  Invoke(0, 0xA77A, MARSHALLER_TYPE_RET_U1ARRAY, &a); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getBioRoles"); return a; }
+
+    inline unsigned char getBioDefaultRole( void ) { Timer t; t.start( ); unsigned char u = 0; try {  Invoke(0, 0x17FD, MARSHALLER_TYPE_RET_U1, &u); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getBioDefaultRole"); return u; }
+
+    inline std::string* getBioVerificationUIName( void ) { Timer t; t.start( ); std::string* s = 0; try {  Invoke(0, 0x7BB7, MARSHALLER_TYPE_RET_STRING, &s); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getBioVerificationUIName"); return s; }
+
+    inline std::string* getBioEnrollmentUIName( void ) { Timer t; t.start( ); std::string* s = 0; try {  Invoke(0, 0x0D17, MARSHALLER_TYPE_RET_STRING, &s); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::getBioEnrollmentUIName"); return s; }
+
+    SMARTCARD_TYPE getVersion( void );
+
+private:
+
+    inline void deauthenticateEx( const unsigned char& r ) { Timer t; t.start( ); try { Invoke(1, 0xBD7B, MARSHALLER_TYPE_IN_U1, r, MARSHALLER_TYPE_RET_VOID); } catch( Marshaller::Exception& x ) { checkException( x ); } t.stop( ">> CardModuleService::deauthenticateEx" ); }
+
+    inline Marshaller::u1Array* authenticateEx( const unsigned char& m, const unsigned char& r, Marshaller::u1Array* p ) { /*Timer t; t.start( );*/ Marshaller::u1Array* a = 0; try {  Invoke(3, 0x5177, MARSHALLER_TYPE_IN_U1, m, MARSHALLER_TYPE_IN_U1, r, MARSHALLER_TYPE_IN_U1ARRAY, p, MARSHALLER_TYPE_RET_U1ARRAY, &a);  } catch( Marshaller::Exception& x ) { checkException( x ); } /*t.stop( ">> CardModuleService::authenticateEx");*/ return a; }
+
+    void checkException( Marshaller::Exception & );
+
+    SMARTCARD_TYPE m_ucSmartCardType;
+
+    Timer m_Timer;
+
+    PROPERTIES m_Properties;
+
+};
+
+#endif // __GEMALTO_CARD_MODULE_SERVICE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,355 @@
+
+#include "Configuration.hpp"
+//#include "Util.h"
+//#include "Singleton.h"
+//#include "Context.h"
+
+#include <fstream>
+#include <iostream>
+#include <algorithm> // remove(), erase()
+
+//namespace Gemalto
+//{
+
+/*
+*/
+Configuration::Configuration( )
+{
+	m_szConfigurationfilePath = "";
+}
+
+
+/*
+*/
+void Configuration::load( const std::string& configurationFileName )
+{
+	m_szConfigurationfilePath = configurationFileName;
+
+	if( false == parse( configurationFileName ) )
+	{
+		std::string msg = "## ERROR ## Failed opening configuration file (" + configurationFileName + ")";
+		std::cout  << msg <<  std::endl;
+		throw new std::exception( );
+	}
+}
+
+
+/*
+*/
+void Configuration::getConfigurationFilePath( std::string &result )
+{
+	result = m_szConfigurationfilePath;
+}
+
+
+///*
+//*/
+//void Configuration::print( )
+//{
+//	std::string msg = "print configuration <BEGIN>";
+//	Gemalto::Context::getInstance( ).getLog( ).write( msg );
+//
+//	for( TConfiguration::iterator i = m_configuration.begin( ); i != m_configuration.end( ); i++ )
+//	{
+//		std::string sectionName = (*i).first;
+//		msg = "CurrentSection <" + sectionName + ">";
+//		Gemalto::Context::getInstance( ).getLog( ).write( msg );
+
+//		TSection sectionMap = (*i).second;
+//		for( TSection::iterator j = sectionMap.begin( ); j != sectionMap.end( ); j++ )
+//		{
+//			std::string key = (*j).first;
+//			std::string value = (*j).second;
+//			msg = "    Key <" + key + "> - Value <" + value + ">";
+//			Gemalto::Context::getInstance( ).getLog( ).write( msg );
+//		}
+//	}
+//
+//	msg = "print configuration <END>";
+//	Gemalto::Context::getInstance( ).getLog( ).write( msg );
+//}
+
+
+/*
+*/
+bool Configuration::checkSection( const std::string& sectionName )
+{
+	// Find the section into the map of sections
+	TConfigurationIterator it = m_configuration.find( sectionName );
+	if( m_configuration.end( ) != it )
+	{
+		return true;
+	}
+	return false;
+}
+
+
+/*
+*/
+void Configuration::getValue( const std::string& sectionName, const std::string& keyName, std::string& value )
+{
+	// Find the section into the map of sections
+	TConfigurationIterator it = m_configuration.find( sectionName );
+	if( m_configuration.end( ) != it )
+	{
+		TSection section = it->second;
+
+		// Find the value into the map of entries of the selected section
+		TSectionIterator it2 = section.find( keyName );
+		if( section.end( ) != it2 )
+		{
+			value = it2->second;
+		}
+	}
+}
+
+
+/* Read the whole configuration file
+*/
+bool Configuration::parse( const std::string& configurationFileName )
+{
+	//std::string msg = "Configuration file name <" + configurationFileName + ">";
+	//std::cout  << " ==== " <<  std::endl;
+	//std::cout  << msg <<  std::endl;
+
+	// Open the configuration file
+	std::fstream file;
+	file.open( configurationFileName.c_str( ), std::ios_base::in );
+	if( !file )
+	{
+		return false;
+	}
+
+	// Get the file size
+	file.seekg( 0, std::ios_base::end );
+	std::streamoff size = file.tellg( );
+	file.seekg( 0, std::ios_base::beg );
+	//std::cout  << "FILE SIZE <" << size << ">" << std::endl;
+
+	// Read each line of the configuration file
+	std::string currentSectionName = "";
+	char cStopCharacter = '\n';
+	while( !file.eof( ) )
+	{
+		std::string tmp;
+		std::getline( file, tmp, cStopCharacter );
+		//std::cout  << "tmp <" << tmp << ">" << std::endl;
+		//std::cout  << "tmp.size <" << tmp.size( ) << ">" << std::endl;
+
+		// If the read line is the whole file
+		// Then we must restart the parsing changing the ned-line character
+		if( size == (int)tmp.size( ) )
+		{
+			// Reset the read offset to the beginning of the file
+			file.seekg( 0, std::ios_base::beg );
+
+			cStopCharacter = '\r';
+			tmp = "";
+			std::getline( file, tmp, cStopCharacter );
+			//std::cout  << "tmp AGAIN <" << tmp << ">" << std::endl;
+			//std::cout  << "tmp.size <" << tmp.size( ) << ">" << std::endl;
+			if( size == (int)tmp.size( ) )
+			{
+				std::cout << "## Error - The configuration file is not readable" << std::endl;
+
+				throw new std::exception;
+			}
+		}
+
+		std::string currentLine = "";
+		// Suppress all known end-of-line characters
+		suppressAllOccurencesOfThisCharacter( tmp, '\r', currentLine );
+		suppressAllOccurencesOfThisCharacter( currentLine, '\n', currentLine );			
+		//std::cout  << "currentLine <" << currentLine <<  ">" << std::endl;
+		if( currentLine.empty( ) )
+		{
+			// The current line is empty
+			// We must iterate the next current line
+			continue;
+		}
+
+		// Try to found a comment
+		std::string::size_type pos = findComment( currentLine );
+
+		// Try to find a tag before the comment
+		std::string::size_type end_pos = 0;
+		if( findTag( pos, end_pos, currentLine.substr( 0, pos ) ) )
+		{
+			// Isolate the potentiel tag
+			std::string tag = currentLine.substr( pos, end_pos - pos + 1 );
+
+			// Verify the tag is a real one 
+			// (check if the '[' and ']' characters are present)
+			if( isSection( tag ) )
+			{
+				getSectionName( tag, currentSectionName );
+
+				// Populate the section list with the new section
+				m_configuration.insert( TConfigurationPair( currentSectionName, TSection( ) ) );
+
+				//std::string msg = "CurrentSection <" + currentSectionName + ">";
+				//std::cout  << msg <<  std::endl;
+			}
+			else if( isKey( tag ) )
+			{
+				std::string currentKeyName = "";
+				getKeyName( tag, currentKeyName );
+
+				std::string currentKeyValue = "";
+				getKeyValue( tag, currentKeyValue );
+
+				m_configuration[ currentSectionName ].insert( TEntryPair( currentKeyName, currentKeyValue ) );
+
+				//std::string msg = "    Key <" + currentKeyName + "> - Value <" + currentKeyValue + ">";
+				//std::cout  << msg <<  std::endl;
+			}
+		}
+	}
+
+	file.close( );
+
+	//std::cout  << " ==== " <<  std::endl;
+
+	return true;
+} 
+
+
+/* Return the index of the comment into the incomming string.
+A comment is marked with with the ';' character
+*/
+std::string::size_type Configuration::findComment( const std::string& str )
+{
+	return str.find( ";" );
+}
+
+
+/*
+*/
+bool Configuration::findTag( std::string::size_type& start, std::string::size_type& end, const std::string& str )
+{
+	start = str.find_first_not_of( " \t" );
+	if( start == std::string::npos )
+	{
+		return false;
+	}
+
+	end = str.find_last_not_of( " \t" );
+	if( end == std::string::npos )
+	{
+		return false;
+	}
+
+	if( start >= end )
+	{
+		return false;
+	}
+
+	return true;
+}
+
+
+/*
+*/
+void Configuration::strip( const std::string& str, std::string &result, const std::string& what )
+{
+	if( false == str.empty( ) )
+	{
+		std::string::size_type start = str.find_first_not_of( what );
+		std::string::size_type end = str.find_last_not_of( what );
+
+		if( ( std::string::npos != start ) && ( std::string::npos != end ) )
+		{
+			result.assign( str.substr( start, end - start + 1 ) );
+		}
+	}
+}
+
+
+/*
+*/
+bool Configuration::isSection( const std::string& str )
+{
+	std::string::size_type size = str.size( );
+
+	if( size <= 2 )
+	{
+		return false;
+	}
+
+	if( ( str[ 0 ] == '[' ) && ( str[ size - 1 ] == ']' ) )
+	{
+		std::string tmp = "";
+		strip( str.substr( 1, size - 2 ), tmp );
+		if( false == tmp.empty( ) )
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+
+/*
+*/
+bool Configuration::isKey( const std::string& str )
+{
+	if( str.size() < 2 )
+		return false;
+
+	std::string::size_type pos = str.find( "=" );
+
+	if( pos == 0 || pos == std::string::npos )
+		return false;
+
+	return true;
+}
+
+
+/*
+*/
+void Configuration::getKeyName( const std::string& str, std::string &result )
+{
+	std::string::size_type pos = str.find_first_of( " \t=" );
+	if( std::string::npos != pos )
+	{
+		result.assign( str.substr( 0, pos ) );
+	}
+}
+
+
+/*
+*/
+void Configuration::getKeyValue( const std::string& str, std::string &result )
+{
+	std::string::size_type start = str.find( "=" );
+	std::string::size_type pos = str.find_first_not_of( " \t=", start );
+
+	if( std::string::npos != pos )
+	{
+		std::string tmp = str.substr( pos );
+		result.assign( tmp );
+	}
+}
+
+
+/*
+*/
+void Configuration::getSectionName( const std::string& str, std::string &result )
+{
+	strip( str.substr( 1, str.size( ) - 2 ), result );
+}
+
+
+
+
+/* Suppress all occurences of the targeted character
+*/
+void Configuration::suppressAllOccurencesOfThisCharacter( const std::string& s, char c, std::string& result )
+{ 
+	result = s;
+	result.erase( std::remove( result.begin( ), result.end( ), c ), result.end( ) ); 
+}   
+
+
+//} //namespace

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Configuration.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,75 @@
+
+
+#ifndef __CONFIGURATION_H__
+#define __CONFIGURATION_H__
+
+
+#include <map>
+#include <string>
+
+//namespace Gemalto
+//{
+
+	// A entry is a map of {key,value} pair
+	typedef std::pair<std::string, std::string> TEntryPair;
+
+	// A section is a map of {key,value} pairs (an entry)
+	typedef std::map<std::string, std::string> TSection;
+	typedef TSection::iterator TSectionIterator;
+
+	// A Configuration is a map of sections
+	typedef std::map<std::string, TSection> TConfiguration;
+	typedef TConfiguration::iterator TConfigurationIterator;
+	typedef std::pair<std::string, TSection> TConfigurationPair;
+
+
+	/*
+	*/
+	class Configuration
+	{
+
+	public:
+		
+		Configuration( ); // Constructor is hidden
+
+		void load( const std::string& szConfigurationFileName );
+
+		void getValue( const std::string& sectionName, const std::string& parameterName, std::string &result );
+
+		void getConfigurationFilePath( std::string &result );
+
+		bool checkSection( const std::string& sectionName );
+
+		void print( );
+
+	private:
+
+		std::string m_szConfigurationfilePath;
+
+		TConfiguration m_configuration;
+
+		void strip( const std::string& str, std::string &result, const std::string& what = " \t\0\n" );
+
+		bool parse( const std::string& configurationFileName );
+
+		std::string::size_type findComment( const std::string& str );
+
+		bool findTag( std::string::size_type& start, std::string::size_type& end, const std::string& str );
+
+		bool isSection( const std::string& str );
+
+		bool isKey( const std::string& str );
+
+		void getKeyName( const std::string& str, std::string &result );
+
+		void getKeyValue( const std::string& str, std::string &result );
+
+		void getSectionName( const std::string& str, std::string &result );
+
+		void suppressAllOccurencesOfThisCharacter( const std::string& s, char c, std::string& result );
+
+	};
+
+//} //namespace
+
+#endif // __CONFIGURATION_H__

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Digest.cpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Digest.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Digest.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,76 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <cstdlib>
+#include <cstring>
+#include "cryptoki.h"
+#include "digest.h"
+#include <memory>
+
+CDigest::CDigest(){
+    _counter       = 0;
+    _workingOffset = 0;
+    _workingLength = 0;
+}
+
+CDigest::~CDigest(){
+    free(_hashValue);
+    free(_workingBuffer);
+}
+
+void CDigest::hashCore( CK_BYTE_PTR data, const CK_LONG& a_ulOffset, const CK_LONG& a_ulCount )
+{
+	CK_LONG count = a_ulCount;
+	CK_LONG offset = a_ulOffset;
+
+    while (count > 0)
+    {
+        // prepare working buffer.
+        if ((_workingOffset + count) >= _blockLength){
+            _workingLength = _blockLength - _workingOffset;
+        }
+        else{
+            _workingLength = count;
+        }
+
+        memcpy(&_workingBuffer[_workingOffset],&data[offset],_workingLength);
+
+        _workingOffset += _workingLength;
+        count -= _workingLength;
+        offset += _workingLength;
+
+        if ((_workingOffset == _blockLength) && (count > 0)){
+
+            TransformBlock(_workingBuffer,_counter,_hashValue);
+
+            _counter += _blockLength;
+            _workingOffset = 0;
+        }
+    }
+}
+
+void CDigest::hashFinal(CK_BYTE_PTR hash)
+{
+    TransformFinalBlock(_workingBuffer,_workingOffset,_counter,_hashValue);
+    memcpy(hash,_hashValue,_hashLength);
+}
+
+
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/DigestMD5.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/DigestMD5.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/DigestMD5.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,78 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#include <cstdlib>
+#include <cstring>
+
+#include "cryptoki.h"
+#include "md5.h"
+#include "algo_md5.h"
+
+
+CMD5::CMD5(){
+    _hashValue     = (CK_BYTE_PTR)malloc(MD5_HASH_LENGTH);
+    _workingBuffer = (CK_BYTE_PTR)malloc(MD5_BLOCK_LENGTH);
+    _hashLength    = MD5_HASH_LENGTH;
+    _blockLength   = MD5_BLOCK_LENGTH;
+}
+
+CMD5::~CMD5(){
+}
+
+void CMD5::TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result)
+{
+    algo_md5_context ctx;
+
+    ctx.digest = (u4*)result;
+
+    if (counter == 0) {
+		algo_md5_starts(&ctx);
+    } else {
+        ctx.total[0] = counter;
+        ctx.total[1] = 0;
+    }
+
+    algo_md5_update(&ctx, data, MD5_BLOCK_LENGTH);
+}
+
+void CMD5::TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result)
+{
+    algo_md5_context ctx;
+
+    ctx.digest = (u4*)result;
+
+    if (counter == 0) {
+		algo_md5_starts(&ctx);
+    } else {
+        ctx.total[0] = counter;
+        ctx.total[1] = 0;
+    }
+
+    // allocate tempory working buffer
+    ctx.input = (u1*)malloc(MD5_BLOCK_LENGTH);
+    memset(ctx.input,0,MD5_BLOCK_LENGTH);
+
+    algo_md5_update(&ctx,data,length);
+    algo_md5_finish(&ctx);
+
+    free(ctx.input);
+}
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA1.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA1.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA1.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,76 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <cstdlib>
+#include <cstring>
+
+#include "cryptoki.h"
+#include "digest.h"
+#include "sha1.h"
+#include <memory>
+
+CSHA1::CSHA1(){
+    _hashValue     = (CK_BYTE_PTR)malloc(SHA1_HASH_LENGTH);
+    _workingBuffer = (CK_BYTE_PTR)malloc(SHA1_BLOCK_LENGTH);
+    _hashLength    = SHA1_HASH_LENGTH;
+    _blockLength   = SHA1_BLOCK_LENGTH;
+}
+
+CSHA1::~CSHA1(){
+}
+
+void CSHA1::TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result)
+{
+    algo_sha1_context ctx;
+
+    ctx.digest = (unsigned int*)result;
+
+    if (counter == 0) {
+		algo_sha1_starts(&ctx);
+    } else {
+        ctx.total[0] = counter;
+        ctx.total[1] = 0;
+    }
+
+    algo_sha1_update(&ctx, data, SHA1_BLOCK_LENGTH);
+}
+
+void CSHA1::TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result)
+{
+    algo_sha1_context ctx;
+
+    ctx.digest = (unsigned int*)result;
+
+    if (counter == 0) {
+		algo_sha1_starts(&ctx);
+    } else {
+        ctx.total[0] = counter;
+        ctx.total[1] = 0;
+    }
+
+    ctx.input = (unsigned char*)malloc(SHA1_BLOCK_LENGTH);
+    memset(ctx.input,0,SHA1_BLOCK_LENGTH);
+
+    algo_sha1_update(&ctx, data, length);
+    algo_sha1_finish(&ctx);
+
+    free(ctx.input);
+}
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA256.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA256.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/DigestSHA256.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,80 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <cstdlib>
+#include <cstring>
+
+#include "cryptoki.h"
+#include "digest.h"
+#include "sha256.h"
+
+CSHA256::CSHA256(){
+    _hashValue     = (CK_BYTE_PTR)malloc(SHA256_HASH_LENGTH);
+    _workingBuffer = (CK_BYTE_PTR)malloc(SHA256_BLOCK_LENGTH);
+    _hashLength    = SHA256_HASH_LENGTH;
+    _blockLength   = SHA256_BLOCK_LENGTH;
+}
+
+CSHA256::~CSHA256(){
+}
+
+void CSHA256::TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result)
+{
+    algo_sha256_context* ctx = (algo_sha256_context*)malloc(sizeof(algo_sha256_context));
+
+    ctx->digest = (u4*)result;
+
+    if (counter == 0) {
+		algo_sha256_starts(ctx);
+    } else {
+        ctx->total[0] = counter;
+        ctx->total[1] = 0;
+    }
+
+    algo_sha256_update(ctx, data, SHA256_BLOCK_LENGTH);
+
+    free((u1*)ctx);
+}
+
+void CSHA256::TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result)
+{
+    algo_sha256_context* ctx = (algo_sha256_context*)malloc(sizeof(algo_sha256_context));
+
+    ctx->digest = (u4*)result;
+
+    if (counter == 0) {
+		algo_sha256_starts(ctx);
+    } else {
+        ctx->total[0] = counter;
+        ctx->total[1] = 0;
+    }
+
+    // allocate tempory working buffer
+    ctx->input = (u1*)malloc(SHA256_BLOCK_LENGTH);
+    memset(ctx->input, 0,SHA256_BLOCK_LENGTH);
+
+    // warning: algo_sha1_update must not throw any exception.
+    algo_sha256_update(ctx, data, length);
+    algo_sha256_finish(ctx);
+
+    free(ctx->input);
+    free((u1*)ctx);
+}
+

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/Except.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Except.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Except.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,334 +1,335 @@
 /*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
 
 #ifndef _include_marshaller_except_h
 #define _include_marshaller_except_h
 
-MARSHALLER_NS_BEGIN
+#include <stdexcept>
 
-// .NET specific exception classes
+    MARSHALLER_NS_BEGIN
+
+    // .NET specific exception classes
 class Exception  : public std::runtime_error{
 
 public:
-	explicit Exception(std::string msg): std::runtime_error(msg) { }
-	const char *what() const throw(){
-		return std::runtime_error::what();
-	}
+    explicit Exception(std::string msg): std::runtime_error(msg) { }
+    const char *what() const throw(){
+        return std::runtime_error::what();
+    }
 };
 
 class SystemException : public Exception{
 
 public:
-	explicit SystemException(std::string msg) : Exception(msg) { }
-	explicit SystemException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit SystemException(std::string msg) : Exception(msg) { }
+    explicit SystemException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 };
 
 class ArgumentException : public Exception{
 
 public:
-	explicit ArgumentException(std::string msg) : Exception(msg) { }
-	explicit ArgumentException();
-	explicit ArgumentException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ArgumentException(std::string msg) : Exception(msg) { }
+    explicit ArgumentException();
+    explicit ArgumentException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class ArgumentNullException : public Exception{
 
 public:
-	explicit ArgumentNullException(std::string msg) : Exception(msg) { }
-	explicit ArgumentNullException();
-	explicit ArgumentNullException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ArgumentNullException(std::string msg) : Exception(msg) { }
+    explicit ArgumentNullException();
+    explicit ArgumentNullException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class ArgumentOutOfRangeException : public Exception{
 
 public:
-	explicit ArgumentOutOfRangeException(std::string msg) : Exception(msg) { }
-	explicit ArgumentOutOfRangeException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ArgumentOutOfRangeException(std::string msg) : Exception(msg) { }
+    explicit ArgumentOutOfRangeException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class IndexOutOfRangeException : public Exception{
 
 public:
-	explicit IndexOutOfRangeException(std::string  msg) : Exception(msg) { }
-	explicit IndexOutOfRangeException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit IndexOutOfRangeException(std::string  msg) : Exception(msg) { }
+    explicit IndexOutOfRangeException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class InvalidCastException : public Exception{
 
 public:
-	explicit InvalidCastException(std::string  msg) : Exception(msg) { }
-	explicit InvalidCastException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit InvalidCastException(std::string  msg) : Exception(msg) { }
+    explicit InvalidCastException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class InvalidOperationException : public Exception{
 
 public:
-	explicit InvalidOperationException(std::string msg) : Exception(msg) { }
-	explicit InvalidOperationException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit InvalidOperationException(std::string msg) : Exception(msg) { }
+    explicit InvalidOperationException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class NotImplementedException : public Exception{
 
 public:
-	explicit NotImplementedException(std::string msg) : Exception(msg) { }
-	explicit NotImplementedException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit NotImplementedException(std::string msg) : Exception(msg) { }
+    explicit NotImplementedException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class NotSupportedException : public Exception{
 
 public:
-	explicit NotSupportedException(std::string msg) : Exception(msg) { }
-	explicit NotSupportedException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit NotSupportedException(std::string msg) : Exception(msg) { }
+    explicit NotSupportedException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class NullReferenceException : public Exception{
 
 public:
-	explicit NullReferenceException(std::string msg) : Exception(msg) { }
-	explicit NullReferenceException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit NullReferenceException(std::string msg) : Exception(msg) { }
+    explicit NullReferenceException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class OutOfMemoryException : public Exception{
 
 public:
-	explicit OutOfMemoryException(std::string msg) : Exception(msg) { }
-	explicit OutOfMemoryException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit OutOfMemoryException(std::string msg) : Exception(msg) { }
+    explicit OutOfMemoryException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class UnauthorizedAccessException : public Exception{
 
 public:
-	explicit UnauthorizedAccessException(std::string msg) : Exception(msg) { }
-	explicit UnauthorizedAccessException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit UnauthorizedAccessException(std::string msg) : Exception(msg) { }
+    explicit UnauthorizedAccessException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class ObjectDisposedException : public Exception{
 
 public:
-	explicit ObjectDisposedException(std::string msg) : Exception(msg) { }
-	explicit ObjectDisposedException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ObjectDisposedException(std::string msg) : Exception(msg) { }
+    explicit ObjectDisposedException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class ApplicationException : public Exception{
 
 public:
-	explicit ApplicationException(std::string msg) : Exception(msg) { }
-	explicit ApplicationException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ApplicationException(std::string msg) : Exception(msg) { }
+    explicit ApplicationException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class ArithmeticException : public Exception{
 
 public:
-	explicit ArithmeticException(std::string msg) : Exception(msg) { }
-	explicit ArithmeticException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ArithmeticException(std::string msg) : Exception(msg) { }
+    explicit ArithmeticException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class ArrayTypeMismatchException : public Exception{
 
 public:
-	explicit ArrayTypeMismatchException(std::string msg) : Exception(msg) { }
-	explicit ArrayTypeMismatchException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit ArrayTypeMismatchException(std::string msg) : Exception(msg) { }
+    explicit ArrayTypeMismatchException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class BadImageFormatException : public Exception{
 
 public:
-	explicit BadImageFormatException(std::string msg) : Exception(msg) { }
-	explicit BadImageFormatException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit BadImageFormatException(std::string msg) : Exception(msg) { }
+    explicit BadImageFormatException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class CryptographicException : public Exception{
 
 public:
-	explicit CryptographicException(std::string msg) : Exception(msg) { }
-	explicit CryptographicException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit CryptographicException(std::string msg) : Exception(msg) { }
+    explicit CryptographicException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class DirectoryNotFoundException : public Exception{
 
 public:
-	explicit DirectoryNotFoundException(std::string msg) : Exception(msg) { }
-	explicit DirectoryNotFoundException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit DirectoryNotFoundException(std::string msg) : Exception(msg) { }
+    explicit DirectoryNotFoundException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class DivideByZeroException : public Exception{
 
 public:
-	explicit DivideByZeroException(std::string msg) : Exception(msg) { }
-	explicit DivideByZeroException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit DivideByZeroException(std::string msg) : Exception(msg) { }
+    explicit DivideByZeroException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class FileNotFoundException : public Exception{
 
 public:
-	explicit FileNotFoundException(std::string msg) : Exception(msg) { }
-	explicit FileNotFoundException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit FileNotFoundException(std::string msg) : Exception(msg) { }
+    explicit FileNotFoundException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class FormatException : public Exception{
 
 public:
-	explicit FormatException(std::string msg) : Exception(msg) { }
-	explicit FormatException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit FormatException(std::string msg) : Exception(msg) { }
+    explicit FormatException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class IOException : public Exception{
 
 public:
-	explicit IOException(std::string msg) : Exception(msg) { }
-	explicit IOException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit IOException(std::string msg) : Exception(msg) { }
+    explicit IOException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class RankException : public Exception{
 
 public:
-	explicit RankException(std::string msg) : Exception(msg) { }
-	explicit RankException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit RankException(std::string msg) : Exception(msg) { }
+    explicit RankException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
-class RemotingException : public Exception{
 
+/*
+*/
+class RemotingException : public Exception {
+
 private:
-	s4 resultCode;	// this code is for PCSC releated error/success codes
 
+    long m_ResultCode;
+
 public:
-	explicit RemotingException(std::string msg) : Exception(msg) {
-		this->resultCode = 0;
-	}
-	explicit RemotingException(char *msg) : Exception(NULL != msg ? msg : "") {
-		this->resultCode = 0;
-	}
-	explicit RemotingException(std::string msg,s4 resultCode) : Exception(msg){
-		this->resultCode = resultCode;
-	}
-	explicit RemotingException(char *msg,s4 resultCode) : Exception(NULL != msg ? msg : ""){
-		this->resultCode = resultCode;
-	}
-	explicit RemotingException(s4 resultCode) : Exception(""){
-		this->resultCode = resultCode;
-	}
-	s4 getResultCode(){
-		return this->resultCode;
-	}
+
+    explicit RemotingException( const std::string& msg ) : Exception( msg ) { m_ResultCode = 0; }
+
+    explicit RemotingException( const char *msg ) : Exception( NULL != msg ? msg : "" ) { m_ResultCode = 0; }
+    
+    explicit RemotingException( const std::string& msg, const long& a_resultCode ) : Exception( msg ) { m_ResultCode = a_resultCode; }
+    
+    explicit RemotingException( const char *msg, const long& a_resultCode ) : Exception( NULL != msg ? msg : "" ){ m_ResultCode = a_resultCode; }
+
+    explicit RemotingException( const long& a_resultCode ) : Exception( "" ) { m_ResultCode = a_resultCode; }
+    
+    long getResultCode( void ) { return m_ResultCode; }
 };
 
+
 class StackOverflowException : public Exception{
 
 public:
-	explicit StackOverflowException(std::string msg) : Exception(msg) { }
-	explicit StackOverflowException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit StackOverflowException(std::string msg) : Exception(msg) { }
+    explicit StackOverflowException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class TypeLoadException : public Exception{
 
 public:
-	explicit TypeLoadException(std::string msg) : Exception(msg) { }
-	explicit TypeLoadException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit TypeLoadException(std::string msg) : Exception(msg) { }
+    explicit TypeLoadException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class MemberAccessException : public Exception{
 
 public:
-	explicit MemberAccessException(std::string msg) : Exception(msg) { }
-	explicit MemberAccessException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit MemberAccessException(std::string msg) : Exception(msg) { }
+    explicit MemberAccessException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class MissingFieldException : public Exception{
 
 public:
-	explicit MissingFieldException(std::string msg) : Exception(msg) { }
-	explicit MissingFieldException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit MissingFieldException(std::string msg) : Exception(msg) { }
+    explicit MissingFieldException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class MissingMemberException : public Exception{
 
 public:
-	explicit MissingMemberException(std::string msg) : Exception(msg) { }
-	explicit MissingMemberException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit MissingMemberException(std::string msg) : Exception(msg) { }
+    explicit MissingMemberException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class MissingMethodException : public Exception{
 
 public:
-	explicit MissingMethodException(std::string msg) : Exception(msg) { }
-	explicit MissingMethodException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit MissingMethodException(std::string msg) : Exception(msg) { }
+    explicit MissingMethodException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class OverflowException : public Exception{
 
 public:
-	explicit OverflowException(std::string msg) : Exception(msg) { }
-	explicit OverflowException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit OverflowException(std::string msg) : Exception(msg) { }
+    explicit OverflowException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class SecurityException : public Exception{
 
 public:
-	explicit SecurityException(std::string msg) : Exception(msg) { }
-	explicit SecurityException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit SecurityException(std::string msg) : Exception(msg) { }
+    explicit SecurityException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class VerificationException : public Exception{
 
 public:
-	explicit VerificationException(std::string msg) : Exception(msg) { }
-	explicit VerificationException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit VerificationException(std::string msg) : Exception(msg) { }
+    explicit VerificationException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 
 class SerializationException : public Exception{
 
 public:
-	explicit SerializationException(std::string msg) : Exception(msg) { }
-	explicit SerializationException(char *msg) : Exception(NULL != msg ? msg : "") { }
+    explicit SerializationException(std::string msg) : Exception(msg) { }
+    explicit SerializationException(const char *msg) : Exception(NULL != msg ? msg : "") { }
 
 };
 

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/IDeviceMonitorListener.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/IDeviceMonitorListener.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/IDeviceMonitorListener.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,46 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_DEVICE_MONITOR_LISTENER_INTERFACE__
+#define __GEMALTO_DEVICE_MONITOR_LISTENER_INTERFACE__
+
+
+/*
+*/
+class IDeviceMonitorListener {
+
+public:
+
+	virtual ~IDeviceMonitorListener( ) { }
+
+	virtual void notifyReaderInserted( const std::string& s ) = 0;
+	
+	virtual void notifyReaderRemoved( const std::string& s ) = 0;
+	
+	virtual void notifySmartCardRemoved( const std::string& s ) = 0;
+	
+	virtual void notifySmartCardInserted( const std::string& s ) = 0;
+
+	virtual void notifySmartCardChanged( const std::string& s ) = 0;
+
+};
+
+#endif // __GEMALTO_DEVICE_MONITOR_LISTENER_INTERFACE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Log.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Log.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Log.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,2357 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <string.h>
+#include <stdio.h>
+
+#include "Log.hpp"
+
+
+#ifdef WIN32
+#include <Windows.h>
+clock_t Log::m_clockStart;
+#else
+timeval Log::m_clockStart;
+#endif
+
+bool Log::s_bEnableLog = false;
+
+const unsigned char T_BOOL = 0;
+#define T_BYTES 1
+#define T_LONG 2
+#define T_KEY_TYPE 3
+#define T_CERTIFICATE_TYPE 4
+#define T_CLASS 5
+#define T_DATE 6
+#define T_KEY_GEN_MECHANISM 7
+#define T_UNKNOWN 8
+
+
+
+//std::string Log::s_stLogFilePath = "/tmp";
+//std::string Log::s_stLogFile = "/tmp/Gemalto.NET.PKCS11.log";
+
+
+char Log::s_LogFilePath[ 255 ] = "";
+
+
+
+
+void Log::setLogPath( const std::string& stPath ) { 
+
+    std::string s = stPath + std::string( "/Gemalto.NET.PKCS11.log" );  
+    
+    memset( s_LogFilePath, 0, sizeof( s_LogFilePath ) ); 
+    
+    if( s.length( ) < sizeof( s_LogFilePath ) ) { 
+    
+        memcpy( s_LogFilePath, s.c_str( ), s.length( ) ); 
+    
+    } else { 
+        
+        char szDefaultPath[ ] = "/tmp/Gemalto.NET.PKCS11.log";
+        
+        memcpy( s_LogFilePath, szDefaultPath, sizeof( szDefaultPath ) );  
+    }
+}
+
+/* Log a message into the log file
+*/
+void Log::log( const char * format, ... )
+{
+	if( !Log::s_bEnableLog ) {
+	
+            return;
+	}
+
+    /*
+    if( Log::s_stLogFile.empty( ) ) {
+     
+        return;
+    }*/
+
+    try {
+		va_list args;
+
+	    // Try to open the file
+	    FILE* pLog = fopen( s_LogFilePath, "a" ); /*s_stLogFile.c_str( )*/
+	    if( pLog ) {
+			// Write the message to the log file
+			va_start( args, format );
+			vfprintf( pLog, format, args );
+			va_end( args );
+			fprintf(pLog, "\n");
+
+			// Close the file
+			fclose( pLog );
+	    }
+
+#ifndef WIN32
+	    // Write the message to stderr stream
+	    va_start( args, format );
+	    vfprintf( stderr, format, args );
+	    va_end( args );
+	    fprintf( stderr, "\n");
+    #else
+	    // Get the size of the buffer necessary to write the message
+	    // The size must be extended to include the '\n' and the '\0' characters.
+	    va_start( args, format );
+	    size_t len = _vscprintf( format, args );
+	    va_end( args );
+
+	    // Allocate the buffer for the message
+	    char *buffer = new char[ len + 2 ];
+	    memset( buffer, '\0', len + 2 );
+
+	    // Write the message into the buffer.
+	    va_start( args, format );
+	    vsprintf_s( buffer, len + 1, format, args );
+	    va_end( args );
+	    buffer[ len ] = '\n';
+
+	    // Write the message to the console
+	    OutputDebugString( buffer );
+
+	    // Release the buffer
+	    delete[] buffer;
+    #endif
+
+	    va_end( args );
+
+    } catch( ... ) { }
+}
+
+
+/*
+*/
+void Log::begin( const char* a_pMethod )
+{
+	log( "%s - <BEGIN>", a_pMethod );
+}
+
+
+/*
+*/
+void Log::end( const char* a_pMethod )
+{
+	log( "%s - <END>\n", a_pMethod );
+}
+
+
+/*
+*/
+void Log::in( const char* a_pMethod )
+{
+	log( "%s - [IN]", a_pMethod );
+}
+
+
+/*
+*/
+void Log::out( const char* a_pMethod )
+{
+	log( "%s - [OUT]", a_pMethod );
+}
+
+
+/*
+*/
+void Log::error( const char* a_pMethod, const char* a_pError )
+{
+	log( "%s - ## Error ## %s", a_pMethod, a_pError );
+}
+
+
+/*
+*/
+void Log::logCK_UTF8CHAR_PTR( const char* a_pName, const unsigned char* a_pBuffer, const std::size_t& a_Size )
+{
+	if( !s_bEnableLog ) {
+		
+        return;
+	}
+
+	if( a_pBuffer ) {
+
+        std::string s = "";
+		
+        toString( a_pBuffer, a_Size, s );
+	    
+        log( "%s - <%#02x> - size <%ld> - buffer <%s>", a_pName, a_pBuffer, a_Size, s.c_str( ) );
+	
+    } else {
+    
+        log( "%s - NULL_PTR", a_pName );
+    }
+}
+
+
+/*
+*/
+void Log::logCK_MECHANISM_INFO_PTR( const char* a_pMethod, CK_MECHANISM_INFO_PTR pInfo )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( pInfo ) {
+
+		std::string flags = "";
+		CK_FLAGS f = pInfo->flags;
+		mechanismFlagsToString( f, flags );
+
+		log( "%s - CK_MECHANISM_INFO - ulMinKeySize <%#02x> - ulMaxKeySize <%#02x> - flags <%s>", a_pMethod, pInfo->ulMinKeySize, pInfo->ulMaxKeySize, flags.c_str( ) );
+	}
+	else
+	{
+		log( "%s - CK_MECHANISM_INFO - NULL_PTR", a_pMethod );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_INFO( const char* a_pMethod, const CK_INFO_PTR pInfo )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( pInfo )
+	{
+		std::string s = "";
+		CK_INFOToString( pInfo, s );
+		log( "%s - CK_INFO <%s>", a_pMethod, s.c_str( ) );
+	}
+	else
+	{
+		log( "%s - CK_INFO <NULL_PTR>", a_pMethod );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_RV( const char* a_pMethod, const CK_RV& rv )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( CKR_OK == rv )
+	{
+		log( "%s - [RV] <0x00> (CKR_OK)", a_pMethod );
+	}
+	else
+	{
+		std::string s = "";
+		CK_RVToString( rv, s );
+		log( "%s - [RV] <%#02x> (%s)", a_pMethod, rv, s.c_str( ) );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_C_INITIALIZE_ARGS_PTR( const char* a_pMethod, CK_C_INITIALIZE_ARGS_PTR a_pArgs )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( a_pArgs )
+	{
+		//log( a_pMethod, "pInitArgs->CreateMutex <%#02x>", a_pArgs.CreateMutex );
+		log( "%s - CK_C_INITIALIZE_ARGS - DestroyMutex <%#02x> - LockMutex <%#02x> - UnlockMutex <%#02x> - flags <%#02x> - pReserved <%#02x>",
+			a_pMethod, a_pArgs->DestroyMutex, a_pArgs->LockMutex, a_pArgs->UnlockMutex, a_pArgs->flags, a_pArgs->pReserved );
+	}
+	else
+	{
+		log( "%s - CK_C_INITIALIZE_ARGS - CreateMutex <NULL_PTR> - DestroyMutex <NULL_PTR> - LockMutex <NULL_PTR> - UnlockMutex <NULL_PTR> - flags <NULL_PTR> - pReserved <NULL_PTR>", a_pMethod );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_SLOT_ID_PTR( const char* a_pMethod, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount )
+{
+	if( !s_bEnableLog ) {
+		return;
+    }
+
+	if( NULL_PTR == pSlotList )
+	{
+		log( "%s - CK_SLOT_ID_PTR - pulCount <%#02x> (%ld) - pSlotList <NULL_PTR>", a_pMethod, pulCount, ( NULL_PTR != pulCount ) ? *pulCount : 0 );
+	}
+	else
+	{
+		std::string sList = "";
+		if( NULL_PTR != pulCount )
+		{
+			for( size_t i = 0 ; i < (size_t)*pulCount ; i++ )
+			{
+				std::string s = "";
+				toString( (unsigned long) pSlotList[ i ], s );
+				sList += s;
+				if( i != (size_t)( *pulCount - 1 ) )
+				{
+					sList += ", " ;
+				}
+			}
+		}
+		log( "%s - CK_SLOT_ID_PTR - pulCount <%#02x> (%ld) - pSlotList <%#02x> (%s)", a_pMethod, pulCount, ( NULL_PTR != pulCount ) ? *pulCount : 0, pSlotList, sList.c_str( ) );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_SLOT_INFO_PTR( const char* a_pMethod, CK_SLOT_INFO_PTR pInfo )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( pInfo )
+	{
+		std::string slotDescription = "";
+		toString( pInfo->slotDescription, 64, slotDescription );
+
+		std::string manufacturerID = "";
+		toString( pInfo->manufacturerID, 32, manufacturerID );
+
+		std::string flags = "";
+		CK_FLAGS f = pInfo->flags;
+		slotFlagsToString( f, flags );
+
+		std::string hardwareVersion = "";
+		CK_VERSIONToString( &(pInfo->hardwareVersion), hardwareVersion );
+
+		std::string firmwareVersion = "";
+		CK_VERSIONToString( &(pInfo->firmwareVersion), firmwareVersion );
+
+		log( "%s - CK_SLOT_INFO_PTR - slotDescription <%s> - manufacturerID <%s> - flags <%s> - hardwareVersion <%s> - firmwareVersion <%s>",
+			a_pMethod, slotDescription.c_str( ), manufacturerID.c_str( ), flags.c_str( ), hardwareVersion.c_str( ), firmwareVersion.c_str( ) );
+	}
+	else
+	{
+		log( "%s - CK_SLOT_INFO_PTR - NULL_PTR", a_pMethod );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_TOKEN_INFO_PTR( const char* a_pMethod, CK_TOKEN_INFO_PTR pInfo )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( pInfo )
+	{
+		std::string label = "";
+		toString( pInfo->label, 32, label );
+
+		std::string manufacturerID = "";
+		toString( pInfo->manufacturerID, 32, manufacturerID );
+
+		std::string model = "";
+		toString( pInfo->model, 16, model );
+
+		std::string serialNumber = "";
+		toString( pInfo->serialNumber, 16, serialNumber );
+
+		std::string hardwareVersion = "";
+		CK_VERSIONToString( &(pInfo->hardwareVersion), hardwareVersion );
+
+		std::string firmwareVersion = "";
+		CK_VERSIONToString( &(pInfo->firmwareVersion), firmwareVersion );
+
+		std::string utcTime = "";
+		toString( pInfo->utcTime, 16, utcTime );
+
+		log( "%s - CK_TOKEN_INFO_PTR - <%#02x> - label <%s> - manufacturerID <%s> - model <%s> - serialNumber <%s> - flags <%#02x> - ulMaxSessionCount <%#02x> - ulSessionCount <%#02x> - \
+			 ulMaxRwSessionCount <%#02x> - ulRwSessionCount <%#02x> - ulMaxPinLen <%#02x> - ulMinPinLen <%#02x> - ulTotalPublicMemory <%#02x> - \
+			 ulFreePublicMemory <%#02x> - ulTotalPrivateMemory <%#02x> - ulFreePrivateMemory <%#02x> - hardwareVersion <%s> - \
+			 firmwareVersion <%s> - utcTime <%s>",
+			 a_pMethod,
+			 pInfo,
+			 label.c_str( ),
+			 manufacturerID.c_str( ),
+			 model.c_str( ),
+			 serialNumber.c_str( ),
+			 pInfo->flags,
+			 pInfo->ulMaxSessionCount,
+			 pInfo->ulSessionCount,
+			 pInfo->ulMaxRwSessionCount,
+			 pInfo->ulRwSessionCount,
+			 pInfo->ulMaxPinLen,
+			 pInfo->ulMinPinLen,
+			 pInfo->ulTotalPublicMemory,
+			 pInfo->ulFreePublicMemory,
+			 pInfo->ulTotalPrivateMemory,
+			 pInfo->ulFreePrivateMemory,
+			 hardwareVersion.c_str( ),
+			 firmwareVersion.c_str( ),
+			 utcTime.c_str( ) );
+	}
+	else
+	{
+		log( "%s - CK_TOKEN_INFO_PTR - <NULL_PTR>", a_pMethod );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_MECHANISM_TYPE( const char* a_pMethod, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    std::string s = "";
+	if( pMechanismList && pulCount )
+	{
+		CK_MECHANISM_TYPEToString( pMechanismList, *pulCount, s );
+	}
+	log( "%s - CK_MECHANISM_TYPE_PTR - pulCount <%#02x> (%ld) - pMechanismList <%#02x> (%s)", a_pMethod, pulCount, ( ( NULL_PTR != pulCount ) ? *pulCount : 0 ), pMechanismList, s.c_str( ) );
+}
+
+
+/*
+*/
+void Log::logCK_MECHANISM_TYPE( const char* a_pMethod, CK_MECHANISM_TYPE & ulMechanism )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    std::string s = "";
+	CK_MECHANISM_TYPEToString( ulMechanism, s );
+	log( "%s - CK_MECHANISM_TYPE <%s>", a_pMethod, s.c_str( ) );
+}
+
+
+/*
+*/
+void Log::logSessionFlags( const char* a_pMethod, CK_FLAGS & flags )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    std::string s = "";
+	sessionFlagsToString( flags, s );
+	log( "%s - CK_FLAGS <%s>", a_pMethod, s.c_str( ) );
+}
+
+
+/*
+*/
+void Log::logCK_SESSION_INFO_PTR( const char* a_pMethod, CK_SESSION_INFO_PTR pInfo )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( pInfo )
+	{
+		std::string s = "";
+		CK_SESSION_INFOToString( pInfo, s );
+		log( "%s - CK_SESSION_INFO <%#02x> (%s)", a_pMethod, pInfo, s.c_str( ) );
+	}
+	else
+	{
+		log( "%s - CK_SESSION_INFO <NULL_PTR>", a_pMethod );
+	}
+}
+
+
+/*
+*/
+void Log::logCK_USER_TYPE( const char* a_pMethod, CK_USER_TYPE &userType )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    std::string s = "";
+	CK_USER_TYPEToString( userType, s );
+	log( "%s - CK_USER_TYPE <%s>", a_pMethod, s.c_str( ) );
+}
+
+
+/*
+*/
+void Log::logCK_MECHANISM_PTR( const char* a_pMethod, CK_MECHANISM_PTR pMechanism )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    std::string s = "";
+	CK_MECHANISMToString( pMechanism, s );
+	log( "%s - CK_MECHANISM_PTR <%s>", a_pMethod, s.c_str( ) );
+}
+
+
+/*
+*/
+void Log::logCK_ATTRIBUTE_PTR( const char* a_pMethod, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG& ulCount )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    log( "%s - pTemplate <%#02x> - ulCount <%ld>", a_pMethod, pTemplate, ulCount );
+	if( pTemplate )
+	{
+		for( size_t i = 0; i < (size_t)ulCount; i++ )
+		{
+			CK_ATTRIBUTE a = pTemplate[ i ];
+			std::string attribute = "";
+			CK_ATTRIBUTEToString( &a, attribute );
+
+			log( "%s	- Attribute #%d - %s", a_pMethod, i, attribute.c_str( ) );
+		}
+	}
+}
+
+
+/*
+*/
+void Log::CK_MECHANISMToString( CK_MECHANISM_PTR m, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == m )
+	{
+		return;
+	}
+
+	std::string mechanismType = "";
+	CK_MECHANISM_TYPE t = m->mechanism;
+	CK_MECHANISM_TYPEToString( t, mechanismType );
+
+	std::string mechanismParam = "";
+	toString( (const unsigned char*)m->pParameter, m->ulParameterLen, mechanismParam );
+
+	toString( result,
+		"Type <%s> - Parameter <%s> - ParameterLen <%#02x>",
+		mechanismType.c_str( ),
+		mechanismParam.c_str( ),
+		m->ulParameterLen );
+}
+
+
+/*
+*/
+void Log::CK_ATTRIBUTEToString( const CK_ATTRIBUTE_PTR a, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == a )
+	{
+		return;
+	}
+
+	std::string t = "";
+	int type = T_UNKNOWN;
+	CK_ATTRIBUTE_TYPEToString( a->type, t, type );
+
+	if( ( (CK_ULONG)(-1) ) == a->ulValueLen )
+	{
+		toString( result, "Type <%s> - Length <-1> - Value <UNKNOWN>", t.c_str( ) );
+		return;
+	}
+    
+	std::string v = "";
+	if( NULL_PTR == a->pValue )
+	{
+		v = "null";
+	}
+	else
+	{
+		switch( type )
+		{
+		case T_BOOL:
+			toString( ((CK_BBOOL*)a->pValue)[0], v );
+			break;
+
+		case T_BYTES:
+			toString( (CK_BYTE_PTR) a->pValue, a->ulValueLen, v );
+			break;
+
+		case T_LONG:
+			toString( ((CK_ULONG*)a->pValue)[0], v );
+			break;
+
+		case T_KEY_TYPE:
+			CK_KEY_TYPEToString( ((CK_KEY_TYPE *)a->pValue)[0], v );
+			break;
+
+		case T_CERTIFICATE_TYPE:
+			CK_CERTIFICATE_TYPEToString( ((CK_CERTIFICATE_TYPE *)a->pValue)[0], v );
+			break;
+
+		case T_CLASS:
+			CK_OBJECT_CLASSToString( ((CK_OBJECT_CLASS *)a->pValue)[0], v );
+			break;
+
+		case T_DATE:
+			CK_DATEToString( (CK_DATE*) a->pValue, v );
+			break;
+
+		case T_KEY_GEN_MECHANISM:
+			CK_MECHANISM_TYPEToString( ((CK_MECHANISM_TYPE *)a->pValue)[0], v );
+			break;
+
+		default:
+			v = "UNPREDICTABLE VALUE";
+		}
+	}
+
+	toString( result, "Type <%s> - Length <%#02x> - Value <%s>", t.c_str( ), a->ulValueLen, v.c_str( ) );
+}
+
+
+/*
+*/
+void Log::CK_ATTRIBUTE_TYPEToString( const CK_ATTRIBUTE_TYPE& a, std::string &t, int& type )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( a )
+	{
+	case CKA_CLASS:
+		t = "CKA_CLASS";
+		type = T_CLASS;
+		break;
+
+	case CKA_TOKEN:
+		t = "CKA_TOKEN";
+		type = T_BOOL;
+		break;
+
+	case CKA_PRIVATE:
+		t = "CKA_PRIVATE";
+		type = T_BOOL;
+		break;
+
+	case CKA_LABEL:
+		t = "CKA_LABEL";
+		type = T_BYTES;
+		break;
+
+	case CKA_APPLICATION:
+		t = "CKA_APPLICATION";
+		type = T_BYTES;
+		break;
+
+	case CKA_VALUE:
+		t = "CKA_VALUE";
+		type = T_BYTES;
+		break;
+
+	case CKA_CERTIFICATE_TYPE:
+		t = "CKA_CERTIFICATE_TYPE";
+		type = T_CERTIFICATE_TYPE;
+		break;
+
+	case CKA_ISSUER:
+		t = "CKA_ISSUER";
+		type = T_BYTES;
+		break;
+
+	case CKA_SERIAL_NUMBER:
+		t = "CKA_SERIAL_NUMBER";
+		type = T_BYTES;
+		break;
+
+	case CKA_KEY_TYPE:
+		t = "CKA_KEY_TYPE";
+		type = T_KEY_TYPE;
+		break;
+
+	case CKA_SUBJECT:
+		t = "CKA_SUBJECT";
+		type = T_BYTES;
+		break;
+
+	case CKA_ID:
+		t = "CKA_ID";
+		type = T_BYTES;
+		break;
+
+	case CKA_SENSITIVE:
+		t = "CKA_SENSITIVE";
+		type = T_BOOL;
+		break;
+
+	case CKA_ENCRYPT:
+		t = "CKA_ENCRYPT";
+		type = T_BOOL;
+		break;
+
+	case CKA_DECRYPT:
+		t = "CKA_DECRYPT";
+		type = T_BOOL;
+		break;
+
+	case CKA_WRAP:
+		t = "CKA_WRAP";
+		type = T_BOOL;
+		break;
+
+	case CKA_UNWRAP:
+		t = "CKA_UNWRAP";
+		type = T_BOOL;
+		break;
+
+	case CKA_SIGN:
+		t = "CKA_SIGN";
+		type = T_BOOL;
+		break;
+
+	case CKA_SIGN_RECOVER:
+		t = "CKA_SIGN_RECOVER";
+		type = T_BOOL;
+		break;
+
+	case CKA_VERIFY:
+		t = "CKA_VERIFY";
+		type = T_BOOL;
+		break;
+
+	case CKA_VERIFY_RECOVER:
+		t = "CKA_VERIFY_RECOVER";
+		type = T_BOOL;
+		break;
+
+	case CKA_DERIVE:
+		t = "CKA_DERIVE";
+		type = T_BOOL;
+		break;
+
+	case CKA_START_DATE:
+		t = "CKA_START_DATE";
+		type = T_DATE;
+		break;
+
+	case CKA_END_DATE:
+		t = "CKA_END_DATE";
+		type = T_DATE;
+		break;
+
+	case CKA_MODULUS:
+		t = "CKA_MODULUS";
+		type = T_BYTES;
+		break;
+
+	case CKA_MODULUS_BITS:
+		t = "CKA_MODULUS_BITS";
+		type = T_LONG;
+		break;
+
+	case CKA_PUBLIC_EXPONENT:
+		t = "CKA_PUBLIC_EXPONENT";
+		type = T_BYTES;
+		break;
+
+	case CKA_PRIVATE_EXPONENT:
+		t = "CKA_PRIVATE_EXPONENT";
+		type = T_BYTES;
+		break;
+
+	case CKA_PRIME_1:
+		t = "CKA_PRIME_1";
+		type = T_BYTES;
+		break;
+
+	case CKA_PRIME_2:
+		t = "CKA_PRIME_2";
+		type = T_BYTES;
+		break;
+
+	case CKA_EXPONENT_1:
+		t = "CKA_EXPONENT_1";
+		type = T_BYTES;
+		break;
+
+	case CKA_EXPONENT_2:
+		t = "CKA_EXPONENT_2";
+		type = T_BYTES;
+		break;
+
+	case CKA_COEFFICIENT:
+		t = "CKA_COEFFICIENT";
+		type = T_BYTES;
+		break;
+
+	case CKA_PRIME:
+		t = "CKA_PRIME";
+		type = T_BYTES;
+		break;
+
+	case CKA_SUBPRIME:
+		t = "CKA_SUBPRIME";
+		type = T_BYTES;
+		break;
+
+	case CKA_BASE:
+		t = "CKA_BASE";
+		type = T_BYTES;
+		break;
+
+	case CKA_VALUE_BITS:
+		t = "CKA_VALUE_BITS";
+		type = T_BYTES;
+		break;
+
+	case CKA_VALUE_LEN:
+		t = "CKA_VALUE_LEN";
+		type = T_LONG;
+		break;
+
+	case CKA_EXTRACTABLE:
+		t = "CKA_EXTRACTABLE";
+		type = T_BOOL;
+		break;
+
+	case CKA_LOCAL:
+		t = "CKA_LOCAL";
+		type = T_BOOL;
+		break;
+
+	case CKA_NEVER_EXTRACTABLE:
+		t = "CKA_NEVER_EXTRACTABLE";
+		type = T_BOOL;
+		break;
+
+	case CKA_ALWAYS_SENSITIVE:
+		t = "CKA_ALWAYS_SENSITIVE";
+		type = T_BOOL;
+		break;
+
+	case CKA_MODIFIABLE:
+		t = "CKA_MODIFIABLE";
+		type = T_BOOL;
+		break;
+
+	case CKA_ECDSA_PARAMS:
+		t = "CKA_ECDSA_PARAMS";
+		type = T_BYTES;
+		break;
+
+	case CKA_EC_POINT:
+		t = "CKA_EC_POINT";
+		type = T_BYTES;
+		break;
+
+	case CKA_VENDOR_DEFINED:
+		t = "CKA_VENDOR_DEFINED";
+		type = T_BYTES;
+		break;
+
+		//case CKA_KEY_GEN_MECHANISM:
+		//	t = "CKA_KEY_GEN_MECHANISM";
+		//	type = T_KEY_GEN_MECHANISM;
+		//	break;
+
+	default:
+		toString( t, "UNKNOWN TYPE <%#02x>", a );
+		type = T_UNKNOWN;
+	}
+}
+
+
+/*
+*/
+void Log::CK_DATEToString( const CK_DATE* t, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == t )
+	{
+		return;
+	}
+
+	std::string year = "";
+	toString( t->year, 4, year );
+
+	std::string month = "";
+	toString( t->month, 2, month );
+
+	std::string day = "";
+	toString( t->day, 2, day );
+
+	result = "Year <" + year + "> - Month <" + month + "> - Day <" + day + ">";
+}
+
+
+/*
+*/
+void Log::CK_OBJECT_CLASSToString( const CK_OBJECT_CLASS& t, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( t )
+	{
+	case CKO_DATA:
+		result = "CKO_DATA";
+		break;
+
+	case CKO_CERTIFICATE:
+		result = "CKO_CERTIFICATE";
+		break;
+
+	case CKO_PUBLIC_KEY:
+		result = "CKO_PUBLIC_KEY";
+		break;
+
+	case CKO_PRIVATE_KEY:
+		result = "CKO_PRIVATE_KEY";
+		break;
+
+	case CKO_SECRET_KEY:
+		result = "CKO_SECRET_KEY";
+		break;
+
+	case CKO_VENDOR_DEFINED:
+		result = "CKO_VENDOR_DEFINED";
+		break;
+
+	default:
+		toString( result, "UNKNOWN OBJECT CLASS <%#02x>", t );
+	}
+}
+
+
+/*
+*/
+void Log::CK_KEY_TYPEToString( const CK_KEY_TYPE& t, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( t )
+	{
+	case CKK_RSA:
+		result = "CKK_RSA";
+		break;
+
+	case CKK_DSA:
+		result = "CKK_DSA";
+		break;
+
+	case CKK_ECDSA:
+		result = "CKK_ECDSA";
+		break;
+
+	case CKK_DH:
+		result = "CKK_DH";
+		break;
+
+	case CKK_KEA:
+		result = "CKK_KEA";
+		break;
+
+	case CKK_GENERIC_SECRET:
+		result = "CKK_GENERIC_SECRET";
+		break;
+
+	case CKK_RC2:
+		result = "CKK_RC2";
+		break;
+
+	case CKK_RC4:
+		result = "CKK_RC4";
+		break;
+
+	case CKK_DES:
+		result = "CKK_DES";
+		break;
+
+	case CKK_DES2:
+		result = "CKK_DES2";
+		break;
+
+	case CKK_DES3:
+		result = "CKK_DES3";
+		break;
+
+	case CKK_CAST:
+		result = "CKK_CAST";
+		break;
+
+	case CKK_CAST3:
+		result = "CKK_CAST3";
+		break;
+
+	case CKK_CAST5:
+		result = "CKK_CAST5/128";
+		break;
+
+	case CKK_RC5:
+		result = "CKK_RC5";
+		break;
+
+	case CKK_IDEA:
+		result = "CKK_IDEA";
+		break;
+
+	case CKK_SKIPJACK:
+		result = "CKK_SKIPJACK";
+		break;
+
+	case CKK_BATON:
+		result = "CKK_BATON";
+		break;
+
+	case CKK_JUNIPER:
+		result = "CKK_JUNIPER";
+		break;
+
+	case CKK_CDMF:
+		result = "CKK_CDMF";
+		break;
+
+	case CKK_VENDOR_DEFINED:
+		result = "CKK_VENDOR_DEFINED";
+		break;
+
+	default:
+		toString( result, "UNKNOWN KEY TYPE <%#02x>", t );
+	}
+}
+
+
+/*
+*/
+void Log::CK_CERTIFICATE_TYPEToString( const CK_CERTIFICATE_TYPE &t, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( t )
+	{
+	case CKC_X_509:
+		result = "CKC_X_509";
+		break;
+
+	case CKC_VENDOR_DEFINED:
+		result = "CKC_VENDOR_DEFINED";
+		break;
+
+	default:
+		toString( result, "UNKNOWN CERTIFICATE TYPE <%#02x>", t );
+	}
+}
+
+
+/*
+*/
+void Log::CK_INFOToString( CK_INFO_PTR pInfo, std::string& result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == pInfo )
+	{
+		return;
+	}
+
+	std::string cryptokiVersion = "";
+	CK_VERSIONToString( &(pInfo->cryptokiVersion), cryptokiVersion );
+
+	std::string manufacturerID = "";
+	toString( pInfo->manufacturerID, 32, manufacturerID );
+
+	std::string flags = "";
+	CK_FLAGS f = pInfo->flags;
+	toString( f, flags );
+
+	std::string libraryDescription = "";
+	toString( pInfo->libraryDescription, 32, libraryDescription );
+
+	std::string libraryVersion = "";
+	CK_VERSIONToString( &(pInfo->libraryVersion), libraryVersion );
+
+	result = "cryptokiVersion <" + cryptokiVersion
+		+ "> - manufacturerID <" + manufacturerID
+		+ "> - flags <" + flags
+		+ "> - libraryDescription <" + libraryDescription
+		+ "> - libraryVersion <" + libraryVersion
+		+ ">";
+}
+
+
+/*
+*/
+void Log::CK_RVToString( const CK_RV& rv, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( rv )
+	{
+	case CKR_OK:
+		result = "CKR_OK";
+		break;
+	case CKR_CANCEL:
+		result = "CKR_CANCEL";
+		break;
+	case CKR_HOST_MEMORY:
+		result = "CKR_HOST_MEMORY";
+		break;
+	case CKR_SLOT_ID_INVALID:
+		result = "CKR_SLOT_ID_INVALID";
+		break;
+	case CKR_GENERAL_ERROR:
+		result = "CKR_GENERAL_ERROR";
+		break;
+	case CKR_FUNCTION_FAILED:
+		result = "CKR_FUNCTION_FAILED";
+		break;
+	case CKR_ARGUMENTS_BAD:
+		result = "CKR_ARGUMENTS_BAD";
+		break;
+	case CKR_NO_EVENT:
+		result = "CKR_NO_EVENT";
+		break;
+	case CKR_NEED_TO_CREATE_THREADS:
+		result = "CKR_NEED_TO_CREATE_THREADS";
+		break;
+	case CKR_CANT_LOCK:
+		result = "CKR_CANT_LOCK";
+		break;
+	case CKR_ATTRIBUTE_READ_ONLY:
+		result = "CKR_ATTRIBUTE_READ_ONLY";
+		break;
+	case CKR_ATTRIBUTE_SENSITIVE:
+		result = "CKR_ATTRIBUTE_SENSITIVE";
+		break;
+	case CKR_ATTRIBUTE_TYPE_INVALID:
+		result = "CKR_ATTRIBUTE_TYPE_INVALID";
+		break;
+	case CKR_ATTRIBUTE_VALUE_INVALID:
+		result = "CKR_ATTRIBUTE_VALUE_INVALID";
+		break;
+	case CKR_DATA_INVALID:
+		result = "CKR_DATA_INVALID";
+		break;
+	case CKR_DATA_LEN_RANGE:
+		result = "CKR_DATA_LEN_RANGE";
+		break;
+	case CKR_DEVICE_ERROR:
+		result = "CKR_DEVICE_ERROR";
+		break;
+	case CKR_DEVICE_MEMORY:
+		result = "CKR_DEVICE_MEMORY";
+		break;
+	case CKR_DEVICE_REMOVED:
+		result = "CKR_DEVICE_REMOVED";
+		break;
+	case CKR_ENCRYPTED_DATA_INVALID:
+		result = "CKR_ENCRYPTED_DATA_INVALID";
+		break;
+	case CKR_ENCRYPTED_DATA_LEN_RANGE:
+		result = "CKR_ENCRYPTED_DATA_LEN_RANGE";
+		break;
+	case CKR_FUNCTION_CANCELED:
+		result = "CKR_FUNCTION_CANCELED";
+		break;
+	case CKR_FUNCTION_NOT_PARALLEL:
+		result = "CKR_FUNCTION_NOT_PARALLEL";
+		break;
+	case CKR_FUNCTION_NOT_SUPPORTED:
+		result = "CKR_FUNCTION_NOT_SUPPORTED";
+		break;
+	case CKR_KEY_HANDLE_INVALID:
+		result = "CKR_KEY_HANDLE_INVALID";
+		break;
+	case CKR_KEY_SIZE_RANGE:
+		result = "CKR_KEY_SIZE_RANGE";
+		break;
+	case CKR_KEY_TYPE_INCONSISTENT:
+		result = "CKR_KEY_TYPE_INCONSISTENT";
+		break;
+	case CKR_KEY_NOT_NEEDED:
+		result = "CKR_KEY_NOT_NEEDED";
+		break;
+	case CKR_KEY_CHANGED:
+		result = "CKR_KEY_CHANGED";
+		break;
+	case CKR_KEY_NEEDED:
+		result = "CKR_KEY_NEEDED";
+		break;
+	case CKR_KEY_INDIGESTIBLE:
+		result = "CKR_KEY_INDIGESTIBLE";
+		break;
+	case CKR_KEY_FUNCTION_NOT_PERMITTED:
+		result = "CKR_KEY_FUNCTION_NOT_PERMITTED";
+		break;
+	case CKR_KEY_NOT_WRAPPABLE:
+		result = "CKR_KEY_NOT_WRAPPABLE";
+		break;
+	case CKR_KEY_UNEXTRACTABLE:
+		result = "CKR_KEY_UNEXTRACTABLE";
+		break;
+	case CKR_MECHANISM_INVALID:
+		result = "CKR_MECHANISM_INVALID";
+		break;
+	case CKR_MECHANISM_PARAM_INVALID:
+		result = "CKR_MECHANISM_PARAM_INVALID";
+		break;
+	case CKR_OBJECT_HANDLE_INVALID:
+		result = "CKR_OBJECT_HANDLE_INVALID";
+		break;
+	case CKR_OPERATION_ACTIVE:
+		result = "CKR_OPERATION_ACTIVE";
+		break;
+	case CKR_OPERATION_NOT_INITIALIZED:
+		result = "CKR_OPERATION_NOT_INITIALIZED";
+		break;
+	case CKR_PIN_INCORRECT:
+		result = "CKR_PIN_INCORRECT";
+		break;
+	case CKR_PIN_INVALID:
+		result = "CKR_PIN_INVALID";
+		break;
+	case CKR_PIN_LEN_RANGE:
+		result = "CKR_PIN_LEN_RANGE";
+		break;
+	case CKR_PIN_EXPIRED:
+		result = "CKR_PIN_EXPIRED";
+		break;
+	case CKR_PIN_LOCKED:
+		result = "CKR_PIN_LOCKED";
+		break;
+	case CKR_SESSION_CLOSED:
+		result = "CKR_SESSION_CLOSED";
+		break;
+	case CKR_SESSION_COUNT:
+		result = "CKR_SESSION_COUNT";
+		break;
+	case CKR_SESSION_HANDLE_INVALID:
+		result = "CKR_SESSION_HANDLE_INVALID";
+		break;
+	case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
+		result = "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
+		break;
+	case CKR_SESSION_READ_ONLY:
+		result = "CKR_SESSION_READ_ONLY";
+		break;
+	case CKR_SESSION_EXISTS:
+		result = "CKR_SESSION_EXISTS";
+		break;
+	case CKR_SESSION_READ_ONLY_EXISTS:
+		result = "CKR_SESSION_READ_ONLY_EXISTS";
+		break;
+	case CKR_SESSION_READ_WRITE_SO_EXISTS:
+		result = "CKR_SESSION_READ_WRITE_SO_EXISTS";
+		break;
+	case CKR_SIGNATURE_INVALID:
+		result = "CKR_SIGNATURE_INVALID";
+		break;
+	case CKR_SIGNATURE_LEN_RANGE:
+		result = "CKR_SIGNATURE_LEN_RANGE";
+		break;
+	case CKR_TEMPLATE_INCOMPLETE:
+		result = "CKR_TEMPLATE_INCOMPLETE";
+		break;
+	case CKR_TEMPLATE_INCONSISTENT:
+		result = "CKR_TEMPLATE_INCONSISTENT";
+		break;
+	case CKR_TOKEN_NOT_PRESENT:
+		result = "CKR_TOKEN_NOT_PRESENT";
+		break;
+	case CKR_TOKEN_NOT_RECOGNIZED:
+		result = "CKR_TOKEN_NOT_RECOGNIZED";
+		break;
+	case CKR_TOKEN_WRITE_PROTECTED:
+		result = "CKR_TOKEN_WRITE_PROTECTED";
+		break;
+	case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
+		result = "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
+		break;
+	case CKR_UNWRAPPING_KEY_SIZE_RANGE:
+		result = "CKR_UNWRAPPING_KEY_SIZE_RANGE";
+		break;
+	case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
+		result = "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
+		break;
+	case CKR_USER_ALREADY_LOGGED_IN:
+		result = "CKR_USER_ALREADY_LOGGED_IN";
+		break;
+	case CKR_USER_NOT_LOGGED_IN:
+		result = "CKR_USER_NOT_LOGGED_IN";
+		break;
+	case CKR_USER_PIN_NOT_INITIALIZED:
+		result = "CKR_USER_PIN_NOT_INITIALIZED";
+		break;
+	case CKR_USER_TYPE_INVALID:
+		result = "CKR_USER_TYPE_INVALID";
+		break;
+	case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
+		result = "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
+		break;
+	case CKR_USER_TOO_MANY_TYPES:
+		result = "CKR_USER_TOO_MANY_TYPES";
+		break;
+	case CKR_WRAPPED_KEY_INVALID:
+		result = "CKR_WRAPPED_KEY_INVALID";
+		break;
+	case CKR_WRAPPED_KEY_LEN_RANGE:
+		result = "CKR_WRAPPED_KEY_LEN_RANGE";
+		break;
+	case CKR_WRAPPING_KEY_HANDLE_INVALID:
+		result = "CKR_WRAPPING_KEY_HANDLE_INVALID";
+		break;
+	case CKR_WRAPPING_KEY_SIZE_RANGE:
+		result = "CKR_WRAPPING_KEY_SIZE_RANGE";
+		break;
+	case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
+		result = "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
+		break;
+	case CKR_RANDOM_SEED_NOT_SUPPORTED:
+		result = "CKR_RANDOM_SEED_NOT_SUPPORTED";
+		break;
+	case CKR_RANDOM_NO_RNG:
+		result = "CKR_RANDOM_NO_RNG";
+		break;
+	case CKR_BUFFER_TOO_SMALL:
+		result = "CKR_BUFFER_TOO_SMALL";
+		break;
+	case CKR_SAVED_STATE_INVALID:
+		result = "CKR_SAVED_STATE_INVALID";
+		break;
+	case CKR_INFORMATION_SENSITIVE:
+		result = "CKR_INFORMATION_SENSITIVE";
+		break;
+	case CKR_STATE_UNSAVEABLE:
+		result = "CKR_STATE_UNSAVEABLE";
+		break;
+	case CKR_CRYPTOKI_NOT_INITIALIZED:
+		result = "CKR_CRYPTOKI_NOT_INITIALIZED";
+		break;
+	case CKR_CRYPTOKI_ALREADY_INITIALIZED:
+		result = "CKR_CRYPTOKI_ALREADY_INITIALIZED";
+		break;
+	case CKR_MUTEX_BAD:
+		result = "CKR_MUTEX_BAD";
+		break;
+	case CKR_MUTEX_NOT_LOCKED:
+		result = "CKR_MUTEX_NOT_LOCKED";
+		break;
+	case CKR_VENDOR_DEFINED:
+		result = "CKR_VENDOR_DEFINED";
+		break;
+	default:
+		toString( result, "UNKNOWN ERROR <%#02x>", rv );
+	}
+}
+
+
+/*
+*/
+void Log::toString( std::string &result, const char * format, ... )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    try {
+        result = "";
+
+	    // Get the size of the buffer necessary to write the message
+	    // The size must be extended to include the '\n' and the '\0' characters.
+	    va_list args;
+	    va_start( args, format );
+    #ifdef WIN32
+	    size_t len = _vscprintf( format, args );
+    #else
+	    char tmp[1];
+	    int len = vsnprintf( tmp, sizeof(tmp), format, args );
+    #endif
+	    va_end( args );
+
+	    // Allocate the buffer for the message
+	    char *buffer = new char[ len + 2 ];
+	    memset( buffer, '\0', len + 2 );
+
+	    // Write the message into the buffer.
+	    va_start( args, format );
+    #ifdef WIN32
+	    vsprintf_s( buffer, len + 1, format, args );
+    #else
+	    vsprintf( buffer, format, args );
+    #endif
+	    va_end( args );
+
+	    // Write the message to the string
+	    result = buffer;
+
+	    // Release the buffer
+	    delete[ ] buffer;
+    
+    } catch( ... ) {
+    
+        // An excpetion occurs if the format string is not properly
+        // set to accept all the incoming parameters
+    }
+}
+
+
+/*
+*/
+void Log::toString( const unsigned char* buffer, std::size_t size, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( ( NULL == buffer ) || ( size <= 0 ) )
+	{
+		//result.assign( "null" );
+		return;
+	}
+
+	std::ostringstream oss;
+	oss.rdbuf( )->str( "" );
+
+	// Afficher en héxadécimal et en majuscule
+	oss << std::hex << std::uppercase;
+
+	// Remplir les blancs avec des zéros
+	oss << std::setfill('0');
+
+	for( std::size_t i = 0; i < size; ++i )
+	{
+		// Séparer chaque octet par un espace
+		if (i != 0)
+			oss << ' ';
+
+		// Afficher sa valeur hexadécimale précédée de "0x"
+		// setw(2) permet de forcer l'affichage à 2 caractères
+		oss << /*"0x" <<*/ std::setw(2) << static_cast<int>( buffer[i] );
+	}
+
+	result.assign( oss.str( ) );
+}
+
+
+/*
+*/
+void Log::toString( const unsigned long &l, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    classtoString<unsigned long>( l, result );
+}
+
+
+/*
+*/
+template<typename T> void Log::classtoString( const T & value, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL == &value )
+	{
+		return;
+	}
+	std::ostringstream str;
+	str << value;
+	result.assign( str.str( ) );
+}
+
+
+/*
+*/
+void Log::slotFlagsToString( const CK_FLAGS& f, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    result = "";
+
+	// Slot Information Flags
+	if( f & CKF_TOKEN_PRESENT )
+	{
+		result += "CKF_TOKEN_PRESENT";
+	}
+
+	if( f & CKF_REMOVABLE_DEVICE )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_REMOVABLE_DEVICE";
+	}
+
+	if( f & CKF_HW_SLOT )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_HW_SLOT";
+	}
+}
+
+
+/*
+*/
+void Log::CK_VERSIONToString( CK_VERSION_PTR pVersion, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == pVersion )
+	{
+		return;
+	}
+
+	toString( result, "%#02x - %#02x", pVersion->major, pVersion->minor );
+}
+
+
+/*
+*/
+void Log::CK_MECHANISM_TYPEToString( CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG mechanismListLen, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == pMechanismList )
+	{
+		return;
+	}
+
+	result = "";
+
+	for( size_t i = 0 ; i < (size_t)mechanismListLen; i++ )
+	{
+		std::string m = "";
+		CK_MECHANISM_TYPEToString( pMechanismList[ i ], m );
+		result += m;
+		if( i != (size_t)( mechanismListLen - 1 ) )
+		{
+			result +=", ";
+		}
+	}
+}
+
+
+/*
+*/
+void Log::CK_MECHANISM_TYPEToString( const CK_MECHANISM_TYPE &t, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( t )
+	{
+	case CKM_RSA_PKCS_KEY_PAIR_GEN:
+		result = "CKM_RSA_PKCS_KEY_PAIR_GEN";
+		break;
+	case CKM_RSA_PKCS:
+		result = "CKM_RSA_PKCS";
+		break;
+	case CKM_RSA_9796:
+		result = "CKM_RSA_9796";
+		break;
+	case CKM_RSA_X_509:
+		result = "CKM_RSA_X_509";
+		break;
+	case CKM_MD2_RSA_PKCS:
+		result = "CKM_MD2_RSA_PKCS";
+		break;
+	case CKM_MD5_RSA_PKCS:
+		result = "CKM_MD5_RSA_PKCS";
+		break;
+	case CKM_SHA1_RSA_PKCS:
+		result = "CKM_SHA1_RSA_PKCS";
+		break;
+	case CKM_DSA_KEY_PAIR_GEN:
+		result = "CKM_DSA_KEY_PAIR_GEN";
+		break;
+	case CKM_DSA:
+		result = "CKM_DSA";
+		break;
+	case CKM_DSA_SHA1:
+		result = "CKM_DSA_SHA1";
+		break;
+	case CKM_DH_PKCS_KEY_PAIR_GEN:
+		result = "CKM_DH_PKCS_KEY_PAIR_GEN";
+		break;
+	case CKM_DH_PKCS_DERIVE:
+		result = "CKM_DH_PKCS_DERIVE";
+		break;
+	case CKM_RC2_KEY_GEN:
+		result = "CKM_RC2_KEY_GEN";
+		break;
+	case CKM_RC2_ECB:
+		result = "CKM_RC2_ECB";
+		break;
+	case CKM_RC2_CBC:
+		result = "CKM_RC2_CBC";
+		break;
+	case CKM_RC2_MAC:
+		result = "CKM_RC2_MAC";
+		break;
+	case CKM_RC2_MAC_GENERAL:
+		result = "CKM_RC2_MAC_GENERAL";
+		break;
+	case CKM_RC2_CBC_PAD:
+		result = "CKM_RC2_CBC_PAD";
+		break;
+	case CKM_RC4_KEY_GEN:
+		result = "CKM_RC4_KEY_GEN";
+		break;
+	case CKM_RC4:
+		result = "CKM_RC4";
+		break;
+	case CKM_DES_KEY_GEN:
+		result = "CKM_DES_KEY_GEN";
+		break;
+	case CKM_DES_ECB:
+		result = "CKM_DES_ECB";
+		break;
+	case CKM_DES_CBC:
+		result = "CKM_DES_CBC";
+		break;
+	case CKM_DES_MAC:
+		result = "CKM_DES_MAC";
+		break;
+	case CKM_DES_MAC_GENERAL:
+		result = "CKM_DES_MAC_GENERAL";
+		break;
+	case CKM_DES_CBC_PAD:
+		result = "CKM_DES_CBC_PAD";
+		break;
+	case CKM_DES2_KEY_GEN:
+		result = "CKM_DES2_KEY_GEN";
+		break;
+	case CKM_DES3_KEY_GEN:
+		result = "CKM_DES3_KEY_GEN";
+		break;
+	case CKM_DES3_ECB:
+		result = "CKM_DES3_ECB";
+		break;
+	case CKM_DES3_CBC:
+		result = "CKM_DES3_CBC";
+		break;
+	case CKM_DES3_MAC:
+		result = "CKM_DES3_MAC";
+		break;
+	case CKM_DES3_MAC_GENERAL:
+		result = "CKM_DES3_MAC_GENERAL";
+		break;
+	case CKM_DES3_CBC_PAD:
+		result = "CKM_DES3_CBC_PAD";
+		break;
+	case CKM_CDMF_KEY_GEN:
+		result = "CKM_CDMF_KEY_GEN";
+		break;
+	case CKM_CDMF_ECB:
+		result = "CKM_CDMF_ECB";
+		break;
+	case CKM_CDMF_CBC:
+		result = "CKM_CDMF_CBC";
+		break;
+	case CKM_CDMF_MAC:
+		result = "CKM_CDMF_MAC";
+		break;
+	case CKM_CDMF_MAC_GENERAL:
+		result = "CKM_CDMF_MAC_GENERAL";
+		break;
+	case CKM_CDMF_CBC_PAD:
+		result = "CKM_CDMF_CBC_PAD";
+		break;
+	case CKM_MD2:
+		result = "CKM_MD2";
+		break;
+	case CKM_MD2_HMAC:
+		result = "CKM_MD2_HMAC";
+		break;
+	case CKM_MD2_HMAC_GENERAL:
+		result = "CKM_MD2_HMAC_GENERAL";
+		break;
+	case CKM_MD5:
+		result = "CKM_MD5";
+		break;
+	case CKM_MD5_HMAC:
+		result = "CKM_MD5_HMAC";
+		break;
+	case CKM_MD5_HMAC_GENERAL:
+		result = "CKM_MD5_HMAC_GENERAL";
+		break;
+	case CKM_SHA_1:
+		result = "CKM_SHA_1";
+		break;
+	case CKM_SHA_1_HMAC:
+		result = "CKM_SHA_1_HMAC";
+		break;
+	case CKM_SHA_1_HMAC_GENERAL:
+		result = "CKM_SHA_1_HMAC_GENERAL";
+		break;
+	case CKM_CAST_KEY_GEN:
+		result = "CKM_CAST_KEY_GEN";
+		break;
+	case CKM_CAST_ECB:
+		result = "CKM_CAST_ECB";
+		break;
+	case CKM_CAST_CBC:
+		result = "CKM_CAST_CBC";
+		break;
+	case CKM_CAST_MAC:
+		result = "CKM_CAST_MAC";
+		break;
+	case CKM_CAST_MAC_GENERAL:
+		result = "CKM_CAST_MAC_GENERAL";
+		break;
+	case CKM_CAST_CBC_PAD:
+		result = "CKM_CAST_CBC_PAD";
+		break;
+	case CKM_CAST3_KEY_GEN:
+		result = "CKM_CAST3_KEY_GEN";
+		break;
+	case CKM_CAST3_ECB:
+		result = "CKM_CAST3_ECB";
+		break;
+	case CKM_CAST3_CBC:
+		result = "CKM_CAST3_CBC";
+		break;
+	case CKM_CAST3_MAC:
+		result = "CKM_CAST3_MAC";
+		break;
+	case CKM_CAST3_MAC_GENERAL:
+		result = "CKM_CAST3_MAC_GENERAL";
+		break;
+	case CKM_CAST3_CBC_PAD:
+		result = "CKM_CAST3_CBC_PAD";
+		break;
+		/*case CKM_CAST5_KEY_GEN:
+		result = "CKM_CAST5_KEY_GEN";
+		break;*/
+	case CKM_CAST128_KEY_GEN:
+		result = "CKM_CAST128_KEY_GEN/CKM_CAST5_KEY_GEN";
+		break;
+		/*case CKM_CAST5_ECB:
+		result = "CKM_CAST5_ECB";
+		break;*/
+	case CKM_CAST128_ECB:
+		result = "CKM_CAST128_ECB/CKM_CAST5_ECB";
+		break;
+		/*case CKM_CAST5_CBC:
+		result = "CKM_CAST5_CBC";
+		break;*/
+	case CKM_CAST128_CBC:
+		result = "CKM_CAST128_CBC/CKM_CAST5_CBC";
+		break;
+		/*case CKM_CAST5_MAC:
+		result = "CKM_CAST5_MAC";
+		break;*/
+	case CKM_CAST128_MAC:
+		result = "CKM_CAST128_MAC/CKM_CAST5_MAC";
+		break;
+		/*case CKM_CAST5_MAC_GENERAL:
+		result = "CKM_CAST5_MAC_GENERAL";
+		break;*/
+	case CKM_CAST128_MAC_GENERAL:
+		result = "CKM_CAST128_MAC_GENERAL/CKM_CAST5_MAC_GENERAL";
+		break;
+		/*case CKM_CAST5_CBC_PAD:
+		result = "CKM_CAST5_CBC_PAD";
+		break;*/
+	case CKM_CAST128_CBC_PAD:
+		result = "CKM_CAST128_CBC_PAD/CKM_CAST5_CBC_PAD";
+		break;
+	case CKM_RC5_KEY_GEN:
+		result = "CKM_RC5_KEY_GEN";
+		break;
+	case CKM_RC5_ECB:
+		result = "CKM_RC5_ECB";
+		break;
+	case CKM_RC5_CBC:
+		result = "CKM_RC5_CBC";
+		break;
+	case CKM_RC5_MAC:
+		result = "CKM_RC5_MAC";
+		break;
+	case CKM_RC5_MAC_GENERAL:
+		result = "CKM_RC5_MAC_GENERAL";
+		break;
+	case CKM_RC5_CBC_PAD:
+		result = "CKM_RC5_CBC_PAD";
+		break;
+	case CKM_IDEA_KEY_GEN:
+		result = "CKM_IDEA_KEY_GEN";
+		break;
+	case CKM_IDEA_ECB:
+		result = "CKM_IDEA_ECB";
+		break;
+	case CKM_IDEA_CBC:
+		result = "CKM_IDEA_CBC";
+		break;
+	case CKM_IDEA_MAC:
+		result = "CKM_IDEA_MAC";
+		break;
+	case CKM_IDEA_MAC_GENERAL:
+		result = "CKM_IDEA_MAC_GENERAL";
+		break;
+	case CKM_IDEA_CBC_PAD:
+		result = "CKM_IDEA_CBC_PAD";
+		break;
+	case CKM_GENERIC_SECRET_KEY_GEN:
+		result = "CKM_GENERIC_SECRET_KEY_GEN";
+		break;
+	case CKM_CONCATENATE_BASE_AND_KEY:
+		result = "CKM_CONCATENATE_BASE_AND_KEY";
+		break;
+	case CKM_CONCATENATE_BASE_AND_DATA:
+		result = "CKM_CONCATENATE_BASE_AND_DATA";
+		break;
+	case CKM_CONCATENATE_DATA_AND_BASE:
+		result = "CKM_CONCATENATE_DATA_AND_BASE";
+		break;
+	case CKM_XOR_BASE_AND_DATA:
+		result = "CKM_XOR_BASE_AND_DATA";
+		break;
+	case CKM_EXTRACT_KEY_FROM_KEY:
+		result = "CKM_EXTRACT_KEY_FROM_KEY";
+		break;
+	case CKM_SSL3_PRE_MASTER_KEY_GEN:
+		result = "CKM_SSL3_PRE_MASTER_KEY_GEN";
+		break;
+	case CKM_SSL3_MASTER_KEY_DERIVE:
+		result = "CKM_SSL3_MASTER_KEY_DERIVE";
+		break;
+	case CKM_SSL3_KEY_AND_MAC_DERIVE:
+		result = "CKM_SSL3_KEY_AND_MAC_DERIVE";
+		break;
+	case CKM_SSL3_MD5_MAC:
+		result = "CKM_SSL3_MD5_MAC";
+		break;
+	case CKM_SSL3_SHA1_MAC:
+		result = "CKM_SSL3_SHA1_MAC";
+		break;
+	case CKM_MD5_KEY_DERIVATION:
+		result = "CKM_MD5_KEY_DERIVATION";
+		break;
+	case CKM_MD2_KEY_DERIVATION:
+		result = "CKM_MD2_KEY_DERIVATION";
+		break;
+	case CKM_SHA1_KEY_DERIVATION:
+		result = "CKM_SHA1_KEY_DERIVATION";
+		break;
+	case CKM_PBE_MD2_DES_CBC:
+		result = "CKM_PBE_MD2_DES_CBC";
+		break;
+	case CKM_PBE_MD5_DES_CBC:
+		result = "CKM_PBE_MD5_DES_CBC";
+		break;
+	case CKM_PBE_MD5_CAST_CBC:
+		result = "CKM_PBE_MD5_CAST_CBC";
+		break;
+	case CKM_PBE_MD5_CAST3_CBC:
+		result = "CKM_PBE_MD5_CAST3_CBC";
+		break;
+		/*case CKM_PBE_MD5_CAST5_CBC:
+		result = "CKM_PBE_MD5_CAST5_CBC";
+		break;*/
+	case CKM_PBE_MD5_CAST128_CBC:
+		result = "CKM_PBE_MD5_CAST128_CBC/CKM_PBE_MD5_CAST5_CBC";
+		break;
+		/*case CKM_PBE_SHA1_CAST5_CBC:
+		result = "CKM_PBE_SHA1_CAST5_CBC";
+		break;*/
+	case CKM_PBE_SHA1_CAST128_CBC:
+		result = "CKM_PBE_SHA1_CAST128_CBC/CKM_PBE_SHA1_CAST5_CBC";
+		break;
+	case CKM_PBE_SHA1_RC4_128:
+		result = "CKM_PBE_SHA1_RC4_128";
+		break;
+	case CKM_PBE_SHA1_RC4_40:
+		result = "CKM_PBE_SHA1_RC4_40";
+		break;
+	case CKM_PBE_SHA1_DES3_EDE_CBC:
+		result = "CKM_PBE_SHA1_DES3_EDE_CBC";
+		break;
+	case CKM_PBE_SHA1_DES2_EDE_CBC:
+		result = "CKM_PBE_SHA1_DES2_EDE_CBC";
+		break;
+	case CKM_PBE_SHA1_RC2_128_CBC:
+		result = "CKM_PBE_SHA1_RC2_128_CBC";
+		break;
+	case CKM_PBE_SHA1_RC2_40_CBC:
+		result = "CKM_PBE_SHA1_RC2_40_CBC";
+		break;
+	case CKM_PBA_SHA1_WITH_SHA1_HMAC:
+		result = "CKM_PBA_SHA1_WITH_SHA1_HMAC";
+		break;
+	case CKM_KEY_WRAP_LYNKS:
+		result = "CKM_KEY_WRAP_LYNKS";
+		break;
+	case CKM_KEY_WRAP_SET_OAEP:
+		result = "CKM_KEY_WRAP_SET_OAEP";
+		break;
+	case CKM_SKIPJACK_KEY_GEN:
+		result = "CKM_SKIPJACK_KEY_GEN";
+		break;
+	case CKM_SKIPJACK_ECB64:
+		result = "CKM_SKIPJACK_ECB64";
+		break;
+	case CKM_SKIPJACK_CBC64:
+		result = "CKM_SKIPJACK_CBC64";
+		break;
+	case CKM_SKIPJACK_OFB64:
+		result = "CKM_SKIPJACK_OFB64";
+		break;
+	case CKM_SKIPJACK_CFB64:
+		result = "CKM_SKIPJACK_CFB64";
+		break;
+	case CKM_SKIPJACK_CFB32:
+		result = "CKM_SKIPJACK_CFB32";
+		break;
+	case CKM_SKIPJACK_CFB16:
+		result = "CKM_SKIPJACK_CFB16";
+		break;
+	case CKM_SKIPJACK_CFB8:
+		result = "CKM_SKIPJACK_CFB8";
+		break;
+	case CKM_SKIPJACK_WRAP:
+		result = "CKM_SKIPJACK_WRAP";
+		break;
+	case CKM_SKIPJACK_PRIVATE_WRAP:
+		result = "CKM_SKIPJACK_PRIVATE_WRAP";
+		break;
+	case CKM_SKIPJACK_RELAYX:
+		result = "CKM_SKIPJACK_RELAYX";
+		break;
+	case CKM_KEA_KEY_PAIR_GEN:
+		result = "CKM_KEA_KEY_PAIR_GEN";
+		break;
+	case CKM_KEA_KEY_DERIVE:
+		result = "CKM_KEA_KEY_DERIVE";
+		break;
+	case CKM_FORTEZZA_TIMESTAMP:
+		result = "CKM_FORTEZZA_TIMESTAMP";
+		break;
+	case CKM_BATON_KEY_GEN:
+		result = "CKM_BATON_KEY_GEN";
+		break;
+	case CKM_BATON_ECB128:
+		result = "CKM_BATON_ECB128";
+		break;
+	case CKM_BATON_ECB96:
+		result = "CKM_BATON_ECB96";
+		break;
+	case CKM_BATON_CBC128:
+		result = "CKM_BATON_CBC128";
+		break;
+	case CKM_BATON_COUNTER:
+		result = "CKM_BATON_COUNTER";
+		break;
+	case CKM_BATON_SHUFFLE:
+		result = "CKM_BATON_SHUFFLE";
+		break;
+	case CKM_BATON_WRAP:
+		result = "CKM_RSA_9796";
+		break;
+	case CKM_ECDSA:
+		result = "CKM_ECDSA";
+		break;
+	case CKM_ECDSA_SHA1:
+		result = "CKM_ECDSA_SHA1";
+		break;
+	case CKM_JUNIPER_KEY_GEN:
+		result = "CKM_JUNIPER_KEY_GEN";
+		break;
+	case CKM_JUNIPER_ECB128:
+		result = "CKM_JUNIPER_ECB128";
+		break;
+	case CKM_JUNIPER_CBC128:
+		result = "CKM_JUNIPER_CBC128";
+		break;
+	case CKM_JUNIPER_COUNTER:
+		result = "CKM_JUNIPER_COUNTER";
+		break;
+	case CKM_JUNIPER_SHUFFLE:
+		result = "CKM_JUNIPER_SHUFFLE";
+		break;
+	case CKM_JUNIPER_WRAP:
+		result = "CKM_JUNIPER_WRAP";
+		break;
+	case CKM_FASTHASH:
+		result = "CKM_FASTHASH";
+		break;
+	case CKM_VENDOR_DEFINED:
+		result = "CKM_VENDOR_DEFINED";
+		break;
+	case CKM_SHA256:
+		result = "CKM_SHA256";
+		break;
+	case CKM_SHA256_RSA_PKCS:
+		result = "CKM_SHA256_RSA_PKCS";
+		break;
+	default:
+		toString( result, "UNKNOWN MECHANISM <%#02x>", t );
+	}
+}
+
+
+/*
+*/
+void Log::CK_MECHANISM_INFOToString( CK_MECHANISM_INFO_PTR pInfo, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == pInfo )
+	{
+		return;
+	}
+
+	std::string flags = "";
+	CK_FLAGS f = pInfo->flags;
+	mechanismFlagsToString( f, flags );
+
+	toString( result, "ulMinKeySize <%#02x> - ulMaxKeySize <%#02x> - flags <%s>", pInfo->ulMinKeySize, pInfo->ulMaxKeySize, flags.c_str( ) );
+}
+
+
+/*
+*/
+void Log::mechanismFlagsToString( const CK_FLAGS& f, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( f & CKF_EXTENSION )
+	{
+		result += "CKF_EXTENSION";
+	}
+	if( f & CKF_DERIVE )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_DERIVE";
+	}
+	if( f & CKF_UNWRAP )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_UNWRAP";
+	}
+	if( f & CKF_WRAP )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_WRAP";
+	}
+	if( f & CKF_GENERATE_KEY_PAIR )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_GENERATE_KEY_PAIR";
+	}
+	if( f & CKF_GENERATE )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_GENERATE";
+	}
+	if( f & CKF_VERIFY_RECOVER )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_VERIFY_RECOVER";
+	}
+	if( f & CKF_VERIFY )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_VERIFY";
+	}
+	if( f & CKF_SIGN_RECOVER )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_SIGN_RECOVER";
+	}
+	if( f & CKF_HW )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_HW";
+	}
+	if( f & CKF_ENCRYPT )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_ENCRYPT";
+	}
+	if( f & CKF_DECRYPT )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_DECRYPT";
+	}
+	if( f & CKF_DIGEST )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_DIGEST";
+	}
+	if( f & CKF_SIGN )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_SIGN";
+	}
+}
+
+
+/*
+*/
+void Log::sessionFlagsToString( const CK_FLAGS &f, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    result = "";
+
+	// Session information flags
+	if( f & CKF_SERIAL_SESSION )
+	{
+		result += "CKF_SERIAL_SESSION";
+	}
+
+	if( f & CKF_RW_SESSION )
+	{
+		if( !result.empty( ) )
+		{
+			result += " | ";
+		}
+		result += "CKF_RW_SESSION";
+	}
+}
+
+
+/*
+*/
+void Log::CK_SESSION_INFOToString( CK_SESSION_INFO_PTR pInfo, std::string& result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    if( NULL_PTR == pInfo )
+	{
+		return;
+	}
+
+	std::string flags = "";
+	CK_FLAGS f = pInfo->flags;
+	sessionFlagsToString( f, flags );
+
+    std::string state = "";
+    CK_STATEToString( pInfo->state, state );
+
+	toString( result, "slotID <%#02x> - state <%#02x> (%s) - flags <%#02x> (%s) - ulDeviceError <%#02x>",
+		pInfo->slotID,
+		pInfo->state,
+        state.c_str( ),
+		pInfo->flags,
+		flags.c_str( ),
+		pInfo->ulDeviceError );
+}
+
+
+/*
+*/
+void Log::CK_STATEToString( const CK_STATE& a_State, std::string& a_stResult ) {
+
+    if( !s_bEnableLog ) {
+        
+		return;
+	}
+
+    switch ( a_State ) {
+
+    case CKS_RO_PUBLIC_SESSION:
+        a_stResult = "CKS_RO_PUBLIC_SESSION";
+        break;
+
+    case CKS_RO_USER_FUNCTIONS:
+        a_stResult = "CKS_RO_USER_FUNCTIONS";
+        break;
+
+    case CKS_RW_PUBLIC_SESSION:
+        a_stResult = "CKS_RW_PUBLIC_SESSION";
+        break;
+
+    case CKS_RW_USER_FUNCTIONS:
+        a_stResult = "CKS_RW_USER_FUNCTIONS";
+        break;
+
+    case CKS_RW_SO_FUNCTIONS:
+        a_stResult = "CKS_RW_SO_FUNCTIONS";
+        break;
+
+    default:
+        a_stResult = "<<UNKNOWN CK_STATE>>";
+        break;
+    }
+}
+
+
+/*
+*/
+void Log::CK_USER_TYPEToString( const CK_USER_TYPE& t, std::string &result )
+{
+	if( !s_bEnableLog ) {
+		return;
+	}
+
+    switch( t )
+	{
+	case CKU_USER:
+		result = "CKU_USER";
+		break;
+
+	case CKU_SO:
+		result  = "CKU_SO";
+		break;
+
+	default:
+		toString( result, "UNKNOWN USER TYPE <%#02x>", t );
+	}
+}
+
+
+/*
+*/
+void Log::start( void ) {
+#ifdef WIN32
+	m_clockStart = clock( );
+#else
+   gettimeofday( &m_clockStart, NULL ); 
+#endif
+}
+
+
+/*
+*/
+void Log::stop( const char* a_pMethod ) {
+
+    	if( !s_bEnableLog ) {
+		return;
+	}
+
+#ifdef WIN32
+      double duration = (double)(clock( ) - m_clockStart) / CLOCKS_PER_SEC;
+	   m_clockStart = 0;
+#else	
+      timeval now;         
+      gettimeofday( &now, NULL );  
+
+      timeval diff;
+      diff.tv_sec = now.tv_sec - m_clockStart.tv_sec;
+      diff.tv_usec = now.tv_usec - m_clockStart.tv_usec; 
+      while( diff.tv_usec < 0 )
+      {
+         diff.tv_sec--;
+         diff.tv_usec = 1000000 + ( now.tv_usec - m_clockStart.tv_usec );
+      }
+      double duration = diff.tv_sec;         
+      duration += (double)( diff.tv_usec / 1e6 ); 
+ 
+      memset( &m_clockStart, 0, sizeof( timeval ) );
+#endif
+
+	if( 0.500 > duration ) {
+     
+        Log::log( "%s - Elapsed time <%f> seconds", a_pMethod, duration );
+    
+    } else {
+     
+        Log::log( "%s - Elapsed time <%f> seconds [LONG DURATION]\n", a_pMethod, duration );
+    }
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Log.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Log.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Log.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,120 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_LOG__
+#define __GEMALTO_LOG__
+
+
+#include <string>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sstream>
+#include <iostream>
+#include <iomanip>
+#include "cryptoki.h"
+
+#ifdef WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+
+/*
+*/
+class Log {
+
+public:
+
+#ifdef WIN32
+	static clock_t m_clockStart;
+#else
+	static timeval m_clockStart;
+#endif
+
+	static void log( const char * format, ... );
+
+	static void error( const char*, const char* );
+	static void in( const char* a_pMethod );
+	static void out( const char* a_pMethod );
+	static void begin( const char* a_pMethod );
+	static void end( const char* a_pMethod );
+
+	static void start( void );
+	static void stop( const char* a_pMethod );
+
+	static void logCK_SLOT_ID_PTR( const char*, CK_SLOT_ID_PTR, CK_ULONG_PTR );
+	static void logCK_SLOT_INFO_PTR( const char*, CK_SLOT_INFO_PTR );
+	static void logCK_C_INITIALIZE_ARGS_PTR( const char*, CK_C_INITIALIZE_ARGS_PTR );
+	static void logCK_INFO( const char*, const CK_INFO_PTR );
+	static void logCK_RV( const char*, const CK_RV & );
+	static void logCK_UTF8CHAR_PTR( const char*, const unsigned char*, const std::size_t& );
+	static void logCK_TOKEN_INFO_PTR( const char*, CK_TOKEN_INFO_PTR );
+	static void logCK_MECHANISM_TYPE( const char*, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR );
+	static void logCK_MECHANISM_TYPE( const char*, CK_MECHANISM_TYPE & );
+	static void logCK_SESSION_INFO_PTR( const char*, CK_SESSION_INFO_PTR );
+    
+	static void logCK_USER_TYPE( const char*, CK_USER_TYPE & );
+	static void logCK_ATTRIBUTE_PTR( const char*, CK_ATTRIBUTE_PTR, CK_ULONG & );
+	static void logSessionFlags( const char*, CK_FLAGS & );
+	static void logCK_MECHANISM_INFO_PTR( const char*, CK_MECHANISM_INFO_PTR );
+	static void logCK_MECHANISM_PTR( const char*, CK_MECHANISM_PTR );
+
+	static void CK_STATEToString( const CK_STATE&, std::string& );
+    static void CK_MECHANISMToString( CK_MECHANISM_PTR, std::string & );
+	static void CK_CERTIFICATE_TYPEToString( const CK_CERTIFICATE_TYPE &, std::string & );
+	static void CK_KEY_TYPEToString( const CK_KEY_TYPE&, std::string & );
+	static void CK_OBJECT_CLASSToString( const CK_OBJECT_CLASS&, std::string & );
+	static void CK_DATEToString( const CK_DATE*, std::string & );
+	static void CK_INFOToString( CK_INFO_PTR pInfo, std::string &result );
+	static void slotFlagsToString( const CK_FLAGS& f, std::string &result );
+	static void mechanismFlagsToString( const CK_FLAGS &, std::string & );
+	static void sessionFlagsToString( const CK_FLAGS & , std::string & );
+	static void CK_VERSIONToString( CK_VERSION_PTR pVersion, std::string& result );
+	static void CK_RVToString( const CK_RV& rv, std::string &result );
+	static void CK_MECHANISM_TYPEToString( CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG mechanismListLen, std::string &result );
+	static void CK_MECHANISM_TYPEToString( const CK_MECHANISM_TYPE &, std::string & );
+	static void CK_MECHANISM_INFOToString( CK_MECHANISM_INFO_PTR pInfo, std::string &result );
+	static void CK_SESSION_INFOToString( CK_SESSION_INFO_PTR, std::string& );
+	static void CK_USER_TYPEToString( const CK_USER_TYPE&, std::string & );
+	static void CK_ATTRIBUTEToString( const CK_ATTRIBUTE_PTR, std::string & );
+	static void CK_ATTRIBUTE_TYPEToString( const CK_ATTRIBUTE_TYPE& , std::string &, int& );
+
+	static void toString( std::string &result, const char * format, ... );
+	static void toString( const unsigned char* buffer, std::size_t size, std::string &result );
+	static void toString( const unsigned long &l, std::string &result );
+
+	template<typename T> static void classtoString( const T & value, std::string &result );
+
+    static void setLogPath( const std::string& stPath );
+
+	static bool s_bEnableLog;
+
+	static char s_LogFilePath[ 255 ];
+
+private:
+
+    static struct timeval s_StartTimeVal;
+};
+
+
+#endif // __GEMALTO_LOG__

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am	2012-02-20 14:26:10 UTC (rev 141)
@@ -3,14 +3,6 @@
 libgtop11dotnet_la_LDFLAGS = -shared
 
 libgtop11dotnet_la_SOURCES = \
-	$(top_srcdir)/cppMarshaller/Array.cpp \
-	$(top_srcdir)/cppMarshaller/Array.h \
-	$(top_srcdir)/cppMarshaller/Except.h \
-	$(top_srcdir)/cppMarshaller/MarshallerCfg.h \
-	$(top_srcdir)/cppMarshaller/Marshaller.cpp \
-	$(top_srcdir)/cppMarshaller/Marshaller.h \
-	$(top_srcdir)/cppMarshaller/PCSC.cpp \
-	$(top_srcdir)/cppMarshaller/PCSC.h \
 	algo_des.cpp \
 	algo_des.h \
 	algo_md5.cpp \
@@ -21,113 +13,151 @@
 	algo_sha256.h \
 	algo_utils.cpp \
 	algo_utils.h \
-	application.cpp \
-	application.h \
+	Application.cpp \
+	Application.hpp \
+	Array.cpp \
+	Array.hpp \
 	attrcert.cpp \
 	attrcert.h \
+	autogen.sh \
 	beroctet.cpp \
 	beroctet.h \
-	cardcache.cpp \
-	cardcache.h \
-	cardmoduleservice.cpp \
-	cardmoduleservice.h \
-	certificateobject.cpp \
-	certificateobject.h \
+	cardmod.h \
+	CardModuleService.cpp \
+	CardModuleService.hpp \
 	cert_utils.cpp \
 	cert_utils.h \
-	config.h \
-	critsect.cpp \
-	critsect.h \
-	dataobject.cpp \
-	dataobject.h \
+	Configuration.cpp \
+	Configuration.hpp \
+	cr_digit.cpp \
+	cr_digit.h \
+	cr_global.h \
+	cr_nn.cpp \
+	cr_nn.h \
+	cr_random.cpp \
+	cr_random.h \
+	cr_rsa.cpp \
+	cr_rsa.h \
+	cryptoki.h \
 	des.cpp \
 	des.h \
-	digest.cpp \
+	Device.cpp \
+	Device.hpp \
+	DeviceMonitor.cpp \
+	DeviceMonitor.hpp \
+	Digest.cpp \
 	digest.h \
-	error.cpp \
-	error.h \
-	event.cpp \
-	event.h \
-	keyobject.cpp \
-	keyobject.h \
-	md5.cpp \
+	DigestMD5.cpp \
+	DigestSHA1.cpp \
+	DigestSHA256.cpp \
+	Except.h \
+	ha_config.h \
+	IDeviceMonitorListener.hpp \
+	Log.cpp \
+	Log.hpp \
+	MarshallerCfg.h \
+	Marshaller.cpp \
+	Marshaller.h \
+	MarshallerUtil.cpp \
+	MarshallerUtil.h \
 	md5.h \
-	mutex.cpp \
-	mutex.h \
-	pkcs11.cpp \
+	MiniDriverAuthentication.cpp \
+	MiniDriverAuthentication.hpp \
+	MiniDriverCardCacheFile.cpp \
+	MiniDriverCardCacheFile.hpp \
+	MiniDriverContainer.cpp \
+	MiniDriverContainer.hpp \
+	MiniDriverContainerMapFile.cpp \
+	MiniDriverContainerMapFile.hpp \
+	MiniDriver.cpp \
+	MiniDriverException.hpp \
+	MiniDriverFiles.cpp \
+	MiniDriverFiles.hpp \
+	MiniDriver.hpp \
+	MiniDriverPinPolicy.cpp \
+	MiniDriverPinPolicy.hpp \
+	Module.cpp \
+	pbbase.h \
+	PCSC.cpp \
+	PCSC.h \
+	PKCS11.cpp \
+	PKCS11Exception.hpp \
+	PCSCMissing.h \
 	pkcs11f.h \
 	pkcs11.h \
+	Pkcs11ObjectCertificate.cpp \
+	Pkcs11ObjectCertificate.hpp \
+	Pkcs11ObjectCertificateX509PublicKey.cpp \
+	Pkcs11ObjectCertificateX509PublicKey.hpp \
+	Pkcs11ObjectData.cpp \
+	Pkcs11ObjectData.hpp \
+	Pkcs11ObjectKey.cpp \
+	Pkcs11ObjectKey.hpp \
+	Pkcs11ObjectKeyPrivate.cpp \
+	Pkcs11ObjectKeyPrivate.hpp \
+	Pkcs11ObjectKeyPrivateRSA.cpp \
+	Pkcs11ObjectKeyPrivateRSA.hpp \
+	Pkcs11ObjectKeyPublic.cpp \
+	Pkcs11ObjectKeyPublic.hpp \
+	Pkcs11ObjectKeyPublicRSA.cpp \
+	Pkcs11ObjectKeyPublicRSA.hpp \
+	Pkcs11ObjectStorage.cpp \
+	Pkcs11ObjectStorage.hpp \
 	pkcs11t.h \
-	platconfig.h \
-	privatekeyobject.cpp \
-	privatekeyobject.h \
-	publickeyobject.cpp \
-	publickeyobject.h \
-	resource.h \
-	rsa/cr_digit.cpp \
-	rsa/cr_digit.h \
-	rsa/cr_global.h \
-	rsa/cr_nn.cpp \
-	rsa/cr_nn.h \
-	rsa/cr_random.cpp \
-	rsa/cr_random.h \
-	rsa/cr_rsa.cpp \
-	rsa/cr_rsa.h \
-	rsa/ha_config.h \
-	rsaprivatekeyobject.cpp \
-	rsaprivatekeyobject.h \
-	rsapublickeyobject.cpp \
-	rsapublickeyobject.h \
-	sctoken.cpp \
-	sctoken.h \
-	secretkeyobject.cpp \
-	secretkeyobject.h \
-	session.cpp \
-	session.h \
-	sha1.cpp \
+	pkcs-11v2-20a3.h \
+	Session.cpp \
+	Session.hpp \
 	sha1.h \
-	sha256.cpp \
 	sha256.h \
-	slot.cpp \
-	slot.h \
-	stdafx.cpp \
-	stdafx.h \
-	storageobject.cpp \
-	storageobject.h \
+	Slot.cpp \
+	Slot.hpp \
+	SmartCardReader.cpp \
+	SmartCardReaderException.hpp \
+	SmartCardReader.hpp \
 	symmalgo.cpp \
 	symmalgo.h \
 	tdes.cpp \
 	tdes.h \
-	template.cpp \
-	template.h \
-	thread.cpp \
-	thread.h \
-	timer.cpp \
-	timer.h \
-	transaction.cpp \
-	transaction.h \
+	Template.cpp \
+	Template.hpp \
+	Timer.cpp \
+	Timer.hpp \
+	Token.cpp \
+	Token.hpp \
 	util.cpp \
 	util.h \
+	version.hpp \
 	x509cert.cpp \
-	x509cert.h \
-	x509pubkeycertobject.cpp \
-	x509pubkeycertobject.h \
-	log.h \
-	log.cpp
+	x509cert.h
 
-AM_CPPFLAGS = -DINCLUDE_EVENTING=1 -DCRYPTOKI_EXPORTS=1 \
+AM_CPPFLAGS = -DCRYPTOKI_EXPORTS=1 \
 	-DUNIX $(PTHREAD_CFLAGS) \
 	-Wall \
 	-Wextra \
 	-pedantic
 
+if ENABLE_SYSTEM_BOOST
+else
+BOOST_INCLUDES = -I../boost_1_46_1
+BOOST_LIB = -L../boost_1_46_1/stage/lib
+endif
+
 INCLUDES = \
-	-I$(top_srcdir)/cppMarshaller \
-	-I$(top_srcdir)/PKCS11Module2 \
-	-I$(top_srcdir)/PKCS11Module2/rsa \
+	$(BOOST_INCLUDES) \
 	$(PCSC_CFLAGS)
 
-LIBS = $(PCSC_LIBS) $(PTHREAD_LIBS) -lz
+LIBS = \
+    $(PCSC_LIBS) \
+	-lz \
+	$(BOOST_LIB) \
+    -lboost_date_time \
+    -lboost_filesystem \
+    -lboost_serialization \
+    -lboost_system \
+    -lboost_thread \
+    -lpthread
+     
+EXTRA_DIST = autogen.sh c-mac.sh ./docs/LGPL-2.1 ./docs/Release_Notes_Linux.pdf ./docs/PKCS\#11_Libs_.NET_Linux_User_Guide.pdf ./config/Gemalto.NET.PKCS11.ini
 
 # see http://wiki.cacert.org/wiki/Pkcs11TaskForce
 install-exec-hook:

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,22 +1,22 @@
 /*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
 
 #ifdef WIN32
 #include <Windows.h>
@@ -26,10 +26,6 @@
 #define DBG_UNREFERENCED_LOCAL_VARIABLE(a)
 #endif
 
-#ifdef INCLUDE_VLD
-#include <vld.h>
-#endif
-
 #ifdef __APPLE__
 #include <PCSC/winscard.h>
 #else
@@ -43,1608 +39,189 @@
 #include <stdarg.h>
 #include <stdexcept>
 #include "MarshallerCfg.h"
-#include "Array.h"
-#ifndef _XCL_
+#include "Array.hpp"
 #include "PCSC.h"
-#else // _XCL_
-#include "xcl_broker.h"
-#endif // _XCL_
 #include "Marshaller.h"
 #include "Except.h"
+#include "Log.hpp"
 
-#include "log.h"
-
 MARSHALLER_NS_BEGIN
 
-#define SUPPORT_BETA_VERSION
 
-#define APDU_TO_CARD_MAX_SIZE                                   0xFF
+    /*
+    */
+    SmartCardMarshaller::SmartCardMarshaller( std::string a_pstReaderName, u2 a_PortNumber, std::string a_stURI, u4 a_NameSpaceHivecode, u2 a_TypeHivecode, u4 a_Index ) {
 
-#define HIVECODE_NAMESPACE_SYSTEM                               0x00D25D1C
-#define HIVECODE_NAMESPACE_SYSTEM_IO                            0x00D5E6DB
-#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CHANNELS     0x0000886E
-#define HIVECODE_NAMESPACE_NETCARD_FILESYSTEM                   0x00A1AC39
-#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING              0x00EB3DD9
-#define HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY         0x00ACF53B
-#define HIVECODE_NAMESPACE_SYSTEM_COLLECTIONS                   0x00C5A010
-#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CONTEXTS     0x001F4994
-#define HIVECODE_NAMESPACE_SYSTEM_SECURITY                      0x00964145
-#define HIVECODE_NAMESPACE_SYSTEM_REFLECTION                    0x0008750F
-#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION         0x008D3B3D
-#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_MESSAGING    0x00DEB940
-#define HIVECODE_NAMESPACE_SYSTEM_DIAGNOSTICS                   0x0097995F
-#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_COMPILERSERVICES      0x00F63E11
-#define HIVECODE_NAMESPACE_SYSTEM_TEXT                          0x00702756
+        m_stURI = a_stURI;
 
-#define HIVECODE_TYPE_SYSTEM_VOID           0xCE81
-#define HIVECODE_TYPE_SYSTEM_INT32          0x61C0
-#define HIVECODE_TYPE_SYSTEM_INT32_ARRAY    0x61C1
-#define HIVECODE_TYPE_SYSTEM_BOOLEAN        0x2227
-#define HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY  0x2228
-#define HIVECODE_TYPE_SYSTEM_SBYTE          0x767E
-#define HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY    0x767F
-#define HIVECODE_TYPE_SYSTEM_UINT16         0xD98B
-#define HIVECODE_TYPE_SYSTEM_UINT16_ARRAY   0xD98C
-#define HIVECODE_TYPE_SYSTEM_UINT32         0x95E7
-#define HIVECODE_TYPE_SYSTEM_UINT32_ARRAY   0x95E8
-#define HIVECODE_TYPE_SYSTEM_BYTE           0x45A2
-#define HIVECODE_TYPE_SYSTEM_BYTE_ARRAY     0x45A3
-#define HIVECODE_TYPE_SYSTEM_CHAR           0x958E
-#define HIVECODE_TYPE_SYSTEM_CHAR_ARRAY     0x958F
-#define HIVECODE_TYPE_SYSTEM_INT16          0xBC39
-#define HIVECODE_TYPE_SYSTEM_INT16_ARRAY    0xBC3A
-#define HIVECODE_TYPE_SYSTEM_STRING         0x1127
-#define HIVECODE_TYPE_SYSTEM_STRING_ARRAY   0x1128
-#define HIVECODE_TYPE_SYSTEM_INT64			0xDEFB
-#define HIVECODE_TYPE_SYSTEM_INT64_ARRAY	0xDEFC
-#define HIVECODE_TYPE_SYSTEM_UINT64			0x71AF
-#define HIVECODE_TYPE_SYSTEM_UINT64_ARRAY	0x71B0
+        m_pPCSC = NULL;
 
-#define HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM 0xFED7
+        m_PortNumber = a_PortNumber;
 
-// for port discovery lookup.
-#define CARDMANAGER_SERVICE_PORT                                                    1
-#define CARDMANAGER_SERVICE_NAME                                                    "ContentManager"
-#define HIVECODE_NAMESPACE_SMARTCARD                                                0x00F5EFBF
-#define HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER                                      0xB18C
-#define HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT                  0x7616
+        m_NameSpaceHivecode = a_NameSpaceHivecode;
 
-#define HIVECODE_TYPE_SYSTEM_EXCEPTION                                      0xD4B0
-#define HIVECODE_TYPE_SYSTEM_SYSTEMEXCEPTION                                0x28AC
-#define HIVECODE_TYPE_SYSTEM_OUTOFMEMORYEXCEPTION                           0xE14E
-#define HIVECODE_TYPE_SYSTEM_ARGUMENTEXCEPTION                              0xAB8C
-#define HIVECODE_TYPE_SYSTEM_ARGUMENTNULLEXCEPTION                          0x2138
-#define HIVECODE_TYPE_SYSTEM_NULLREFERENCEEXCEPTION                         0xC5B8
-#define HIVECODE_TYPE_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION                    0x6B11
-#define HIVECODE_TYPE_SYSTEM_NOTSUPPORTEDEXCEPTION                          0xAA74
-#define HIVECODE_TYPE_SYSTEM_INVALIDCASTEXCEPTION                           0xD24F
-#define HIVECODE_TYPE_SYSTEM_INVALIDOPERATIONEXCEPTION                      0xFAB4
-#define HIVECODE_TYPE_SYSTEM_NOTIMPLEMENTEDEXCEPTION                        0x3CE5
-#define HIVECODE_TYPE_SYSTEM_OBJECTDISPOSEDEXCEPTION                        0x0FAC
-#define HIVECODE_TYPE_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION                    0x4697
-#define HIVECODE_TYPE_SYSTEM_INDEXOUTOFRANGEEXCEPTION                       0xBF1D
-#define HIVECODE_TYPE_SYSTEM_FORMATEXCEPTION                                0xF3BF
-#define HIVECODE_TYPE_SYSTEM_ARITHMETICEXCEPTION                            0x6683
-#define HIVECODE_TYPE_SYSTEM_OVERFLOWEXCEPTION                              0x20A0
-#define HIVECODE_TYPE_SYSTEM_BADIMAGEFORMATEXCEPTION                        0x530A
-#define HIVECODE_TYPE_SYSTEM_APPLICATIONEXCEPTION                           0xB1EA
-#define HIVECODE_TYPE_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION                     0x3F88
-#define HIVECODE_TYPE_SYSTEM_DIVIDEBYZEROEXCEPTION                          0xDFCF
-#define HIVECODE_TYPE_SYSTEM_MEMBERACCESSEXCEPTION                          0xF5F3
-#define HIVECODE_TYPE_SYSTEM_MISSINGMEMBEREXCEPTION                         0x20BB
-#define HIVECODE_TYPE_SYSTEM_MISSINGFIELDEXCEPTION                          0x7366
-#define HIVECODE_TYPE_SYSTEM_MISSINGMETHODEXCEPTION                         0x905B
-#define HIVECODE_TYPE_SYSTEM_RANKEXCEPTION                                  0xB2AE
-#define HIVECODE_TYPE_SYSTEM_STACKOVERFLOWEXCEPTION                         0x0844
-#define HIVECODE_TYPE_SYSTEM_TYPELOADEXCEPTION                              0x048E
-#define HIVECODE_TYPE_SYSTEM_IO_IOEXCEPTION                                 0x3BBE
-#define HIVECODE_TYPE_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION                  0x975A
-#define HIVECODE_TYPE_SYSTEM_IO_FILENOTFOUNDEXCEPTION                       0x07EB
-#define HIVECODE_TYPE_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION             0xD52A
-#define HIVECODE_TYPE_SYSTEM_RUNTIME_SERIALIZATION_SERIALIZATIONEXCEPTION   0xA1D2
-#define HIVECODE_TYPE_SYSTEM_SECURITY_SECURITYEXCEPTION						0x31AF
-#define HIVECODE_TYPE_SYSTEM_SECURITY_VERIFICATIONEXCEPTION					0x67F1
-#define HIVECODE_TYPE_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION   0x8FEB
+        m_TypeHivecode = a_TypeHivecode;
 
-#ifdef SMARTCARDMARSHALLER_EXPORTS
+        m_pProcessInputStream  = NULL;
 
-BOOL APIENTRY DllMain(HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
-{
-   UNREFERENCED_PARAMETER(hModule);
-   UNREFERENCED_PARAMETER(lpReserved);
+        m_pProcessOutputStream = NULL;
 
-   switch (ul_reason_for_call)
-   {
-   case DLL_PROCESS_ATTACH:
-   case DLL_THREAD_ATTACH:
-   case DLL_THREAD_DETACH:
-   case DLL_PROCESS_DETACH:
-      break;
-   }
-   return TRUE;
-}
-
-#endif
-
-static u2 ComReadU2At(u1Array &array, u4 pos)
-{
-   if ((u8)(pos + sizeof(u2)) > (u8)array.GetLength()) {
-      throw ArgumentOutOfRangeException((lpCharPtr)"");
-   }
-   u1* buff = array.GetBuffer();
-   return (u2)((((u2)buff[pos]) << 8) + buff[pos + 1]);
-}
-
-u4 ComReadU4At(u1Array &array, u4 pos);
-u4 ComReadU4At(u1Array &array, u4 pos)
-{
-   if ((u8)(pos + sizeof(u4)) > (u8)array.GetLength()) {
-      throw ArgumentOutOfRangeException((lpCharPtr)"");
-   }
-   u1* buff = array.GetBuffer();
-   return (u4)((((u4)buff[pos]) << 24) + (((u4)buff[pos + 1]) << 16) + (((u4)buff[pos + 2]) << 8) + buff[pos + 3]);
-}
-
-static u8 ComReadU8At(u1Array &array, u4 pos)
-{
-   if ((u8)(pos + sizeof(u8)) > (u8)array.GetLength()) {
-      throw ArgumentOutOfRangeException((lpCharPtr)"");
-   }
-   u1* buff = array.GetBuffer();
-
-   u1 b1 = buff[pos];
-   u1 b2 = buff[pos + 1];
-   u1 b3 = buff[pos + 2];
-   u1 b4 = buff[pos + 3];
-   u1 b5 = buff[pos + 4];
-   u1 b6 = buff[pos + 5];
-   u1 b7 = buff[pos + 6];
-   u1 b8 = buff[pos + 7];
-
-   return (((u8)b1 << 56) | ((u8)b2 << 48) | ((u8)b3 << 40) | ((u8)b4 << 32) | ((u8)b5 << 24) | ((u8)b6 << 16) | ((u8)b7 << 8) | b8);
-}
-
-static void ProcessException(u1Array answer, u4 protocolOffset)
-{
-   u4 exceptionNamespace;
-   u4 exceptionName;
-   char* chst = NULL;
-
-   try {
-      exceptionNamespace = ComReadU4At(answer, protocolOffset + 0);
-      exceptionName      = ComReadU2At(answer, protocolOffset + 4);
-
-      if (answer.GetLength() > (protocolOffset + 6)) {
-         u2 strLen = ComReadU2At(answer, protocolOffset + 6);
-         if ((strLen > 0) && (strLen != 0xFFFF)) {
-            u2 len = ComputeLPSTRLength(answer, protocolOffset + 8, strLen);
-            chst = new char[len + 1];
-            chst[len] = '\0';
-            UTF8Decode(answer, protocolOffset + 8, strLen, chst);
-         }
-      }
-   } catch (...) {
-      // someone is messing with the protocol
-      if (chst != NULL) {
-         delete[] chst;
-      }
-      throw RemotingException((lpCharPtr)"");
-   }
-
-   if (chst == NULL) {
-      // prepare empty string
-      chst = new char[1];
-      chst[0] = '\0';
-   }
-
-   // create a string object on the stack.
-   // when exception is thrown the exception object is copied on
-   // a temporary location and live till used by catch block
-   //
-   // it is not a good idea to pass chst as a parameter of exception object
-   // as there will be no way to delete it.
-   std::string chstr(chst);
-
-   delete[] chst;
-
-   switch (exceptionNamespace)
-   {
-   case HIVECODE_NAMESPACE_SYSTEM:
-      {
-         switch(exceptionName){
-
-   case (u2)HIVECODE_TYPE_SYSTEM_EXCEPTION:
-      throw Exception(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_SYSTEMEXCEPTION:
-      throw SystemException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_OUTOFMEMORYEXCEPTION:
-      throw OutOfMemoryException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_ARGUMENTEXCEPTION:
-      throw ArgumentException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_ARGUMENTNULLEXCEPTION:
-      throw ArgumentNullException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_NULLREFERENCEEXCEPTION:
-      throw NullReferenceException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION:
-      throw ArgumentOutOfRangeException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_NOTSUPPORTEDEXCEPTION:
-      throw NotSupportedException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_INVALIDCASTEXCEPTION:
-      throw InvalidCastException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_INVALIDOPERATIONEXCEPTION:
-      throw InvalidOperationException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_NOTIMPLEMENTEDEXCEPTION:
-      throw NotImplementedException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_OBJECTDISPOSEDEXCEPTION:
-      throw ObjectDisposedException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION:
-      throw UnauthorizedAccessException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_INDEXOUTOFRANGEEXCEPTION:
-      throw IndexOutOfRangeException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_FORMATEXCEPTION:
-      throw FormatException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_ARITHMETICEXCEPTION:
-      throw ArithmeticException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_OVERFLOWEXCEPTION:
-      throw OverflowException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_BADIMAGEFORMATEXCEPTION:
-      throw BadImageFormatException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_APPLICATIONEXCEPTION:
-      throw ApplicationException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION:
-      throw ArrayTypeMismatchException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_DIVIDEBYZEROEXCEPTION:
-      throw DivideByZeroException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_MEMBERACCESSEXCEPTION:
-      throw MemberAccessException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_MISSINGMEMBEREXCEPTION:
-      throw MissingMemberException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_MISSINGFIELDEXCEPTION:
-      throw MissingFieldException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_MISSINGMETHODEXCEPTION:
-      throw MissingMethodException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_RANKEXCEPTION:
-      throw RankException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_STACKOVERFLOWEXCEPTION:
-      throw StackOverflowException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_TYPELOADEXCEPTION:
-      throw TypeLoadException(chstr);
-         }
-      }
-      break;
-
-   case HIVECODE_NAMESPACE_SYSTEM_IO:
-      {
-         switch(exceptionName){
-   case (u2)HIVECODE_TYPE_SYSTEM_IO_IOEXCEPTION:
-      throw IOException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION:
-      throw DirectoryNotFoundException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_IO_FILENOTFOUNDEXCEPTION:
-      throw FileNotFoundException(chstr);
-         }
-      }
-      break;
-
-   case HIVECODE_NAMESPACE_SYSTEM_SECURITY:
-      {
-         switch(exceptionName){
-   case (u2)HIVECODE_TYPE_SYSTEM_SECURITY_SECURITYEXCEPTION:
-      throw SecurityException(chstr);
-
-   case (u2)HIVECODE_TYPE_SYSTEM_SECURITY_VERIFICATIONEXCEPTION:
-      throw VerificationException(chstr);
-         }
-      }
-      break;
-
-   case HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING:
-      {
-         switch(exceptionName){
-   case (u2)HIVECODE_TYPE_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION:
-      throw RemotingException(chstr);
-         }
-      }
-      break;
-
-   case HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION:
-      {
-         switch(exceptionName){
-   case (u2)HIVECODE_TYPE_SYSTEM_RUNTIME_SERIALIZATION_SERIALIZATIONEXCEPTION:
-      throw SerializationException(chstr);
-         }
-      }
-      break;
-
-   case HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY:
-      {
-         switch(exceptionName){
-   case (u2)HIVECODE_TYPE_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION:
-      throw CryptographicException(chstr);
-         }
-      }
-      break;
-   }
-
-   // custom exception from the card application or someone is messing with the protocol
-   // no means of translation.
-   throw Exception(chstr);
-}
-
-u4 CheckForException(u1Array answer, u4 nameSpace, u2 type);
-u4 CheckForException(u1Array answer, u4 nameSpace, u2 type)
-{
-   u1 protocolAnswerPrefix = answer.ReadU1At(0);
-
-#ifdef SUPPORT_BETA_VERSION
-   if (protocolAnswerPrefix == 0) {
-      // beta version protocol (namespace & type systematically returned)
-      if ((ComReadU4At(answer, 0) != nameSpace) || (ComReadU2At(answer, 4) != type)) {
-         ProcessException(answer, 0);
-      }
-      // skip namespace & type
-      return (4 + 2);
-   }
-#endif
-
-   // new protocol
-   if (protocolAnswerPrefix != 0x01) {
-      if (protocolAnswerPrefix == 0xFF) {
-         // exception info expected in the buffer
-         ProcessException(answer, 1);
-      } else {
-         // someone is messing with the protocol
-         throw RemotingException((lpCharPtr)"");
-      }
-   }
-
-   // skip return type info (protocolAnswerPrefix: 0x01 = ok, 0xFF = exception)
-   return 1;
-}
-
-SmartCardMarshaller::SmartCardMarshaller(SCARDHANDLE cardHandle, u2 portNumber, M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode)
-{
-   this->uri = NULL;
-   this->pcsc = NULL;
-   this->portNumber = portNumber;
-   this->nameSpaceHivecode = nameSpaceHivecode;
-   this->typeHivecode = typeHivecode;
-   this->ProcessInputStream  = NULL;
-   this->ProcessOutputStream = NULL;
-
-#ifndef _XCL_
-   this->pcsc = new PCSC(cardHandle);
-#else // _XCL_
-    this->pcsc = new XCLBroker(cardHandle);
-#endif // _XCL_
-
-   try {
-      this->uri = new std::string(uri->c_str());
-   } catch (...) {
-      delete this->pcsc;
-      throw;
-   }
-}
-
-SmartCardMarshaller::SmartCardMarshaller(M_SAL_IN std::string* readerName, u2 portNumber, M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode, u4 index)
-{
-   //Log::begin( "SmartCardMarshaller::SmartCardMarshaller" );
-
-   this->uri = NULL;
-   this->pcsc = NULL;
-   this->portNumber = portNumber;
-   this->nameSpaceHivecode = nameSpaceHivecode;
-   this->typeHivecode = typeHivecode;
-   this->ProcessInputStream  = NULL;
-   this->ProcessOutputStream = NULL;
-
 #ifdef WIN32
-   if ((readerName == NULL) || (_stricmp("selfdiscover", readerName->c_str()) == 0))
-   {
+        if( ( a_pstReaderName.empty( ) ) || (_stricmp( "selfdiscover", a_pstReaderName.c_str( ) ) == 0 ) ) {
 #else
-   if ((readerName == NULL) || (strncasecmp("selfdiscover", readerName->c_str(),readerName->length()) == 0))
-   {
+        if( ( a_pstReaderName.empty( ) ) || ( strncasecmp( "selfdiscover", a_pstReaderName.c_str( ), a_pstReaderName.length( ) ) == 0 ) ) {
 #endif
-      //Log::log( "SmartCardMarshaller::SmartCardMarshaller -  new PCSC( readerName, &portNumber, uri, nameSpaceHivecode, typeHivecode, index) ..." );
-#ifndef _XCL_
-      this->pcsc = new PCSC( readerName, &portNumber, uri, nameSpaceHivecode, typeHivecode, index);
-#else // _XCL
-        this->pcsc = new XCLBroker(readerName, &portNumber, uri, nameSpaceHivecode, typeHivecode, index);
-#endif // _XCL_
-      //Log::log( "SmartCardMarshaller::SmartCardMarshaller -  new PCSC( readerName, &portNumber, uri, nameSpaceHivecode, typeHivecode, index) ok" );
-   }
-   else
-   {
-      //Log::log( "SmartCardMarshaller::SmartCardMarshaller -  new PCSC( readerName ) ..." );
-#ifndef _XCL_
-      this->pcsc = new PCSC( readerName );
-#else // _XCL_
-        this->pcsc = new XCLBroker(readerName);
-#endif // _XCL_
-      //Log::log( "SmartCardMarshaller::SmartCardMarshaller -  new PCSC( readerName ) ok" );
-   }
 
-   try
-   {
-      //Log::log( "SmartCardMarshaller::SmartCardMarshaller -  new std::string(uri->c_str()) ..." );
-      this->uri = new std::string(uri->c_str());
-      //Log::log( "SmartCardMarshaller::SmartCardMarshaller -  new std::string(uri->c_str()) ok" );
-   }
-   catch (...)
-   {
-      //Log::error( "SmartCardMarshaller::SmartCardMarshaller", "(...)" );
-      delete this->pcsc;
-      throw;
-   }
+            m_pPCSC = new PCSC( a_pstReaderName, m_PortNumber, a_stURI, a_NameSpaceHivecode, a_TypeHivecode, a_Index );
 
-   //Log::end( "SmartCardMarshaller::SmartCardMarshaller" );
-}
+        } else {
 
-std::string* SmartCardMarshaller::GetReaderName(void)
-{
-   return this->pcsc->GetReaderName();
+            m_pPCSC = new PCSC( a_pstReaderName );
+        }
 }
 
-SCARDHANDLE SmartCardMarshaller::GetCardHandle(void)
-{
-   return this->pcsc->GetCardHandle();
-}
 
-void SmartCardMarshaller::DoTransact(bool flag)
-{
-   this->pcsc->DoTransact(flag);
-}
+/*
+*/
+SmartCardMarshaller::~SmartCardMarshaller( ) {
 
-SmartCardMarshaller::~SmartCardMarshaller(void)
-{
-   if (this->uri != NULL) {
-      delete this->uri;
-      this->uri = NULL;
-   }
-
-   if (this->pcsc != NULL) {
-      delete this->pcsc;
-      this->pcsc = NULL;
-   }
+    delete m_pPCSC;
+    m_pPCSC = NULL;
 }
 
-void SmartCardMarshaller::UpdatePCSCCardHandle(SCARDHANDLE hCard)
-{
-   this->pcsc->SetCardHandle(hCard);
-}
 
-static void ProcessByReferenceArguments(u1 type, u1Array* dataArray, u4* offsetPtr, va_list* markerPtr, u1 isIn)
-{
-   //va_list marker = *markerPtr;
-   u4 offset = *offsetPtr;
+/*
+*/
+void SmartCardMarshaller::Invoke( s4 nParam, ... ) {
 
-   switch (type) {
+    // Allow selfdiscovery of port
+    if ( !m_PortNumber ) {
 
-        case MARSHALLER_TYPE_REF_BOOL:
-        case MARSHALLER_TYPE_REF_U1:
-        case MARSHALLER_TYPE_REF_S1:
-           {
-              u1* val = va_arg(/*marker*/*markerPtr, u1*);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
-              if (isIn == TRUE) {
-                 *dataArray += *val;
-              }
-              else {
-                 *val = (*dataArray).ReadU1At(offset);
-              }
-              offset += sizeof(u1);
-           }
-           break;
+        s4 _s4 = 0;
 
-        case MARSHALLER_TYPE_REF_CHAR:
-        case MARSHALLER_TYPE_REF_U2:
-        case MARSHALLER_TYPE_REF_S2:
-           {
-              u2* val = va_arg(/*marker*/*markerPtr, u2*);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
-              if (isIn == TRUE) {
-                 *dataArray += *val;
-              }
-              else {
-                 *val = ComReadU2At(*dataArray, offset);
-              }
-              offset += sizeof(u2);
-           }
-           break;
+        u4 nameSpaceHivecode = m_NameSpaceHivecode;
 
-        case MARSHALLER_TYPE_REF_U4:
-        case MARSHALLER_TYPE_REF_S4:
-           {
-              u4* val = va_arg(/*marker*/*markerPtr, u4*);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
-              if (isIn == TRUE) {
-                 *dataArray += *val;
-              }
-              else {
-                 *val = ComReadU4At(*dataArray, offset);
-              }
-              offset += sizeof(u4);
-           }
-           break;
+        u2 typeHivecode = m_TypeHivecode;
 
-        case MARSHALLER_TYPE_REF_U8:
-        case MARSHALLER_TYPE_REF_S8:
-           {
-              u8* val = va_arg(/*marker*/*markerPtr, u8*);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
-              if (isIn == TRUE) {
-                 *dataArray += *val;
-              }
-              else {
-                 *val = ComReadU8At(*dataArray, offset);
-              }
-              offset += sizeof(u8);
-           }
-           break;
+        std::string stURI = m_stURI;
 
-        case MARSHALLER_TYPE_REF_STRING:
-           {
-              std::string** val = va_arg(/*marker*/*markerPtr, std::string**);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
-              if (isIn == TRUE) {
-                 offset += sizeof(u2);
-                 if (*val != NULL) {
-                    offset += ComputeUTF8Length((lpCharPtr)((*val)->c_str()));
-                 }
-                 (*dataArray).Append(*val);
-              } else {
-                 u2 len = ComReadU2At(*dataArray, offset);
-                 offset += sizeof(u2);
-                 if (len == 0xFFFF) {
-                    *val = NULL;
-                 } else {
-                    // store result
-                    u2 l = ComputeLPSTRLength(*dataArray, offset, len);
-                    char* chstr = new char[l + 1];
-                    try {
-                       chstr[l] = '\0';
-                       UTF8Decode(*dataArray, offset, len, chstr);
-                       *val = new std::string(chstr);
-                    } catch (...) {
-                       delete[] chstr;
-                       throw;
-                    }
-                    delete[] chstr;
-                    offset += len;
-                 }
-              }
-           }
-           break;
+        m_PortNumber = CARDMANAGER_SERVICE_PORT;
 
-        case MARSHALLER_TYPE_REF_S1ARRAY:
-        case MARSHALLER_TYPE_REF_BOOLARRAY:
-        case MARSHALLER_TYPE_REF_U1ARRAY:
-           {
-              u1Array** val = va_arg(/*marker*/*markerPtr, u1Array**);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
+        m_NameSpaceHivecode = HIVECODE_NAMESPACE_SMARTCARD;
 
-              if (isIn == TRUE) {
-                 offset += sizeof(u4);
-                 if ((*val)->IsNull() == FALSE) {
-                    u4  valLen = (*val)->GetLength();
-                    u1* valBuf = (*val)->GetBuffer();
-                    *dataArray += valLen;
-                    for(u4 v = 0; v < valLen; v++) {
-                       *dataArray += valBuf[v];
-                    }
-                    offset += (sizeof(u1) * valLen);
-                 } else {
-                    *dataArray += 0xFFFFFFFF;
-                 }
-              } else {
+        m_TypeHivecode = HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER;
 
-                 u4 len = ComReadU4At(*dataArray, offset);
-                 offset += sizeof(u4);
+        m_stURI = CARDMANAGER_SERVICE_NAME;
 
-                 u1Array* refArray = NULL;
+        try {
 
-                 try {
-                    if (len == 0xFFFFFFFF) {
-                       refArray = new u1Array(-1);
-                    } else {
-                       refArray = new u1Array(len);
-                       for (u4 i = 0; i < len; i++) {
-                          refArray->SetU1At(i, dataArray->ReadU1At(offset));
-                          offset += sizeof(u1);
-                       }
-                    }
-                 } catch (...) {
-                    if (refArray != NULL) {
-                       delete refArray;
-                    }
-                    throw;
-                 }
+            // call the GetAssociatedPort method.
+            //Invoke(3, HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT, MARSHALLER_TYPE_IN_S4, m_NameSpaceHivecode, MARSHALLER_TYPE_IN_S2, m_TypeHivecode, MARSHALLER_TYPE_IN_STRING, m_stURI, MARSHALLER_TYPE_RET_S4, &_s4);
+            Invoke(3, HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT, MARSHALLER_TYPE_IN_S4, m_NameSpaceHivecode, MARSHALLER_TYPE_IN_S2, m_TypeHivecode, MARSHALLER_TYPE_IN_STRING, m_stURI.c_str( ), MARSHALLER_TYPE_RET_S4, &_s4);
 
-                 if (*val != NULL) {
-                    // perform cleanup
-                    delete *val;
-                 }
+        } catch (...) {
 
-                 *val = refArray;
-              }
-           }
-           break;
+            m_PortNumber = (u2)_s4;
+            m_NameSpaceHivecode = nameSpaceHivecode;
+            m_TypeHivecode = typeHivecode;
+            m_stURI = stURI;
 
-        case MARSHALLER_TYPE_REF_S2ARRAY:
-        case MARSHALLER_TYPE_REF_U2ARRAY:
-           {
-              u2Array** val = va_arg(/*marker*/*markerPtr, u2Array**);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
+            throw;
+        }
 
-              if (isIn == TRUE) {
-                 offset += sizeof(u4);
-                 if ((*val)->IsNull() == FALSE) {
-                    u4  valLen = (*val)->GetLength();
-                    u2* valBuf = (*val)->GetBuffer();
-                    *dataArray += valLen;
-                    for(u4 v = 0; v < valLen; v++) {
-                       *dataArray += valBuf[v];
-                    }
-                    offset += (sizeof(u2) * valLen);
-                 } else {
-                    *dataArray += 0xFFFFFFFF;
-                 }
-              } else {
+        m_PortNumber = (u2)_s4;
+        m_NameSpaceHivecode = nameSpaceHivecode;
+        m_TypeHivecode = typeHivecode;
+        m_stURI = stURI;
 
-                 u4 len = ComReadU4At(*dataArray, offset);
-                 offset += sizeof(u4);
+    }
 
-                 u2Array* refArray = NULL;
+    u1Array invokeAPDU(0);
 
-                 try {
-                    if (len == 0xFFFFFFFF) {
-                       refArray = new u2Array(-1);
-                    } else {
-                       refArray = new u2Array(len);
-                       for (u4 i = 0; i < len; i++) {
-                          refArray->SetU2At(i, ComReadU2At(*dataArray, offset));
-                          offset += sizeof(u2);
-                       }
-                    }
-                 } catch (...) {
-                    if (refArray != NULL) {
-                       delete refArray;
-                    }
-                    throw;
-                 }
+    va_list marker;
 
-                 if (*val != NULL) {
-                    // perform cleanup
-                    delete *val;
-                 }
+    va_start(marker, nParam);
 
-                 *val = refArray;
-              }
-           }
-           break;
+    // add 0xD8
+    invokeAPDU += (u1)0xD8;
 
-        case MARSHALLER_TYPE_REF_S4ARRAY:
-        case MARSHALLER_TYPE_REF_U4ARRAY:
-           {
-              u4Array** val = va_arg(/*marker*/*markerPtr, u4Array**);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
+    // add port number
+    invokeAPDU += (u2)m_PortNumber;
 
-              if (isIn == TRUE) {
-                 offset += sizeof(u4);
-                 if ((*val)->IsNull() == FALSE) {
-                    u4  valLen = (*val)->GetLength();
-                    u4* valBuf = (*val)->GetBuffer();
-                    *dataArray += valLen;
-                    for(u4 v = 0; v < valLen; v++) {
-                       *dataArray += valBuf[v];
-                    }
-                    offset += (sizeof(u4) * valLen);
-                 } else {
-                    *dataArray += 0xFFFFFFFF;
-                 }
-              } else {
+    // add 0x6F
+    invokeAPDU += (u1)0x6F;
 
-                 u4 len = ComReadU4At(*dataArray, offset);
-                 offset += sizeof(u4);
+    // add namespace Hivecode
+    invokeAPDU += m_NameSpaceHivecode;
 
-                 u4Array* refArray = NULL;
+    // add type hivecode
+    invokeAPDU += m_TypeHivecode;
 
-                 try {
-                    if (len == 0xFFFFFFFF) {
-                       refArray = new u4Array(-1);
-                    } else {
-                       refArray = new u4Array(len);
-                       for (u4 i = 0; i < len; i++) {
-                          refArray->SetU4At(i, ComReadU4At(*dataArray, offset));
-                          offset += sizeof(u4);
-                       }
-                    }
-                 } catch (...) {
-                    if (refArray != NULL) {
-                       delete refArray;
-                    }
-                    throw;
-                 }
+    // NOTE : va_arg(marker,type)
+    // As per ISO C++ if the pritives types
+    // char,short,byte are passed as argument to varidic method
+    // they are upcasted to int.
+    //
+    // On windows if you use va_arg(marker,u2), no warning will be issued
+    // and there will be no complain at run time, whereas
+    // On Linux (with g++) if you use va_arg(markey,u2), a warning will be issued
+    // saying that it is invalid to do this and run time will fail and it does fail
+    // with message "Segmentation fault".
+    //
+    // So va_arg for all int primitive types (char, short, byte and their unsigned values)
+    // should have s4 as the type.
 
-                 if (*val != NULL) {
-                    // perform cleanup
-                    delete *val;
-                 }
+    // add method name
+    u2 methodID = (u2)va_arg(marker, s4);
+    
+    invokeAPDU += methodID;
 
-                 *val = refArray;
-              }
-           }
-           break;
+    // add URI
+    u1Array URIArray(ComputeUTF8Length((char*)m_stURI.c_str( )));
+    
+    UTF8Encode((char*)m_stURI.c_str(), URIArray);
+    
+    invokeAPDU += (u2)URIArray.GetLength();
+    
+    invokeAPDU += URIArray;
 
-        case MARSHALLER_TYPE_REF_S8ARRAY:
-        case MARSHALLER_TYPE_REF_U8ARRAY:
-           {
-              u8Array** val = va_arg(/*marker*/*markerPtr, u8Array**);
-              if (val == NULL) {
-                 throw NullReferenceException((lpCharPtr)"");
-              }
+    u1Array invokeAPDU_data(0);
 
-              if (isIn == TRUE) {
-                 offset += sizeof(u4);
-                 if ((*val)->IsNull() == FALSE) {
-                    u4  valLen = (*val)->GetLength();
-                    u8* valBuf = (*val)->GetBuffer();
-                    *dataArray += valLen;
-                    for(u4 v = 0; v < valLen; v++) {
-                       *dataArray += valBuf[v];
-                    }
-                    offset += (sizeof(u8) * valLen);
-                 } else {
-                    *dataArray += 0xFFFFFFFF;
-                 }
-              } else {
+    // process input arguments
+    for (s4 iParam = 0; iParam < nParam; iParam++) {
+        
+        u1 type = (u1)va_arg(marker, s4);
+        
+        m_MarshallerUtil.ProcessInputArguments(type, &invokeAPDU_data, &marker);
+    }
 
-                 u4 len = ComReadU4At(*dataArray, offset);
-                 offset += sizeof(u4);
+    if( m_pProcessInputStream  ){
+    
+        u1Array invokeAPDU_data_Modified(0);
+        
+        m_pProcessInputStream(invokeAPDU_data,invokeAPDU_data_Modified);
+        
+        invokeAPDU += invokeAPDU_data_Modified;
+    
+    }else{
+    
+        invokeAPDU += invokeAPDU_data;
+    }
 
-                 u8Array* refArray = NULL;
+    u1Array answer_o(0);
 
-                 try {
-                    if (len == 0xFFFFFFFF) {
-                       refArray = new u8Array(-1);
-                    } else {
-                       refArray = new u8Array(len);
-                       for (u4 i = 0; i < len; i++) {
-                          refArray->SetU8At(i, ComReadU8At(*dataArray, offset));
-                          offset += sizeof(u4);
-                       }
-                    }
-                 } catch (...) {
-                    if (refArray != NULL) {
-                       delete refArray;
-                    }
-                    throw;
-                 }
+    if(invokeAPDU.GetLength() > (s4)APDU_TO_CARD_MAX_SIZE)
+    {
+        u4 offset = 0;
+        u4 size = invokeAPDU.GetLength() -1 - 2 - 1 - 4 - 2 - 2 - 2 -  URIArray.GetLength();
 
-                 if (*val != NULL) {
-                    // perform cleanup
-                    delete *val;
-                 }
+        u1 first = TRUE;
 
-                 *val = refArray;
-              }
-           }
-           break;
+        u4 dataToSendLength = invokeAPDU.GetLength();
+        u4 invokeApduStartOffset = 0;
 
-        default:
-           {
-              if (isIn == TRUE) {
-                 throw Exception("Un-recognized input argument type");
-              } else {
-                 throw Exception("Un-recognized byref argument type");
-              }
-           }
-           break;
-   }
+        while(dataToSendLength > 0){
 
-   //*markerPtr = marker;
-   *offsetPtr = offset;
-}
-
-
-static void ProcessOutputArguments(u1 type, u1Array* answerPtr, u4* offsetPtr, va_list* markerPtr)
-{
-   switch (type) {
-
-        case MARSHALLER_TYPE_IN_BOOL:
-        case MARSHALLER_TYPE_IN_S1:
-        case MARSHALLER_TYPE_IN_U1:
-        case MARSHALLER_TYPE_IN_CHAR:
-        case MARSHALLER_TYPE_IN_S2:
-        case MARSHALLER_TYPE_IN_U2:
-        case MARSHALLER_TYPE_IN_S4:
-        case MARSHALLER_TYPE_IN_U4:
-        case MARSHALLER_TYPE_IN_STRING:
-        case MARSHALLER_TYPE_IN_MEMORYSTREAM:
-        case MARSHALLER_TYPE_IN_BOOLARRAY:
-        case MARSHALLER_TYPE_IN_S1ARRAY:
-        case MARSHALLER_TYPE_IN_U1ARRAY:
-        case MARSHALLER_TYPE_IN_CHARARRAY:
-        case MARSHALLER_TYPE_IN_S2ARRAY:
-        case MARSHALLER_TYPE_IN_U2ARRAY:
-        case MARSHALLER_TYPE_IN_S4ARRAY:
-        case MARSHALLER_TYPE_IN_U4ARRAY:
-        case MARSHALLER_TYPE_IN_S8ARRAY:
-        case MARSHALLER_TYPE_IN_U8ARRAY:
-        case MARSHALLER_TYPE_IN_STRINGARRAY:
-           {
-              // ignore input argument (slot size = 4 bytes)
-              //va_list marker = *markerPtr;
-              /*u4 v = */va_arg(/*marker*/*markerPtr, u4);
-              //*markerPtr = marker;
-
-              /*DBG_UNREFERENCED_LOCAL_VARIABLE(v);*/
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_S8:
-        case MARSHALLER_TYPE_IN_U8:
-           {
-              // ignore input argument (slot size = 8 bytes)
-              //va_list marker = *markerPtr;
-              /*u8 v = */va_arg(/*marker*/*markerPtr, u8);
-              //*markerPtr = marker;
-
-              /*DBG_UNREFERENCED_LOCAL_VARIABLE(v);*/
-           }
-           break;
-
-        default:
-           ProcessByReferenceArguments(type, answerPtr, offsetPtr, markerPtr, FALSE);
-           break;
-   }
-}
-
-static u4 ProcessReturnType(u1 type, u1Array* answerPtr, va_list* markerPtr)
-{
-   u1Array answer = *answerPtr;
-   u4 offset = 0;
-   //va_list marker = *markerPtr;
-
-   switch (type) {
-
-      // void (can happen for the method return param)
-        case MARSHALLER_TYPE_RET_VOID:
-           {
-              if (answer.GetLength() > 0) {
-#ifdef SUPPORT_BETA_VERSION
-                 if (answer.ReadU1At(0) == 0x00) {
-                    // beta version protocol
-                    ProcessException(answer, 0);
-                 }
-#endif
-                 // new protocol
-                 ProcessException(answer, 1);
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_BOOL:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BOOLEAN);
-              u1* valToReturn = va_arg(/*marker*/*markerPtr, u1*);
-              if (answer.ReadU1At(offset) == 0) {
-                 *valToReturn = FALSE;
-              } else {
-                 *valToReturn = TRUE;
-              }
-              offset += sizeof(u1);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S1:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_SBYTE);
-              s1* valToReturn = va_arg(/*marker*/*markerPtr, s1*);
-              *valToReturn = answer.ReadU1At(offset);
-              offset += sizeof(u1);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U1:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BYTE);
-              u1* valToReturn = va_arg(/*marker*/*markerPtr, u1*);
-              *valToReturn = answer.ReadU1At(offset);
-              offset += sizeof(u1);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_CHAR:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_CHAR);
-              char* valToReturn = va_arg(/*marker*/*markerPtr, char*);
-              *valToReturn = (char)ComReadU2At(answer, offset);
-              offset += sizeof(u2);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S2:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT16);
-              s2* valToReturn = va_arg(/*marker*/*markerPtr, s2*);
-              *valToReturn = ComReadU2At(answer, offset);
-              offset += sizeof(u2);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U2:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT16);
-              u2* valToReturn = va_arg(/*marker*/*markerPtr, u2*);
-              *valToReturn = ComReadU2At(answer, offset);
-              offset += sizeof(u2);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S4:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32);
-              s4* valToReturn = va_arg(/*marker*/*markerPtr, s4*);
-              *valToReturn = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U4:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT32);
-              u4* valToReturn = va_arg(/*marker*/*markerPtr, u4*);
-              *valToReturn = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S8:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT64);
-              s8* valToReturn = va_arg(/*marker*/*markerPtr, s8*);
-              *valToReturn = ComReadU8At(answer, offset);
-              offset += sizeof(u8);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U8:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT64);
-              u8* valToReturn = va_arg(/*marker*/*markerPtr, u8*);
-              *valToReturn = ComReadU8At(answer, offset);
-              offset += sizeof(u8);
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_STRING:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_STRING);
-              std::string** valToReturn = va_arg(/*marker*/*markerPtr, std::string**);
-              u2 len = ComReadU2At(answer, offset);
-              offset += sizeof(u2);
-              if (len == 0xFFFF) {
-                 *valToReturn = NULL;
-              } else {
-                 // store result
-                 u2 l = ComputeLPSTRLength(answer, offset, len);
-                 char* chstr = new char[l + 1];
-                 try {
-                    chstr[l] = '\0';
-                    UTF8Decode(answer, offset, len, chstr);
-                    *valToReturn = new std::string(chstr);
-                 } catch (...) {
-                    delete[] chstr;
-                    throw;
-                 }
-                 delete[] chstr;
-                 offset += len;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_BOOLARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY);
-              u1Array** valToReturn = va_arg(/*marker*/*markerPtr, u1Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new u1Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new u1Array(answer, offset, len);
-                 offset += len;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S1ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY);
-              s1Array** valToReturn = va_arg(/*marker*/*markerPtr, s1Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new s1Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new s1Array(answer, offset, len);
-                 offset += len;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U1ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY);
-              u1Array** valToReturn = va_arg(/*marker*/*markerPtr, u1Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new u1Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new u1Array(answer, offset, len);
-                 offset += len;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_CHARARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_CHAR_ARRAY);
-              charArray** valToReturn = va_arg(/*marker*/*markerPtr, charArray**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new charArray(-1);
-              } else {
-                 // store result
-                 *valToReturn = new charArray(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU2At(answer, offset);
-                       offset += sizeof(s2);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S2ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT16_ARRAY);
-              s2Array** valToReturn = va_arg(/*marker*/*markerPtr, s2Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new s2Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new s2Array(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU2At(answer, offset);
-                       offset += sizeof(s2);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U2ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT16_ARRAY);
-              u2Array** valToReturn = va_arg(/*marker*/*markerPtr, u2Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new u2Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new u2Array(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU2At(answer, offset);
-                       offset += sizeof(u2);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S4ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32_ARRAY);
-              s4Array** valToReturn = va_arg(/*marker*/*markerPtr, s4Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new s4Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new s4Array(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU4At(answer, offset);
-                       offset += sizeof(s4);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U4ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT32_ARRAY);
-              u4Array** valToReturn = va_arg(/*marker*/*markerPtr, u4Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new u4Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new u4Array(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU4At(answer, offset);
-                       offset += sizeof(u4);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_S8ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT64_ARRAY);
-              s8Array** valToReturn = va_arg(/*marker*/*markerPtr, s8Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new s8Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new s8Array(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU8At(answer, offset);
-                       offset += sizeof(s8);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_U8ARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT64_ARRAY);
-              u8Array** valToReturn = va_arg(/*marker*/*markerPtr, u8Array**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new u8Array(-1);
-              } else {
-                 // store result
-                 *valToReturn = new u8Array(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       (*valToReturn)->GetBuffer()[j] = ComReadU8At(answer, offset);
-                       offset += sizeof(u8);
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_STRINGARRAY:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_STRING_ARRAY);
-              StringArray** valToReturn = va_arg(/*marker*/*markerPtr, StringArray**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new StringArray(-1);
-              } else {
-                 // store result
-                 *valToReturn = new StringArray(len);
-                 try {
-                    for (u4 j = 0; j < len; j++) {
-                       u2 lenStr = ComReadU2At(answer, offset);
-                       offset += sizeof(u2);
-                       if (lenStr != 0xFFFF) {
-                          u2 blen = ComputeLPSTRLength(answer, offset, lenStr);
-                          char* lpstr = new char[blen + 1];
-                          try {
-                             lpstr[blen] = '\0';
-                             UTF8Decode(answer, offset, lenStr, lpstr);
-                             offset += lenStr;
-
-                             (*valToReturn)->SetStringAt(j, new std::string(lpstr));
-                          } catch (...) {
-                             delete[] lpstr;
-                             throw;
-                          }
-                          delete[] lpstr;
-                       }
-                    }
-                 } catch (...) {
-                    delete *valToReturn;
-                    throw;
-                 }
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_RET_MEMORYSTREAM:
-           {
-              offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM_IO, HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM);
-              MemoryStream** valToReturn = va_arg(/*marker*/*markerPtr, MemoryStream**);
-              u4 len = ComReadU4At(answer, offset);
-              offset += sizeof(u4);
-              if (len == 0xFFFFFFFF) {
-                 *valToReturn = new MemoryStream(-1);
-              } else {
-                 // store result
-                 *valToReturn = new MemoryStream(answer, offset, len);
-                 offset += len;
-              }
-           }
-           break;
-
-        default:
-           {
-              throw Exception("Un-recognized return type");
-           }
-           break;
-   }
-
-   //*markerPtr = marker;
-   return offset;
-}
-
-static void ProcessInputArguments(u1 type, u1Array* invokeAPDU_data, va_list* markerPtr)
-{
-   //va_list marker = *markerPtr;
-
-   switch (type) {
-
-        case MARSHALLER_TYPE_IN_BOOL:
-        case MARSHALLER_TYPE_IN_S1:
-        case MARSHALLER_TYPE_IN_U1:
-           {
-              u1 val = (u1)va_arg(/*marker*/*markerPtr, s4);
-              *invokeAPDU_data += val;
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_CHAR:
-        case MARSHALLER_TYPE_IN_S2:
-        case MARSHALLER_TYPE_IN_U2:
-           {
-              u2 val = (u2)va_arg(/*marker*/*markerPtr, s4);
-              *invokeAPDU_data += val;
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_S4:
-        case MARSHALLER_TYPE_IN_U4:
-           {
-              u4 val = (u4)va_arg(/*marker*/*markerPtr, s4);
-              *invokeAPDU_data += val;
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_S8:
-        case MARSHALLER_TYPE_IN_U8:
-           {
-              u8 val = (u8)va_arg(/*marker*/*markerPtr,u8);
-              *invokeAPDU_data += val;
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_STRING:
-           {
-              std::string* val = va_arg(/*marker*/*markerPtr, std::string*);
-              (*invokeAPDU_data).Append(val);
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_MEMORYSTREAM:
-        case MARSHALLER_TYPE_IN_BOOLARRAY:
-        case MARSHALLER_TYPE_IN_S1ARRAY:
-        case MARSHALLER_TYPE_IN_U1ARRAY:
-           {
-              u1Array* val = va_arg(/*marker*/*markerPtr, u1Array*);
-              if ((val != NULL) && (val->IsNull() == FALSE)) {
-                 u4  valLen = val->GetLength();
-                 u1* valBuf = val->GetBuffer();
-                 // add length
-                 *invokeAPDU_data += valLen;
-                 // add data
-                 for(u4 v = 0; v < valLen; v++)
-                    *invokeAPDU_data += valBuf[v];
-              } else {
-                 // add null pointer
-                 *invokeAPDU_data += (u4)0xFFFFFFFF;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_CHARARRAY:
-        case MARSHALLER_TYPE_IN_S2ARRAY:
-        case MARSHALLER_TYPE_IN_U2ARRAY:
-           {
-              u2Array* val = va_arg(/*marker*/*markerPtr, u2Array*);
-              if ((val != NULL) && (val->IsNull() == FALSE)) {
-                 u4  valLen = val->GetLength();
-                 u2* valBuf = val->GetBuffer();
-                 *invokeAPDU_data += valLen;
-                 for(u4 v = 0; v < valLen; v++) {
-                    *invokeAPDU_data += valBuf[v];
-                 }
-              } else {
-                 // add null pointer
-                 *invokeAPDU_data += (u4)0xFFFFFFFF;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_S4ARRAY:
-        case MARSHALLER_TYPE_IN_U4ARRAY:
-           {
-              u4Array* val = va_arg(/*marker*/*markerPtr, u4Array*);
-              if ((val != NULL) && (val->IsNull() == FALSE)) {
-                 u4  valLen = val->GetLength();
-                 u4* valBuf = val->GetBuffer();
-                 *invokeAPDU_data += valLen;
-                 for(u4 v = 0; v < valLen; v++) {
-                    *invokeAPDU_data += valBuf[v];
-                 }
-              } else {
-                 // add null pointer
-                 *invokeAPDU_data += (u4)0xFFFFFFFF;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_S8ARRAY:
-        case MARSHALLER_TYPE_IN_U8ARRAY:
-           {
-              u8Array* val = va_arg(/*marker*/*markerPtr, u8Array*);
-              if ((val != NULL) && (val->IsNull() == FALSE)) {
-                 u4  valLen = val->GetLength();
-                 u8* valBuf = val->GetBuffer();
-                 *invokeAPDU_data += valLen;
-                 for(u4 v = 0; v < valLen; v++) {
-                    *invokeAPDU_data += valBuf[v];
-                 }
-              } else {
-                 // add null pointer
-                 *invokeAPDU_data += (u4)0xFFFFFFFF;
-              }
-           }
-           break;
-
-        case MARSHALLER_TYPE_IN_STRINGARRAY:
-           {
-              StringArray* val = va_arg(/*marker*/*markerPtr, StringArray*);
-              if ((val != NULL) && (val->IsNull() == FALSE)) {
-                 u4  valLen = val->GetLength();
-                 *invokeAPDU_data += valLen;
-                 // add data
-                 for (u4 j = 0; j < valLen; j++) {
-                    std::string* str = val->GetStringAt(j);
-                    if(str == NULL){ // add null pointer
-                       *invokeAPDU_data += (u2)0xFFFF;
-                    }else{
-                       (*invokeAPDU_data).Append(str);
-                    }
-                 }
-              } else {
-                 // add null pointer
-                 *invokeAPDU_data += (u4)0xFFFFFFFF;
-              }
-           }
-           break;
-
-        default:
-           u4 offset = 0;
-           ProcessByReferenceArguments(type, invokeAPDU_data, &offset, /*markerPtr*/markerPtr, TRUE);
-           // do not adjust markerPtr.
-           return;
-
-   }
-
-   //*markerPtr = marker;
-}
-
-void SmartCardMarshaller::Invoke(s4 nParam, ...)
-{
-   // Allow selfdiscovery of port
-   if (this->portNumber == 0) {
-      s4 _s4 = 0;
-      u4 nameSpaceHivecode = this->nameSpaceHivecode;
-      u2 typeHivecode      = this->typeHivecode;
-      std::string* uri     = this->uri;
-
-      this->portNumber		= CARDMANAGER_SERVICE_PORT;
-      this->nameSpaceHivecode = HIVECODE_NAMESPACE_SMARTCARD;
-      this->typeHivecode		= HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER;
-      this->uri				= new std::string(CARDMANAGER_SERVICE_NAME);
-
-      try {
-
-         // call the GetAssociatedPort method.
-         Invoke(3, HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT, MARSHALLER_TYPE_IN_S4, nameSpaceHivecode, MARSHALLER_TYPE_IN_S2, typeHivecode, MARSHALLER_TYPE_IN_STRING, uri, MARSHALLER_TYPE_RET_S4, &_s4);
-
-      } catch (...) {
-
-         delete this->uri;
-
-         this->portNumber		= (u2)_s4;
-         this->nameSpaceHivecode = nameSpaceHivecode;
-         this->typeHivecode		= typeHivecode;
-         this->uri				= uri;
-
-         throw;
-      }
-
-      delete this->uri;
-
-      this->portNumber		= (u2)_s4;
-      this->nameSpaceHivecode = nameSpaceHivecode;
-      this->typeHivecode		= typeHivecode;
-      this->uri				= uri;
-   }
-
-   u1Array invokeAPDU(0);
-
-   va_list marker;
-
-   va_start(marker, nParam);
-
-   // add 0xD8
-   invokeAPDU += (u1)0xD8;
-
-   // add port number
-   invokeAPDU += (u2)this->portNumber;
-
-   // add 0x6F
-   invokeAPDU += (u1)0x6F;
-
-   // add namespace Hivecode
-   invokeAPDU += this->nameSpaceHivecode;
-
-   // add type hivecode
-   invokeAPDU += this->typeHivecode;
-
-   // NOTE : va_arg(marker,type)
-   // As per ISO C++ if the pritives types
-   // char,short,byte are passed as argument to varidic method
-   // they are upcasted to int.
-   //
-   // On windows if you use va_arg(marker,u2), no warning will be issued
-   // and there will be no complain at run time, whereas
-   // On Linux (with g++) if you use va_arg(markey,u2), a warning will be issued
-   // saying that it is invalid to do this and run time will fail and it does fail
-   // with message "Segmentation fault".
-   //
-   // So va_arg for all int primitive types (char, short, byte and their unsigned values)
-   // should have s4 as the type.
-
-   // add method name
-   u2 methodID = (u2)va_arg(marker, s4);
-   invokeAPDU += methodID;
-
-   // add uri
-   u1Array uriArray(ComputeUTF8Length((lpCharPtr)this->uri->c_str()));
-   UTF8Encode((lpCharPtr)this->uri->c_str(), uriArray);
-   invokeAPDU += (u2)uriArray.GetLength();
-   invokeAPDU += uriArray;
-
-   u1Array invokeAPDU_data(0);
-
-   // process input arguments
-   for (s4 iParam = 0; iParam < nParam; iParam++) {
-      u1 type = (u1)va_arg(marker, s4);
-      ProcessInputArguments(type, &invokeAPDU_data, &marker);
-   }
-
-   if(ProcessInputStream != NULL){
-      u1Array invokeAPDU_data_Modified(0);
-      ProcessInputStream(invokeAPDU_data,invokeAPDU_data_Modified);
-      invokeAPDU += invokeAPDU_data_Modified;
-   }else{
-      invokeAPDU += invokeAPDU_data;
-   }
-
-   u1Array answer_o(0);
-
-   this->pcsc->BeginTransaction();
-
-   try {
-
-      if(invokeAPDU.GetLength() > (s4)APDU_TO_CARD_MAX_SIZE)
-      {
-         u4 offset = 0;
-         u4 size = invokeAPDU.GetLength() -1 - 2 - 1 - 4 - 2 - 2 - 2 -  uriArray.GetLength();
-
-         u1 first = TRUE;
-
-         u4 dataToSendLength = invokeAPDU.GetLength();
-         u4 invokeApduStartOffset = 0;
-
-         while(dataToSendLength > 0){
-
             u4 encodedSize = size;
             u4 encodedOffset = (u4)offset;
 
@@ -1654,41 +231,45 @@
 
             u1Array subApdu(0);
 
-            if(first == TRUE){
-               u4 usefulDataLength = length -1 - 2 -1 -4 -2 -2 -2 - uriArray.GetLength();
+            if(first){
+                u4 usefulDataLength = length -1 - 2 -1 -4 -2 -2 -2 - URIArray.GetLength();
 
-               subApdu += (u1)0xD8;
-               subApdu += (u2)0xFFFF;
-               subApdu += encodedSize;
-               subApdu += usefulDataLength;
+                subApdu += (u1)0xD8;
+                subApdu += (u2)0xFFFF;
+                subApdu += encodedSize;
+                subApdu += usefulDataLength;
 
-               if ((u8)(invokeApduStartOffset + length) > (u8)invokeAPDU.GetLength()) {
-                  throw ArgumentOutOfRangeException((lpCharPtr)"");
-               }
+                if ((u8)(invokeApduStartOffset + length) > (u8)invokeAPDU.GetLength()) {
+                    
+                    throw ArgumentOutOfRangeException( (char*)"" );
+                }
 
-               for(u4 j = invokeApduStartOffset; j < (invokeApduStartOffset + length); j++) {
-                  subApdu += invokeAPDU.GetBuffer()[j];
-               }
+                for(u4 j = invokeApduStartOffset; j < (invokeApduStartOffset + length); j++) {
 
-               first = FALSE;
-               offset += usefulDataLength;
+                    subApdu += invokeAPDU.GetBuffer()[j];
+                }
 
+                first = FALSE;
+                offset += usefulDataLength;
+
             }else{
 
-               subApdu += (u1)0xD8;
-               subApdu += (u2)0xFFFF;
-               subApdu += encodedOffset;
-               subApdu += length;
+                subApdu += (u1)0xD8;
+                subApdu += (u2)0xFFFF;
+                subApdu += encodedOffset;
+                subApdu += length;
 
-               if ((u8)(invokeApduStartOffset + length) > (u8)invokeAPDU.GetLength()) {
-                  throw ArgumentOutOfRangeException((lpCharPtr)"");
-               }
+                if ((u8)(invokeApduStartOffset + length) > (u8)invokeAPDU.GetLength()) {
+                    
+                    throw ArgumentOutOfRangeException( (char*)"" );
+                }
 
-               for(u4 j = invokeApduStartOffset; j < (invokeApduStartOffset + length); j++) {
-                  subApdu += invokeAPDU.GetBuffer()[j];
-               }
+                for(u4 j = invokeApduStartOffset; j < (invokeApduStartOffset + length); j++) {
 
-               offset += length;
+                    subApdu += invokeAPDU.GetBuffer()[j];
+                }
+
+                offset += length;
             }
 
             size = 0;
@@ -1704,79 +285,82 @@
             apduToSend.GetBuffer()[4] = (u1)subApdu.GetLength();
             apduToSend += subApdu;
 
-            this->pcsc->ExchangeData(apduToSend, answer_o);
-         }
-      }else{
+            m_pPCSC->exchangeData(apduToSend, answer_o);
+        }
 
-         // construct call
-         u1Array apdu(5);
-         apdu.GetBuffer()[0] = 0x80;
-         apdu.GetBuffer()[1] = 0xC2;
-         apdu.GetBuffer()[2] = 0x00;
-         apdu.GetBuffer()[3] = 0x00;
-         apdu.GetBuffer()[4] = (u1)invokeAPDU.GetLength();
-         apdu += invokeAPDU;
+    }else{
 
-         this->pcsc->ExchangeData(apdu, answer_o);
-      }
-   } catch (...) {
-      this->pcsc->EndTransaction();
-      throw;
-   }
+        // construct call
+        u1Array apdu(5);
+        apdu.GetBuffer()[0] = 0x80;
+        apdu.GetBuffer()[1] = 0xC2;
+        apdu.GetBuffer()[2] = 0x00;
+        apdu.GetBuffer()[3] = 0x00;
+        apdu.GetBuffer()[4] = (u1)invokeAPDU.GetLength();
+        apdu += invokeAPDU;
 
-   this->pcsc->EndTransaction();
+        m_pPCSC->exchangeData(apdu, answer_o);
+    }
 
-   u1Array answer(0);
+    u1Array answer(0);
 
-   if ((ProcessOutputStream != NULL) && (answer_o.GetLength() > 0) && (answer_o.ReadU1At(0) == 0x01)){
-      u1Array answerI(0);
-      u1Array answerM(0);
+    if( m_pProcessOutputStream && ( answer_o.GetLength( ) > 0 ) && ( answer_o.ReadU1At( 0 ) == 0x01 ) ) {
 
-      for(u4 i = 1; i < answer_o.GetLength(); i++){
-         answerI += answer_o.GetBuffer()[i];
-      }
+        u1Array answerI( 0 );
 
-      ProcessOutputStream(answerI, answerM);
+        u1Array answerM( 0 );
 
-      answer += answer_o.GetBuffer()[0];
+        unsigned int l = answer_o.GetLength( );
 
-      for(u4 i=0;i<answerM.GetLength();i++){
-         answer += answerM.GetBuffer()[i];
-      }
+        for( unsigned int i = 1; i < l ; ++i ) {
 
-   } else {
-      for(u4 i=0;i<answer_o.GetLength();i++)
-         answer += answer_o.GetBuffer()[i];
-   }
+            answerI += answer_o.GetBuffer( )[ i ];
+        }
 
-   // analyze return type
-   u4 offset = ProcessReturnType((u1)va_arg(marker, s4), &answer, &marker);
+        m_pProcessOutputStream(answerI, answerM);
 
-   va_end(marker);
+        answer += answer_o.GetBuffer()[0];
 
-   // process byref types
-   va_start(marker, nParam);
+        l = answerM.GetLength( );
 
-   // skip method name param
-   u2 methodID2 = (u2)va_arg(marker, s4);
+        for( unsigned int i = 0 ; i < l ; ++i ) {
 
-   if (methodID2 == methodID) {
-      for (s4 iParam = 0; iParam < nParam; iParam++) {
-         u1 type = (u1)va_arg(marker, s4);
-         ProcessOutputArguments(type, &answer, &offset, &marker);
-      }
-   }
+            answer += answerM.GetBuffer( )[ i ];
+        }
 
-   va_end(marker);
-}
+    } else {
 
-void SmartCardMarshaller::SetInputStream(pCommunicationStream inStream){
-   this->ProcessInputStream = inStream;
-}
+        unsigned int l = answer_o.GetLength( );
 
-void  SmartCardMarshaller::SetOutputStream(pCommunicationStream outStream){
-   this->ProcessOutputStream = outStream;
+        for( unsigned int i = 0 ; i < l ; ++i ) {
+
+            answer += answer_o.GetBuffer( )[ i ];
+        }
+    }
+
+    // analyze return type
+    u4 offset = m_MarshallerUtil.ProcessReturnType((u1)va_arg(marker, s4), &answer, &marker);
+
+    va_end(marker);
+
+    // process byref types
+    va_start(marker, nParam);
+
+    // skip method name param
+    u2 methodID2 = (u2)va_arg(marker, s4);
+
+    if (methodID2 == methodID) {
+
+        for (s4 iParam = 0; iParam < nParam; iParam++) {
+        
+            u1 type = (u1)va_arg(marker, s4);
+            
+            m_MarshallerUtil.ProcessOutputArguments(type, &answer, &offset, &marker);
+        }
+    }
+
+    va_end(marker);
 }
 
-MARSHALLER_NS_END
 
+MARSHALLER_NS_END

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,60 +18,73 @@
  *
  */
 
-#ifndef _include_marshaller_h
-#define _include_marshaller_h
 
-#ifdef _XCL_
-#include "xcl_broker.h"
-#endif // _XCL_
+#ifndef __GEMALTO_MARSHALLER_H__
+#define __GEMALTO_MARSHALLER_H__
 
+
+#include "MarshallerUtil.h"
+#include "PCSC.h"
+
+
 MARSHALLER_NS_BEGIN
 
 typedef void (*pCommunicationStream)(u1Array& st,u1Array& stM);
 
-class SMARTCARDMARSHALLER_DLLAPI SmartCardMarshaller
-{
+class SMARTCARDMARSHALLER_DLLAPI SmartCardMarshaller {
 
 private:
-    u4            nameSpaceHivecode;
-    u2            typeHivecode;
-    u2            portNumber;
-    std::string*  uri;
-#ifndef _XCL_
-    PCSC*         pcsc;
-#else 	// _XCL_
-    XCLBroker*    pcsc;
-#endif 	// _XCL_
 
-    pCommunicationStream ProcessInputStream;
-    pCommunicationStream ProcessOutputStream;
+    PCSC* m_pPCSC;
 
+    u4 m_NameSpaceHivecode;
+    
+	u2 m_TypeHivecode;
+
+	u2 m_PortNumber;
+    
+	std::string m_stURI;
+
+	MarshallerUtil m_MarshallerUtil;
+
+
+    pCommunicationStream m_pProcessInputStream;
+
+    pCommunicationStream m_pProcessOutputStream;
+
 public:
     // Existing PCSC connection
-    SmartCardMarshaller(SCARDHANDLE pcscCardHandle, u2 portNumber,M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode);
+    //SmartCardMarshaller( SCARDHANDLE, u2, std::string, u4, u2 );
 
     // PCSC compatible readers
-    SmartCardMarshaller(M_SAL_IN std::string* readerName, u2 portNumber,M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode, u4 index);
+    SmartCardMarshaller( std::string, u2, std::string, u4, u2, u4 );
 
     // destructor
-    ~SmartCardMarshaller(void);
+    virtual ~SmartCardMarshaller( );
 
     // Remoting marshalling method
-    void Invoke(s4 nParam, ...);
+    void Invoke( s4 nParam, ... );
 
-    void UpdatePCSCCardHandle(SCARDHANDLE hCard);
+    inline void UpdatePCSCCardHandle( SCARDHANDLE m_hCard ) { if( m_pPCSC ) { m_pPCSC->setCardHandle( m_hCard ); } }
 
-    void SetInputStream(pCommunicationStream inStream);
-    void SetOutputStream(pCommunicationStream outStream);
+    inline void SetInputStream( pCommunicationStream a_inStream ) { m_pProcessInputStream = a_inStream; }
+	
+	inline void SetOutputStream( pCommunicationStream a_outStream ){ m_pProcessOutputStream = a_outStream; }
 
-    std::string* GetReaderName();
-    SCARDHANDLE GetCardHandle();
-    void DoTransact(bool flag);
+    inline std::string& GetReaderName( void ) { if( m_pPCSC ) { return m_pPCSC->getReaderName( ); } else throw ("Empty PCSC context"); }
 
+    inline SCARDHANDLE GetCardHandle( void ) { if( m_pPCSC ) { return m_pPCSC->getCardHandle( ); } return NULL; }
+    
+    inline void DoTransact( bool& flag ) { if( m_pPCSC ) { m_pPCSC->doTransact( flag ); } }
+
+    inline void beginTransaction( void ) { if( m_pPCSC ) { m_pPCSC->beginTransaction( ); } }
+
+    inline void endTransaction( void ) { if( m_pPCSC ) { m_pPCSC->endTransaction( ); } }
+
 };
 
 MARSHALLER_NS_END
 
-#endif
+#endif // __GEMALTO_MARSHALLER_H__
 
 

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -21,6 +21,10 @@
 #ifndef _include_marshallercfg_h
 #define _include_marshallercfg_h
 
+#ifdef WIN32
+#include <Windows.h>
+#endif
+
 #ifdef SMARTCARDMARSHALLER_EXPORTS
 	#define SMARTCARDMARSHALLER_DLLAPI __declspec(dllexport)
 #else
@@ -163,5 +167,97 @@
 #define MARSHALLER_NS_BEGIN namespace Marshaller {
 #define MARSHALLER_NS_END }
 
+
+#define SUPPORT_BETA_VERSION
+
+#define APDU_TO_CARD_MAX_SIZE                                   0xFF
+
+#define HIVECODE_NAMESPACE_SYSTEM                               0x00D25D1C
+#define HIVECODE_NAMESPACE_SYSTEM_IO                            0x00D5E6DB
+#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CHANNELS     0x0000886E
+#define HIVECODE_NAMESPACE_NETCARD_FILESYSTEM                   0x00A1AC39
+#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING              0x00EB3DD9
+#define HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY         0x00ACF53B
+#define HIVECODE_NAMESPACE_SYSTEM_COLLECTIONS                   0x00C5A010
+#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_CONTEXTS     0x001F4994
+#define HIVECODE_NAMESPACE_SYSTEM_SECURITY                      0x00964145
+#define HIVECODE_NAMESPACE_SYSTEM_REFLECTION                    0x0008750F
+#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION         0x008D3B3D
+#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING_MESSAGING    0x00DEB940
+#define HIVECODE_NAMESPACE_SYSTEM_DIAGNOSTICS                   0x0097995F
+#define HIVECODE_NAMESPACE_SYSTEM_RUNTIME_COMPILERSERVICES      0x00F63E11
+#define HIVECODE_NAMESPACE_SYSTEM_TEXT                          0x00702756
+
+#define HIVECODE_TYPE_SYSTEM_VOID           0xCE81
+#define HIVECODE_TYPE_SYSTEM_INT32          0x61C0
+#define HIVECODE_TYPE_SYSTEM_INT32_ARRAY    0x61C1
+#define HIVECODE_TYPE_SYSTEM_BOOLEAN        0x2227
+#define HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY  0x2228
+#define HIVECODE_TYPE_SYSTEM_SBYTE          0x767E
+#define HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY    0x767F
+#define HIVECODE_TYPE_SYSTEM_UINT16         0xD98B
+#define HIVECODE_TYPE_SYSTEM_UINT16_ARRAY   0xD98C
+#define HIVECODE_TYPE_SYSTEM_UINT32         0x95E7
+#define HIVECODE_TYPE_SYSTEM_UINT32_ARRAY   0x95E8
+#define HIVECODE_TYPE_SYSTEM_BYTE           0x45A2
+#define HIVECODE_TYPE_SYSTEM_BYTE_ARRAY     0x45A3
+#define HIVECODE_TYPE_SYSTEM_CHAR           0x958E
+#define HIVECODE_TYPE_SYSTEM_CHAR_ARRAY     0x958F
+#define HIVECODE_TYPE_SYSTEM_INT16          0xBC39
+#define HIVECODE_TYPE_SYSTEM_INT16_ARRAY    0xBC3A
+#define HIVECODE_TYPE_SYSTEM_STRING         0x1127
+#define HIVECODE_TYPE_SYSTEM_STRING_ARRAY   0x1128
+#define HIVECODE_TYPE_SYSTEM_INT64			0xDEFB
+#define HIVECODE_TYPE_SYSTEM_INT64_ARRAY	0xDEFC
+#define HIVECODE_TYPE_SYSTEM_UINT64			0x71AF
+#define HIVECODE_TYPE_SYSTEM_UINT64_ARRAY	0x71B0
+
+#define HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM 0xFED7
+
+	// for port discovery lookup.
+#define CARDMANAGER_SERVICE_PORT                                                    1
+#define CARDMANAGER_SERVICE_NAME                                                    "ContentManager"
+#define HIVECODE_NAMESPACE_SMARTCARD                                                0x00F5EFBF
+#define HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER                                      0xB18C
+#define HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT                  0x7616
+
+#define HIVECODE_TYPE_SYSTEM_EXCEPTION                                      0xD4B0
+#define HIVECODE_TYPE_SYSTEM_SYSTEMEXCEPTION                                0x28AC
+#define HIVECODE_TYPE_SYSTEM_OUTOFMEMORYEXCEPTION                           0xE14E
+#define HIVECODE_TYPE_SYSTEM_ARGUMENTEXCEPTION                              0xAB8C
+#define HIVECODE_TYPE_SYSTEM_ARGUMENTNULLEXCEPTION                          0x2138
+#define HIVECODE_TYPE_SYSTEM_NULLREFERENCEEXCEPTION                         0xC5B8
+#define HIVECODE_TYPE_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION                    0x6B11
+#define HIVECODE_TYPE_SYSTEM_NOTSUPPORTEDEXCEPTION                          0xAA74
+#define HIVECODE_TYPE_SYSTEM_INVALIDCASTEXCEPTION                           0xD24F
+#define HIVECODE_TYPE_SYSTEM_INVALIDOPERATIONEXCEPTION                      0xFAB4
+#define HIVECODE_TYPE_SYSTEM_NOTIMPLEMENTEDEXCEPTION                        0x3CE5
+#define HIVECODE_TYPE_SYSTEM_OBJECTDISPOSEDEXCEPTION                        0x0FAC
+#define HIVECODE_TYPE_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION                    0x4697
+#define HIVECODE_TYPE_SYSTEM_INDEXOUTOFRANGEEXCEPTION                       0xBF1D
+#define HIVECODE_TYPE_SYSTEM_FORMATEXCEPTION                                0xF3BF
+#define HIVECODE_TYPE_SYSTEM_ARITHMETICEXCEPTION                            0x6683
+#define HIVECODE_TYPE_SYSTEM_OVERFLOWEXCEPTION                              0x20A0
+#define HIVECODE_TYPE_SYSTEM_BADIMAGEFORMATEXCEPTION                        0x530A
+#define HIVECODE_TYPE_SYSTEM_APPLICATIONEXCEPTION                           0xB1EA
+#define HIVECODE_TYPE_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION                     0x3F88
+#define HIVECODE_TYPE_SYSTEM_DIVIDEBYZEROEXCEPTION                          0xDFCF
+#define HIVECODE_TYPE_SYSTEM_MEMBERACCESSEXCEPTION                          0xF5F3
+#define HIVECODE_TYPE_SYSTEM_MISSINGMEMBEREXCEPTION                         0x20BB
+#define HIVECODE_TYPE_SYSTEM_MISSINGFIELDEXCEPTION                          0x7366
+#define HIVECODE_TYPE_SYSTEM_MISSINGMETHODEXCEPTION                         0x905B
+#define HIVECODE_TYPE_SYSTEM_RANKEXCEPTION                                  0xB2AE
+#define HIVECODE_TYPE_SYSTEM_STACKOVERFLOWEXCEPTION                         0x0844
+#define HIVECODE_TYPE_SYSTEM_TYPELOADEXCEPTION                              0x048E
+#define HIVECODE_TYPE_SYSTEM_IO_IOEXCEPTION                                 0x3BBE
+#define HIVECODE_TYPE_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION                  0x975A
+#define HIVECODE_TYPE_SYSTEM_IO_FILENOTFOUNDEXCEPTION                       0x07EB
+#define HIVECODE_TYPE_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION             0xD52A
+#define HIVECODE_TYPE_SYSTEM_RUNTIME_SERIALIZATION_SERIALIZATIONEXCEPTION   0xA1D2
+#define HIVECODE_TYPE_SYSTEM_SECURITY_SECURITYEXCEPTION						0x31AF
+#define HIVECODE_TYPE_SYSTEM_SECURITY_VERIFICATIONEXCEPTION					0x67F1
+#define HIVECODE_TYPE_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION   0x8FEB
+
+
 #endif
 

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,1664 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "MarshallerUtil.h"
+#include "Except.h"
+
+MARSHALLER_NS_BEGIN
+
+#define SUPPORT_BETA_VERSION
+
+
+/*
+*/
+u2 MarshallerUtil::ComReadU2At( u1Array & a_Buffer, const u4& a_Position ) {
+
+	if( (u8)( a_Position + sizeof( u2 ) ) > (u8)a_Buffer.GetLength( ) ) {
+
+		throw ArgumentOutOfRangeException( (char*)"" );
+	}
+
+	u1* p = a_Buffer.GetBuffer();
+
+	return (u2)( ( ( (u2) p[ a_Position ] ) << 8 ) + p[ a_Position + 1 ] );
+}
+
+
+/*
+*/
+u4 MarshallerUtil::ComReadU4At( u1Array& a_Buffer, const u4& a_Position ) {
+
+	if( (u8)( a_Position + sizeof( u4 ) ) > (u8)a_Buffer.GetLength()) {
+
+		throw ArgumentOutOfRangeException( (char*)"" );
+	}
+
+	u1* p = a_Buffer.GetBuffer();
+
+	return (u4)( ( ( (u4)p[ a_Position ] ) << 24) + ( ( (u4)p[ a_Position + 1 ] ) << 16 ) + ( ( (u4) p[ a_Position + 2 ] ) << 8 ) + p[ a_Position + 3 ] );
+}
+
+
+/*
+*/
+u8 MarshallerUtil::ComReadU8At( u1Array& a_Buffer, const u4& a_Position ) {
+
+	if( (u8)( a_Position + sizeof( u8 ) ) > (u8)a_Buffer.GetLength( ) ) {
+
+		throw ArgumentOutOfRangeException( (char*)"" );
+	}
+
+	u1* p = a_Buffer.GetBuffer( );
+
+	u1 b1 = p[ a_Position ];
+	u1 b2 = p[ a_Position + 1 ];
+	u1 b3 = p[ a_Position + 2 ];
+	u1 b4 = p[ a_Position + 3 ];
+	u1 b5 = p[ a_Position + 4 ];
+	u1 b6 = p[ a_Position + 5 ];
+	u1 b7 = p[ a_Position + 6 ];
+	u1 b8 = p[ a_Position + 7 ];
+
+	return ( ( (u8) b1 << 56 ) | ( (u8) b2 << 48 ) | ( (u8)b3 << 40 ) | ( (u8)b4 << 32 ) | ( (u8)b5 << 24 ) | ( (u8)b6 << 16 ) | ( (u8)b7 << 8 ) | b8 );
+}
+
+
+/*
+*/
+void MarshallerUtil::ProcessException( u1Array& a_Answer, const u4& a_ProtocolOffset ) {
+
+	u4 exceptionNamespace;
+	u4 exceptionName;
+	char* chst = NULL;
+
+	try {
+
+		exceptionNamespace = ComReadU4At( a_Answer, a_ProtocolOffset + 0 );
+
+		exceptionName = ComReadU2At( a_Answer, a_ProtocolOffset + 4 );
+
+		if( a_Answer.GetLength( ) > ( a_ProtocolOffset + 6 ) ) {
+
+			u2 strLen = ComReadU2At( a_Answer, a_ProtocolOffset + 6 );
+
+			if ((strLen > 0) && (strLen != 0xFFFF)) {
+
+				u2 len = ComputeLPSTRLength( a_Answer, a_ProtocolOffset + 8, strLen );
+
+				chst = new char[ len + 1 ];
+
+				chst[len] = '\0';
+
+				UTF8Decode( a_Answer, a_ProtocolOffset + 8, strLen, chst );
+			}
+		}
+	} catch (...) {
+
+		// someone is messing with the protocol
+		if( chst ) {
+			delete[ ] chst;
+		}
+
+		throw RemotingException( (char*)"" );
+	}
+
+	if( !chst ) {
+
+		// prepare empty string
+		chst = new char[1];
+
+		chst[0] = '\0';
+	}
+
+	// create a string object on the stack.
+	// when exception is thrown the exception object is copied on
+	// a temporary location and live till used by catch block
+	//
+	// it is not a good idea to pass chst as a parameter of exception object
+	// as there will be no way to delete it.
+	std::string chstr( chst );
+
+	delete[ ] chst;
+
+	switch( exceptionNamespace ) {
+
+	case HIVECODE_NAMESPACE_SYSTEM:
+		{
+			switch( exceptionName ) {
+
+			case (u2)HIVECODE_TYPE_SYSTEM_EXCEPTION:
+				throw Exception(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_SYSTEMEXCEPTION:
+				throw SystemException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_OUTOFMEMORYEXCEPTION:
+				throw OutOfMemoryException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_ARGUMENTEXCEPTION:
+				throw ArgumentException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_ARGUMENTNULLEXCEPTION:
+				throw ArgumentNullException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_NULLREFERENCEEXCEPTION:
+				throw NullReferenceException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_ARGUMENTOUTOFRANGEEXCEPTION:
+				throw ArgumentOutOfRangeException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_NOTSUPPORTEDEXCEPTION:
+				throw NotSupportedException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_INVALIDCASTEXCEPTION:
+				throw InvalidCastException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_INVALIDOPERATIONEXCEPTION:
+				throw InvalidOperationException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_NOTIMPLEMENTEDEXCEPTION:
+				throw NotImplementedException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_OBJECTDISPOSEDEXCEPTION:
+				throw ObjectDisposedException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_UNAUTHORIZEDACCESSEXCEPTION:
+				throw UnauthorizedAccessException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_INDEXOUTOFRANGEEXCEPTION:
+				throw IndexOutOfRangeException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_FORMATEXCEPTION:
+				throw FormatException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_ARITHMETICEXCEPTION:
+				throw ArithmeticException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_OVERFLOWEXCEPTION:
+				throw OverflowException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_BADIMAGEFORMATEXCEPTION:
+				throw BadImageFormatException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_APPLICATIONEXCEPTION:
+				throw ApplicationException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_ARRAYTYPEMISMATCHEXCEPTION:
+				throw ArrayTypeMismatchException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_DIVIDEBYZEROEXCEPTION:
+				throw DivideByZeroException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_MEMBERACCESSEXCEPTION:
+				throw MemberAccessException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_MISSINGMEMBEREXCEPTION:
+				throw MissingMemberException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_MISSINGFIELDEXCEPTION:
+				throw MissingFieldException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_MISSINGMETHODEXCEPTION:
+				throw MissingMethodException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_RANKEXCEPTION:
+				throw RankException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_STACKOVERFLOWEXCEPTION:
+				throw StackOverflowException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_TYPELOADEXCEPTION:
+				throw TypeLoadException(chstr);
+			}
+		}
+		break;
+
+	case HIVECODE_NAMESPACE_SYSTEM_IO:
+		{
+			switch(exceptionName) {
+
+			case (u2)HIVECODE_TYPE_SYSTEM_IO_IOEXCEPTION:
+				throw IOException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_IO_DIRECTORYNOTFOUNDEXCEPTION:
+				throw DirectoryNotFoundException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_IO_FILENOTFOUNDEXCEPTION:
+				throw FileNotFoundException(chstr);
+			}
+		}
+		break;
+
+	case HIVECODE_NAMESPACE_SYSTEM_SECURITY:
+		{
+			switch(exceptionName){
+			case (u2)HIVECODE_TYPE_SYSTEM_SECURITY_SECURITYEXCEPTION:
+				throw SecurityException(chstr);
+
+			case (u2)HIVECODE_TYPE_SYSTEM_SECURITY_VERIFICATIONEXCEPTION:
+				throw VerificationException(chstr);
+			}
+		}
+		break;
+
+	case HIVECODE_NAMESPACE_SYSTEM_RUNTIME_REMOTING:
+		{
+			switch(exceptionName){
+			case (u2)HIVECODE_TYPE_SYSTEM_RUNTIME_REMOTING_REMOTINGEXCEPTION:
+				throw RemotingException(chstr);
+			}
+		}
+		break;
+
+	case HIVECODE_NAMESPACE_SYSTEM_RUNTIME_SERIALIZATION:
+		{
+			switch(exceptionName){
+			case (u2)HIVECODE_TYPE_SYSTEM_RUNTIME_SERIALIZATION_SERIALIZATIONEXCEPTION:
+				throw SerializationException(chstr);
+			}
+		}
+		break;
+
+	case HIVECODE_NAMESPACE_SYSTEM_SECURITY_CRYPTOGRAPHY:
+		{
+			switch(exceptionName){
+			case (u2)HIVECODE_TYPE_SYSTEM_SECURITY_CRYPTOGRAPHY_CRYPTOGRAPHICEXCEPTION:
+				throw CryptographicException(chstr);
+			}
+		}
+		break;
+	}
+
+	// custom exception from the card application or someone is messing with the protocol
+	// no means of translation.
+	throw Exception( chstr );
+}
+
+
+/*
+*/
+u4 MarshallerUtil::CheckForException( u1Array& a_Answer, const u4& a_NameSpace, const u2& a_Type ) {
+
+	u1 protocolAnswerPrefix = a_Answer.ReadU1At( 0 );
+
+#ifdef SUPPORT_BETA_VERSION
+	if( protocolAnswerPrefix == 0 ) {
+
+		// beta version protocol (namespace & type systematically returned)
+		if( ( ComReadU4At( a_Answer, 0 ) != a_NameSpace ) || ( ComReadU2At( a_Answer, 4 ) != a_Type ) ) {
+
+			ProcessException( a_Answer, 0 );
+		}
+
+		// skip namespace & type
+		return ( 4 + 2 );
+	}
+#endif
+
+	// new protocol
+	if( protocolAnswerPrefix != 0x01 ) {
+
+		if( protocolAnswerPrefix == 0xFF ) {
+
+			// exception info expected in the buffer
+			ProcessException( a_Answer, 1 );
+
+		} else {
+
+			// someone is messing with the protocol
+			throw RemotingException( (char*)"" );
+		}
+	}
+
+	// skip return type info (protocolAnswerPrefix: 0x01 = ok, 0xFF = exception)
+	return 1;
+}
+
+
+/*
+*/
+void MarshallerUtil::ProcessByReferenceArguments( const u1& a_Type, u1Array* a_DataArray, u4* a_OffsetPtr, va_list* a_MarkerPtr, const u1&  a_isIn ) {
+	
+	//va_list marker = *markerPtr;
+	u4 offset = *a_OffsetPtr;
+
+	switch( a_Type ) {
+
+	case MARSHALLER_TYPE_REF_BOOL:
+	case MARSHALLER_TYPE_REF_U1:
+	case MARSHALLER_TYPE_REF_S1:
+		{
+			u1* val = va_arg( *a_MarkerPtr, u1* );
+
+			if( !val ) {
+
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if( a_isIn ) {
+
+				*a_DataArray += *val;
+			
+			} else {
+
+				*val = (*a_DataArray).ReadU1At( offset );
+			}
+
+			offset += sizeof( u1 );
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_CHAR:
+	case MARSHALLER_TYPE_REF_U2:
+	case MARSHALLER_TYPE_REF_S2:
+		{
+			u2* val = va_arg( *a_MarkerPtr, u2* );
+
+			if( !val ) {
+
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if( a_isIn ) {
+			
+				*a_DataArray += *val;
+			
+			} else {
+
+				*val = ComReadU2At( *a_DataArray, offset );
+			}
+
+			offset += sizeof( u2 );
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_U4:
+	case MARSHALLER_TYPE_REF_S4:
+		{
+			u4* val = va_arg( *a_MarkerPtr, u4* );
+
+			if( !val ) {
+
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if( a_isIn ) {
+			
+				*a_DataArray += *val;
+			
+			} else {
+
+				*val = ComReadU4At( *a_DataArray, offset );
+			}
+
+			offset += sizeof( u4 );
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_U8:
+	case MARSHALLER_TYPE_REF_S8:
+		{
+			u8* val = va_arg( *a_MarkerPtr, u8* );
+
+			if ( !val ) {
+			
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if ( a_isIn ) {
+			
+				*a_DataArray += *val;
+			
+			} else {
+
+				*val = ComReadU8At( *a_DataArray, offset );
+			}
+
+			offset += sizeof( u8 );
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_STRING:
+		{
+			std::string** val = va_arg( *a_MarkerPtr, std::string** );
+
+			if ( !val ) {
+
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if ( a_isIn ) {
+			
+				offset += sizeof(u2);
+				
+				if( *val ) {
+
+					offset += ComputeUTF8Length((char*)((*val)->c_str()));
+				}
+
+				(*a_DataArray).Append(*val);
+
+			} else {
+				
+				u2 len = ComReadU2At(*a_DataArray, offset);
+				
+				offset += sizeof(u2);
+				
+				if (len == 0xFFFF) {
+				
+					*val = NULL;
+				
+				} else {
+					// store result
+					u2 l = ComputeLPSTRLength(*a_DataArray, offset, len);
+				
+					char* chstr = new char[l + 1];
+					
+					try {
+					
+						chstr[l] = '\0';
+						
+						UTF8Decode(*a_DataArray, offset, len, chstr);
+						
+						*val = new std::string(chstr);
+					
+					} catch (...) {
+					
+						delete[] chstr;
+					
+						throw;
+					}
+
+					delete[] chstr;
+					
+					offset += len;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_S1ARRAY:
+	case MARSHALLER_TYPE_REF_BOOLARRAY:
+	case MARSHALLER_TYPE_REF_U1ARRAY:
+		{
+			u1Array** val = va_arg(*a_MarkerPtr, u1Array**);
+
+			if ( !val ) {
+			
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if ( a_isIn ) {
+
+				offset += sizeof(u4);
+				
+				if( !(*val)->IsNull( ) ) {
+					
+					u4  valLen = (*val)->GetLength();
+					
+					u1* valBuf = (*val)->GetBuffer();
+					
+					*a_DataArray += valLen;
+					
+					for(u4 v = 0; v < valLen; v++) {
+					
+						*a_DataArray += valBuf[v];
+					}
+
+					offset += (sizeof(u1) * valLen);
+				
+				} else {
+				
+					*a_DataArray += 0xFFFFFFFF;
+				}
+			} else {
+
+				u4 len = ComReadU4At(*a_DataArray, offset);
+
+				offset += sizeof(u4);
+
+				u1Array* refArray = NULL;
+
+				try {
+
+					if (len == 0xFFFFFFFF) {
+					
+						refArray = new u1Array();
+					
+					} else {
+					
+						refArray = new u1Array(len);
+						
+						for (u4 i = 0; i < len; i++) {
+						
+							refArray->SetU1At(i, a_DataArray->ReadU1At(offset));
+							
+							offset += sizeof(u1);
+						}
+					}
+				} catch (...) {
+
+					if ( refArray ) {
+					
+						delete refArray;
+					}
+
+					throw;
+				}
+
+				if( *val ) {
+					
+					// perform cleanup
+					delete *val;
+				}
+
+				*val = refArray;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_S2ARRAY:
+	case MARSHALLER_TYPE_REF_U2ARRAY:
+		{
+			u2Array** val = va_arg(*a_MarkerPtr, u2Array**);
+
+			if ( !val ) {
+			
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if ( a_isIn ) {
+				
+				offset += sizeof(u4);
+				
+				if( !(*val)->IsNull( ) ) {
+
+					u4  valLen = (*val)->GetLength();
+					
+					u2* valBuf = (*val)->GetBuffer();
+					
+					*a_DataArray += valLen;
+					
+					for(u4 v = 0; v < valLen; v++) {
+					
+						*a_DataArray += valBuf[v];
+					}
+
+					offset += (sizeof(u2) * valLen);
+				
+				} else {
+				
+					*a_DataArray += 0xFFFFFFFF;
+				}
+			} else {
+
+				u4 len = ComReadU4At(*a_DataArray, offset);
+				
+				offset += sizeof(u4);
+
+				u2Array* refArray = NULL;
+
+				try {
+				
+					if (len == 0xFFFFFFFF) {
+					
+						refArray = new u2Array(-1);
+			
+					} else {
+					
+						refArray = new u2Array(len);
+						
+						for (u4 i = 0; i < len; i++) {
+						
+							refArray->SetU2At(i, ComReadU2At(*a_DataArray, offset));
+							
+							offset += sizeof(u2);
+						}
+					}
+				} catch (...) {
+					
+					if ( refArray ) {
+					
+						delete refArray;
+					}
+
+					throw;
+				}
+
+				if( *val ) {
+					
+					// perform cleanup
+					delete *val;
+				}
+
+				*val = refArray;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_S4ARRAY:
+	case MARSHALLER_TYPE_REF_U4ARRAY:
+		{
+			u4Array** val = va_arg(*a_MarkerPtr, u4Array**);
+
+			if ( !val ) {
+			
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if ( a_isIn ) {
+				
+				offset += sizeof(u4);
+				
+				if( !(*val)->IsNull( ) ) {
+
+					u4  valLen = (*val)->GetLength();
+					
+					u4* valBuf = (*val)->GetBuffer();
+					
+					*a_DataArray += valLen;
+					
+					for(u4 v = 0; v < valLen; v++) {
+					
+						*a_DataArray += valBuf[v];
+					}
+
+					offset += (sizeof(u4) * valLen);
+				
+				} else {
+				
+					*a_DataArray += 0xFFFFFFFF;
+				}
+			} else {
+
+				u4 len = ComReadU4At(*a_DataArray, offset);
+				
+				offset += sizeof(u4);
+
+				u4Array* refArray = NULL;
+
+				try {
+				
+					if (len == 0xFFFFFFFF) {
+					
+						refArray = new u4Array(-1);
+				
+					} else {
+					
+						refArray = new u4Array(len);
+						
+						for (u4 i = 0; i < len; i++) {
+						
+							refArray->SetU4At(i, ComReadU4At(*a_DataArray, offset));
+							
+							offset += sizeof(u4);
+						}
+					}
+				} catch (...) {
+					
+					if ( refArray ) {
+					
+						delete refArray;
+					}
+
+					throw;
+				}
+
+				if( *val ) {
+					
+					// perform cleanup
+					delete *val;
+				}
+
+				*val = refArray;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_REF_S8ARRAY:
+	case MARSHALLER_TYPE_REF_U8ARRAY:
+		{
+			u8Array** val = va_arg(*a_MarkerPtr, u8Array**);
+			if ( !val ) {
+			
+				throw NullReferenceException( (char*)"" );
+			}
+
+			if ( a_isIn ) {
+				
+				offset += sizeof(u4);
+				
+				if (!(*val)->IsNull() ) {
+				
+					u4  valLen = (*val)->GetLength();
+					
+					u8* valBuf = (*val)->GetBuffer();
+					
+					*a_DataArray += valLen;
+					
+					for(u4 v = 0; v < valLen; v++) {
+					
+						*a_DataArray += valBuf[v];
+					}
+
+					offset += (sizeof(u8) * valLen);
+			
+				} else {
+				
+					*a_DataArray += 0xFFFFFFFF;
+				}
+			} else {
+
+				u4 len = ComReadU4At(*a_DataArray, offset);
+				
+				offset += sizeof(u4);
+
+				u8Array* refArray = NULL;
+
+				try {
+				
+					if (len == 0xFFFFFFFF) {
+					
+						refArray = new u8Array(-1);
+				
+					} else {
+					
+						refArray = new u8Array(len);
+						
+						for (u4 i = 0; i < len; i++) {
+						
+							refArray->SetU8At(i, ComReadU8At(*a_DataArray, offset));
+							
+							offset += sizeof(u4);
+						}
+					}
+				} catch (...) {
+					
+					if ( refArray ) {
+					
+						delete refArray;
+					}
+
+					throw;
+				}
+
+				if( *val ) {
+					
+					// perform cleanup
+					delete *val;
+				}
+
+				*val = refArray;
+			}
+		}
+		break;
+
+	default:
+		{
+			if ( a_isIn ) {
+				
+				throw Exception("Un-recognized input argument type");
+			
+			} else {
+			
+				throw Exception("Un-recognized byref argument type");
+			}
+		}
+		break;
+	}
+
+	*a_OffsetPtr = offset;
+}
+
+
+/*
+*/
+void MarshallerUtil::ProcessOutputArguments( const u1& a_Type, u1Array* a_AnswerPtr, u4* a_OffsetPtr, va_list* a_MarkerPtr ) {
+
+	switch( a_Type ) {
+
+	case MARSHALLER_TYPE_IN_BOOL:
+	case MARSHALLER_TYPE_IN_S1:
+	case MARSHALLER_TYPE_IN_U1:
+	case MARSHALLER_TYPE_IN_CHAR:
+	case MARSHALLER_TYPE_IN_S2:
+	case MARSHALLER_TYPE_IN_U2:
+	case MARSHALLER_TYPE_IN_S4:
+	case MARSHALLER_TYPE_IN_U4:
+	case MARSHALLER_TYPE_IN_STRING:
+	case MARSHALLER_TYPE_IN_MEMORYSTREAM:
+	case MARSHALLER_TYPE_IN_BOOLARRAY:
+	case MARSHALLER_TYPE_IN_S1ARRAY:
+	case MARSHALLER_TYPE_IN_U1ARRAY:
+	case MARSHALLER_TYPE_IN_CHARARRAY:
+	case MARSHALLER_TYPE_IN_S2ARRAY:
+	case MARSHALLER_TYPE_IN_U2ARRAY:
+	case MARSHALLER_TYPE_IN_S4ARRAY:
+	case MARSHALLER_TYPE_IN_U4ARRAY:
+	case MARSHALLER_TYPE_IN_S8ARRAY:
+	case MARSHALLER_TYPE_IN_U8ARRAY:
+	case MARSHALLER_TYPE_IN_STRINGARRAY:
+		{
+			// ignore input argument (slot size = 4 bytes)
+			va_arg( *a_MarkerPtr, u4 );
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_S8:
+	case MARSHALLER_TYPE_IN_U8:
+		{
+			// ignore input argument (slot size = 8 bytes)
+			va_arg( *a_MarkerPtr, u8 );
+		}
+		break;
+
+	default:
+		ProcessByReferenceArguments( a_Type, a_AnswerPtr, a_OffsetPtr, a_MarkerPtr, false );
+		break;
+	}
+}
+
+
+/*
+*/
+u4 MarshallerUtil::ProcessReturnType( const u1& a_Type, u1Array* a_AnswerPtr, va_list* a_MarkerPtr ) {
+
+	u1Array answer = *a_AnswerPtr;
+
+	u4 offset = 0;
+
+	switch( a_Type ) {
+
+		// void (can happen for the method return param)
+	case MARSHALLER_TYPE_RET_VOID:
+		{
+			if (answer.GetLength() > 0) {
+#ifdef SUPPORT_BETA_VERSION
+				if (answer.ReadU1At(0) == 0x00) {
+					// beta version protocol
+					ProcessException(answer, 0);
+				}
+#endif
+				// new protocol
+				ProcessException(answer, 1);
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_BOOL:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BOOLEAN);
+			u1* valToReturn = va_arg(*a_MarkerPtr, u1*);
+			if (answer.ReadU1At(offset) == 0) {
+				*valToReturn = FALSE;
+			} else {
+				*valToReturn = TRUE;
+			}
+			offset += sizeof(u1);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S1:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_SBYTE);
+			s1* valToReturn = va_arg(*a_MarkerPtr, s1*);
+			*valToReturn = answer.ReadU1At(offset);
+			offset += sizeof(u1);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U1:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BYTE);
+			u1* valToReturn = va_arg(*a_MarkerPtr, u1*);
+			*valToReturn = answer.ReadU1At(offset);
+			offset += sizeof(u1);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_CHAR:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_CHAR);
+			char* valToReturn = va_arg(*a_MarkerPtr, char*);
+			*valToReturn = (char)ComReadU2At(answer, offset);
+			offset += sizeof(u2);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S2:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT16);
+			s2* valToReturn = va_arg(*a_MarkerPtr, s2*);
+			*valToReturn = ComReadU2At(answer, offset);
+			offset += sizeof(u2);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U2:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT16);
+			u2* valToReturn = va_arg(*a_MarkerPtr, u2*);
+			*valToReturn = ComReadU2At(answer, offset);
+			offset += sizeof(u2);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S4:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32);
+			s4* valToReturn = va_arg(*a_MarkerPtr, s4*);
+			*valToReturn = ComReadU4At(answer, offset);
+			offset += sizeof(u4);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U4:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT32);
+			u4* valToReturn = va_arg(*a_MarkerPtr, u4*);
+			*valToReturn = ComReadU4At(answer, offset);
+			offset += sizeof(u4);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S8:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT64);
+			s8* valToReturn = va_arg(*a_MarkerPtr, s8*);
+			*valToReturn = ComReadU8At(answer, offset);
+			offset += sizeof(u8);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U8:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT64);
+			u8* valToReturn = va_arg(*a_MarkerPtr, u8*);
+			*valToReturn = ComReadU8At(answer, offset);
+			offset += sizeof(u8);
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_STRING:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_STRING);
+			std::string** valToReturn = va_arg(*a_MarkerPtr, std::string**);
+			u2 len = ComReadU2At(answer, offset);
+			offset += sizeof(u2);
+			if (len == 0xFFFF) {
+				*valToReturn = NULL;
+			} else {
+				// store result
+				u2 l = ComputeLPSTRLength(answer, offset, len);
+				char* chstr = new char[l + 1];
+				try {
+					chstr[l] = '\0';
+					UTF8Decode(answer, offset, len, chstr);
+					*valToReturn = new std::string(chstr);
+				} catch (...) {
+					delete[] chstr;
+					throw;
+				}
+				delete[] chstr;
+				offset += len;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_BOOLARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BOOLEAN_ARRAY);
+			u1Array** valToReturn = va_arg(*a_MarkerPtr, u1Array**);
+			u4 len = ComReadU4At(answer, offset);
+			offset += sizeof(u4);
+			if (len == 0xFFFFFFFF) {
+				*valToReturn = new u1Array();
+			} else {
+				// store result
+				*valToReturn = new u1Array(answer, offset, len);
+				offset += len;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S1ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_SBYTE_ARRAY);
+			s1Array** valToReturn = va_arg(*a_MarkerPtr, s1Array**);
+			u4 len = ComReadU4At(answer, offset);
+			offset += sizeof(u4);
+			if (len == 0xFFFFFFFF) {
+				*valToReturn = new s1Array();
+			} else {
+				// store result
+				*valToReturn = new s1Array(answer, offset, len);
+				offset += len;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U1ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_BYTE_ARRAY);
+
+			u1Array** valToReturn = va_arg(*a_MarkerPtr, u1Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new u1Array();
+			
+			} else {
+			
+				// store result
+				*valToReturn = new u1Array(answer, offset, len);
+				
+				offset += len;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_CHARARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_CHAR_ARRAY);
+
+			charArray** valToReturn = va_arg(*a_MarkerPtr, charArray**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new charArray(-1);
+		
+			} else {
+			
+				// store result
+				*valToReturn = new charArray(len);
+				
+				try {
+				
+					u2* p = (*valToReturn)->GetBuffer( );
+
+					for (u4 j = 0; j < len; j++) {
+					
+						p[j] = ComReadU2At(answer, offset);
+						
+						offset += sizeof(s2);
+					}
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S2ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT16_ARRAY);
+
+			s2Array** valToReturn = va_arg(*a_MarkerPtr, s2Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new s2Array(-1);
+			
+			} else {
+			
+				// store result
+				*valToReturn = new s2Array(len);
+				
+				try {
+				
+					u2* p = (*valToReturn)->GetBuffer();
+
+					for (u4 j = 0; j < len; j++) {
+					
+						p[j] = ComReadU2At(answer, offset);
+						
+						offset += sizeof(s2);
+					}
+
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U2ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT16_ARRAY);
+
+			u2Array** valToReturn = va_arg(*a_MarkerPtr, u2Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new u2Array(-1);
+			
+			} else {
+			
+				// store result
+				*valToReturn = new u2Array(len);
+				
+				try {
+				
+					u2* p = (*valToReturn)->GetBuffer( );
+
+					for (u4 j = 0; j < len; j++) {
+					
+						p[j] = ComReadU2At(answer, offset);
+						
+						offset += sizeof(u2);
+					}
+
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S4ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32_ARRAY);
+
+			s4Array** valToReturn = va_arg(*a_MarkerPtr, s4Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new s4Array(-1);
+			
+			} else {
+			
+				// store result
+				*valToReturn = new s4Array(len);
+				
+				try {
+				
+					u4* p = (*valToReturn)->GetBuffer( );
+
+					for (u4 j = 0; j < len; j++) {
+					
+						p[j] = ComReadU4At(answer, offset);
+						
+						offset += sizeof(s4);
+					}
+
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U4ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT32_ARRAY);
+
+			u4Array** valToReturn = va_arg(*a_MarkerPtr, u4Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new u4Array(-1);
+			
+			} else {
+				
+				// store result
+				*valToReturn = new u4Array(len);
+				
+				u4* p = (*valToReturn)->GetBuffer( );
+
+				try {
+				
+					for (u4 j = 0; j < len; j++) {
+					
+						p[j] = ComReadU4At(answer, offset);
+						
+						offset += sizeof(u4);
+					}
+
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_S8ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT64_ARRAY);
+			
+			s8Array** valToReturn = va_arg(*a_MarkerPtr, s8Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new s8Array(-1);
+			
+			} else {
+			
+				// store result
+				*valToReturn = new s8Array(len);
+				
+				try {
+				
+					u8* p = (*valToReturn)->GetBuffer( );
+					for (u4 j = 0; j < len; j++) {
+
+						p[j] = ComReadU8At(answer, offset);
+
+						offset += sizeof(s8);
+					}
+
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_U8ARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_UINT64_ARRAY);
+
+			u8Array** valToReturn = va_arg(*a_MarkerPtr, u8Array**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new u8Array(-1);
+			
+			} else {
+			
+				// store result
+				*valToReturn = new u8Array(len);
+				
+				try {
+				
+					u8* p = (*valToReturn)->GetBuffer( );
+
+					for (u4 j = 0; j < len; j++) {
+					
+						p[j] = ComReadU8At(answer, offset);
+						
+						offset += sizeof(u8);
+					}
+
+				} catch (...) {
+					
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_STRINGARRAY:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_STRING_ARRAY);
+
+			StringArray** valToReturn = va_arg(*a_MarkerPtr, StringArray**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new StringArray();
+			
+			} else {
+			
+				// store result
+				*valToReturn = new StringArray(len);
+				
+				try {
+
+					u2 lenStr = 0;
+					u2 blen = 0;
+					char* lpstr = 0;
+					for( u4 j = 0 ; j < len ; ++j ) {
+					
+						lenStr = ComReadU2At( answer, offset );
+						
+						offset += sizeof( u2 );
+						
+						if (lenStr != 0xFFFF) {
+						
+							blen = ComputeLPSTRLength( answer, offset, lenStr );
+							
+							lpstr = new char[blen + 1];
+							
+							try {
+							
+								lpstr[blen] = '\0';
+								
+								UTF8Decode(answer, offset, lenStr, lpstr);
+								
+								offset += lenStr;
+
+								(*valToReturn)->SetStringAt(j, new std::string(lpstr));
+							
+							} catch (...) {
+							
+								delete[] lpstr;
+								
+								throw;
+							}
+
+							delete[] lpstr;
+						}
+					}
+				} catch (...) {
+
+					delete *valToReturn;
+					
+					throw;
+				}
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_RET_MEMORYSTREAM:
+		{
+			offset += CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM_IO, HIVECODE_TYPE_SYSTEM_IO_MEMORYSTREAM);
+
+			MemoryStream** valToReturn = va_arg(*a_MarkerPtr, MemoryStream**);
+			
+			u4 len = ComReadU4At(answer, offset);
+			
+			offset += sizeof(u4);
+			
+			if (len == 0xFFFFFFFF) {
+			
+				*valToReturn = new MemoryStream();
+			
+			} else {
+			
+				// store result
+				*valToReturn = new MemoryStream(answer, offset, len);
+				
+				offset += len;
+			}
+		}
+		break;
+
+	default:
+		throw Exception("Un-recognized return type");
+	}
+
+	return offset;
+}
+
+
+/*
+*/
+void MarshallerUtil::ProcessInputArguments( const u1& a_Type, u1Array* a_InvokeAPDU_data, va_list* a_MarkerPtr ) {
+
+	switch( a_Type ) {
+
+	case MARSHALLER_TYPE_IN_BOOL:
+	case MARSHALLER_TYPE_IN_S1:
+	case MARSHALLER_TYPE_IN_U1:
+		{
+			u1 val = (u1)va_arg(*a_MarkerPtr, s4);
+
+			*a_InvokeAPDU_data += val;
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_CHAR:
+	case MARSHALLER_TYPE_IN_S2:
+	case MARSHALLER_TYPE_IN_U2:
+		{
+			u2 val = (u2)va_arg(*a_MarkerPtr, s4);
+
+			*a_InvokeAPDU_data += val;
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_S4:
+	case MARSHALLER_TYPE_IN_U4:
+		{
+			u4 val = (u4)va_arg(*a_MarkerPtr, s4);
+
+			*a_InvokeAPDU_data += val;
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_S8:
+	case MARSHALLER_TYPE_IN_U8:
+		{
+			u8 val = (u8)va_arg(*a_MarkerPtr,u8);
+
+			*a_InvokeAPDU_data += val;
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_STRING:
+		{
+			char * val = va_arg(*a_MarkerPtr, char*);
+            
+			(*a_InvokeAPDU_data).Append(val);
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_MEMORYSTREAM:
+	case MARSHALLER_TYPE_IN_BOOLARRAY:
+	case MARSHALLER_TYPE_IN_S1ARRAY:
+	case MARSHALLER_TYPE_IN_U1ARRAY:
+		{
+			u1Array* val = va_arg(*a_MarkerPtr, u1Array*);
+
+			if( val && !val->IsNull( ) ) {
+			
+				u4  valLen = val->GetLength( );
+				
+				u1* valBuf = val->GetBuffer( );
+				
+				// add length
+				*a_InvokeAPDU_data += valLen;
+				
+				// add data
+				for( u4 v = 0; v < valLen ; ++v ) {
+				
+					*a_InvokeAPDU_data += valBuf[v];
+				}
+
+			} else {
+			
+				// add null pointer
+				*a_InvokeAPDU_data += (u4)0xFFFFFFFF;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_CHARARRAY:
+	case MARSHALLER_TYPE_IN_S2ARRAY:
+	case MARSHALLER_TYPE_IN_U2ARRAY:
+		{
+			u2Array* val = va_arg(*a_MarkerPtr, u2Array*);
+
+			if( val && !val->IsNull( ) ) {
+			
+				u4  valLen = val->GetLength();
+				
+				u2* valBuf = val->GetBuffer();
+				
+				*a_InvokeAPDU_data += valLen;
+				
+				for( u4 v = 0 ; v < valLen ; ++v ) {
+
+					*a_InvokeAPDU_data += valBuf[v];
+				}
+
+			} else {
+				
+				// add null pointer
+				*a_InvokeAPDU_data += (u4)0xFFFFFFFF;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_S4ARRAY:
+	case MARSHALLER_TYPE_IN_U4ARRAY:
+		{
+			u4Array* val = va_arg(*a_MarkerPtr, u4Array*);
+
+			if( val && !val->IsNull( ) ) {
+			
+				u4  valLen = val->GetLength();
+				
+				u4* valBuf = val->GetBuffer();
+
+				*a_InvokeAPDU_data += valLen;
+
+				for( u4 v = 0 ; v < valLen ; ++v ) {
+
+					*a_InvokeAPDU_data += valBuf[v];
+				}
+
+			} else {
+
+				// add null pointer
+				*a_InvokeAPDU_data += (u4)0xFFFFFFFF;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_S8ARRAY:
+	case MARSHALLER_TYPE_IN_U8ARRAY:
+		{
+			u8Array* val = va_arg(*a_MarkerPtr, u8Array*);
+			
+			if( val && !val->IsNull( ) ) {
+			
+				u4  valLen = val->GetLength();
+				
+				u8* valBuf = val->GetBuffer();
+				
+				*a_InvokeAPDU_data += valLen;
+				
+				for( u4 v = 0 ; v < valLen ; ++v ) {
+
+					*a_InvokeAPDU_data += valBuf[v];
+				}
+
+			} else {
+				
+				// add null pointer
+				*a_InvokeAPDU_data += (u4)0xFFFFFFFF;
+			}
+		}
+		break;
+
+	case MARSHALLER_TYPE_IN_STRINGARRAY:
+		{
+			StringArray* val = va_arg(*a_MarkerPtr, StringArray*);
+
+			if( val && !val->IsNull( ) ) {
+
+				u4  valLen = val->GetLength();
+
+				*a_InvokeAPDU_data += valLen;
+
+				// add data
+				for( u4 j = 0 ; j < valLen ; ++j ) {
+
+					std::string* str = val->GetStringAt(j);
+
+					if( str ){
+
+						(*a_InvokeAPDU_data).Append(str);
+					
+					}else{ 
+						// add null pointer
+						*a_InvokeAPDU_data += (u2)0xFFFF;
+					}
+				}
+
+			} else {
+				
+				// add null pointer
+				*a_InvokeAPDU_data += (u4)0xFFFFFFFF;
+			}
+		}
+		break;
+
+	default:
+		u4 offset = 0;
+
+		ProcessByReferenceArguments( a_Type, a_InvokeAPDU_data, &offset, a_MarkerPtr, true );
+		
+		// do not adjust a_MarkerPtr.
+		return;
+
+	}
+}
+
+
+MARSHALLER_NS_END

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.h	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerUtil.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,62 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifndef __GEMALTO_MARSHALLER_UTIL_H__
+#define __GEMALTO_MARSHALLER_UTIL_H__
+
+#include <stdarg.h>
+
+#include "MarshallerCfg.h"
+#include "Array.hpp"
+
+
+MARSHALLER_NS_BEGIN
+
+
+class MarshallerUtil {
+
+public:
+
+	u2 ComReadU2At( u1Array&, const u4& );
+
+	u4 ComReadU4At( u1Array&, const u4& );
+
+	u8 ComReadU8At( u1Array&, const u4& );
+
+	void ProcessException( u1Array&, const u4& );
+
+	u4 CheckForException( u1Array&, const u4&, const u2& );
+
+	void ProcessByReferenceArguments( const u1&, u1Array*, u4*, va_list*, const u1& );
+
+	void ProcessOutputArguments( const u1&, u1Array*, u4*, va_list*);
+
+	u4 ProcessReturnType( const u1&, u1Array*, va_list* );
+
+	void ProcessInputArguments( const u1&, u1Array*, va_list* );
+
+};
+
+MARSHALLER_NS_END
+
+#endif // __GEMALTO_MARSHALLER_UTIL_H__
+
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,842 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/shared_array.hpp>
+#include <boost/foreach.hpp>
+#include <boost/crc.hpp>
+#include <boost/filesystem.hpp>
+#include "MiniDriver.hpp"
+#include "Log.hpp"
+#include "Except.h"
+#include "MiniDriverException.hpp"
+#include "util.h"
+#include "zlib.h"
+#include "SmartCardReader.hpp"
+#ifdef WIN32 
+#include <shlobj.h> // For SHGetFolderPath
+#else
+#endif
+#include <fstream>
+
+#include "PCSCMissing.h"
+
+
+const unsigned MiniDriver::s_iMinLengthKeyRSA = 512;
+const unsigned MiniDriver::s_iMaxLengthKeyRSA = 2048;
+
+#define BLOCK_SIZE 1024
+
+
+/*
+*/
+void MiniDriver::read( const bool& a_bEnableCache ) {
+
+    Log::begin( "MiniDriver::read" );
+    Timer t;
+    t.start( );
+
+    m_bEnableCache = a_bEnableCache;
+
+    try {
+
+        // Read the smart card serial number
+        getSerialNumber( );
+        
+        if( !m_u1aSerialNumber ) {
+        
+            m_stFileName = "";
+
+            m_bEnableCache = false;
+        }
+
+		if( m_bEnableCache ) {
+
+#ifdef WIN32 
+
+        // For each user (roaming) data, use the CSIDL_APPDATA value. 
+        // This defaults to the following path: "\Documents and Settings\All Users\Application Data" 
+        TCHAR szPath[MAX_PATH];
+
+        SHGetFolderPath( NULL, CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath );
+
+        std::string stCacheDirectoryPath = std::string( szPath ) + std::string( "/Gemalto/DotNet PKCS11" );
+
+#else
+		char *home = getenv( "HOME" );
+		std::string stCacheDirectoryPath;
+		if (home)
+			stCacheDirectoryPath = std::string(home) + std::string( "/.cache/Gemalto/DotNet PKCS11/" );
+		else
+			stCacheDirectoryPath = std::string( "/tmp/Gemalto/DotNet PKCS11/" );
+#endif
+			
+			boost::filesystem::path cacheDirectoryPath( stCacheDirectoryPath );
+			
+			if( ! boost::filesystem::exists( cacheDirectoryPath ) ) {
+
+				try {
+
+					boost::filesystem::create_directories( cacheDirectoryPath );
+				
+                } catch (...) {
+				
+                    std::string msg = "";
+
+                    Log::toString( msg, "Cache directory creation failed <%s>", stCacheDirectoryPath.c_str( ) );
+                    
+                    Log::error( "MiniDriver::read", msg.c_str( ) );
+
+                    m_bEnableCache = false;
+				}
+			}
+			
+            if( m_bEnableCache ) {
+
+			    // Build the cache file name
+			    std::string stCacheFileName = "";
+
+			    toString( m_u1aSerialNumber->GetBuffer( ), m_u1aSerialNumber->GetLength( ), stCacheFileName );
+			    
+                stCacheFileName += std::string( ".p11" );
+			
+			    m_stFileName = stCacheDirectoryPath + std::string( "/" ) + stCacheFileName;
+			    
+                Log::log( "MiniDriver::read - Cache file <%s>", m_stFileName.c_str( ) );
+			
+			    // Read the cache from the disk
+			    cacheDeserialize( );
+            }
+		}
+
+        MiniDriverCardCacheFile::ChangeType p = MiniDriverCardCacheFile::NONE;
+        MiniDriverCardCacheFile::ChangeType c = MiniDriverCardCacheFile::NONE;
+        MiniDriverCardCacheFile::ChangeType f = MiniDriverCardCacheFile::NONE;
+        m_Files.hasChanged( p, c, f );
+
+        m_Authentication.read( );
+
+    } catch( ... ) {
+
+		Log::log("MiniDriver::read - Exception");
+    }
+
+    t.stop( "MiniDriver::read" );
+    Log::end( "MiniDriver::read" );
+}
+
+
+/* Store the files, the file list and the containers into a disk file
+*/
+void MiniDriver::cacheSerialize( void ) {
+
+    // Cache enabled/disbled
+    if( !m_bEnableCache ) {
+
+        return;
+    }
+
+    // Name of the cache
+    if( m_stFileName.empty( ) ) {
+
+        return;
+    }
+
+    //m_Files.print( );
+    //m_Authentication.print( );
+
+    m_Files.cacheDisableWrite( );
+
+    Log::begin( "MiniDriver::cacheSerialize" );
+    Timer t;
+    t.start( );
+
+    std::ofstream ofs( m_stFileName.c_str( ), std::ios_base::out | std::ios_base::binary | std::ios_base::trunc );
+
+    if( ofs.is_open( ) ) {
+
+        // Write class instance to archive. Writing seems to work ok.
+        boost::archive::text_oarchive oa( ofs );
+
+        const MiniDriver& m = (MiniDriver&)*this;
+
+        oa << m;
+
+        ofs.flush( );
+
+        ofs.close( );
+    }
+
+    boost::crc_32_type::value_type computedValue = 0;
+    
+    std::ifstream ifs( m_stFileName.c_str( ), std::ios::in | std::ios::binary );
+    
+    if( ifs.is_open( ) ) {
+
+        // Get the length of the file
+        ifs.seekg( 0, std::ios::end );
+        
+        unsigned int l = (unsigned int)ifs.tellg( );
+
+        // Read the whole file
+        ifs.seekg( 0, std::ios::beg );
+        
+        std::auto_ptr< char > p( new char[ l ] );
+        
+        ifs.read( p.get( ), l );
+
+        // Compute the CRC of the file
+        boost::crc_32_type computedCRC; 
+        
+        computedCRC.process_bytes( p.get( ), l );
+        
+        computedValue = computedCRC.checksum( ); 
+
+        ifs.close( );
+    }
+
+    // Add the CRC to the file
+    ofs.open( m_stFileName.c_str( ), std::ios::in | std::ios::binary );
+
+    if( ofs.is_open( ) ) {
+
+        ofs.seekp( 0, std::ios::end );
+        
+        //ofs << computedValue;
+        ofs.write( (char*)&computedValue, sizeof( computedValue ) );
+
+        ofs.flush( );
+
+        ofs.close( );
+    }
+
+    //m_Files.print( );
+    //m_Authentication.print( );
+
+    t.stop( "MiniDriver::cacheSerialize" );
+    Log::end( "MiniDriver::cacheSerialize" );
+}
+
+
+/* Load the files, the file list and the containers from a disk file
+*/
+void MiniDriver::cacheDeserialize( void ) {
+
+    if( !m_bEnableCache ) {
+        return;
+    }
+
+    if( m_stFileName.empty( ) ) {
+        return;
+    }
+
+    Log::begin( "MiniDriver::cacheDeserialize" );
+    Timer t;
+    t.start( );
+
+    boost::crc_32_type::value_type readValue = 0; 
+
+    std::ifstream ifs( m_stFileName.c_str( ), std::ios::in | std::ios::binary );
+
+    if( ifs.is_open( ) ) {
+
+        try {
+
+			boost::archive::text_iarchive ia( ifs );
+
+			MiniDriver& m = (MiniDriver&)*this;
+
+            // Read the cache from the file
+            ia >> m;
+
+            // Read the CRC from the file
+            ifs.seekg( 0, std::ios::end );
+            unsigned int l = (unsigned int)ifs.tellg( ) - 4;
+            ifs.seekg( l, std::ios::beg );
+
+            ifs.read( (char*)&readValue, sizeof( readValue ) );
+
+            ifs.close( );
+        
+        } catch( ... ) {
+        
+            Log::error( "MiniDriver::cacheDeserialize", "deserialization failed" );
+
+            m_Files.clear( MiniDriverCardCacheFile::PINS );
+            m_Files.clear( MiniDriverCardCacheFile::FILES );
+            m_Files.clear( MiniDriverCardCacheFile::CONTAINERS );
+                       
+            ifs.close( );
+
+            std::remove( m_stFileName.c_str( ) );
+        }
+    }
+
+    // Compute the CRC of the file
+    boost::crc_32_type::value_type computedValue = 0;
+    
+    ifs.open( m_stFileName.c_str( ), std::ios::in | std::ios::binary );
+    
+    if( ifs.is_open( ) ) {
+
+        // Get the length of the file
+        ifs.seekg( 0, std::ios::end );
+        
+        unsigned int l = (unsigned int)ifs.tellg( ) - 4;
+
+        // Read the whole file
+        ifs.seekg( 0, std::ios::beg );
+        
+        std::auto_ptr< char > p( new char[ l ] );
+        
+        ifs.read( p.get( ), l );
+
+        // Compute the CRC of the file
+        boost::crc_32_type computedCRC; 
+        
+        computedCRC.process_bytes( p.get( ), l );
+        
+        computedValue = computedCRC.checksum( ); 
+
+        ifs.close( );
+    }
+
+    // Check the both CRC
+    if( computedValue != readValue ) {
+    
+        // Clear the cache
+        m_Files.clear( MiniDriverCardCacheFile::PINS );
+
+        m_Files.clear( MiniDriverCardCacheFile::FILES );
+        
+        m_Files.clear( MiniDriverCardCacheFile::CONTAINERS );
+
+        // Remove the cache file
+        std::remove( m_stFileName.c_str( ) );
+    }
+
+    //m_Files.print( );
+    //m_Authentication.print( );
+
+    t.stop( "MiniDriver::cacheDeserialize" );
+    Log::end( "MiniDriver::cacheDeserialize" );
+}
+
+
+/*
+*/
+Marshaller::u1Array* MiniDriver::getSerialNumber( void ) {
+
+    Log::begin( "MiniDriver::getSerialNumber" );
+    Timer t;
+    t.start( );
+
+    if( !m_u1aSerialNumber.get( ) ) {
+
+        try {
+
+            // Read the cardid file containing a unique 16-byte binary identifier for the smart card (GUID).
+            std::string s( szCARD_IDENTIFIER_FILE );
+
+            //std::auto_ptr< Marshaller::u1Array > f( m_CardModule->readFile( &s ) );
+            
+            std::string stDirectory;
+
+            std::auto_ptr< Marshaller::u1Array > f( m_Files.readFileWithoutCheck( stDirectory, s ) );
+            
+            // Get the 12th last bytes as serial number
+            m_u1aSerialNumber.reset( new Marshaller::u1Array( *f, 4, 12 ) );
+            
+            
+            Log::logCK_UTF8CHAR_PTR( "MiniDriver::getSerialNumber - Serial number", m_u1aSerialNumber->GetBuffer( ), m_u1aSerialNumber->GetLength( ) );
+            
+        } catch( MiniDriverException& ) {
+        
+            int i = 0;
+        }
+
+        //// Try first to load the serial number in a V2+ way
+        //try {
+
+        //    m_u1aSerialNumber.reset( m_CardModule->getCardProperty( CARD_SERIAL_NUMBER, 0 ) );
+
+        //    Log::log( "MiniDriver::getSerialNumber - GetCardProperty" );
+
+        //} catch( MiniDriverException& ) {
+
+        //    Log::error( " MiniDriver::getSerialNumber", "No card property for the serial number" );
+
+        //    try {
+
+        //        // Try at last to get the serial number in a old V2 way
+        //        m_u1aSerialNumber.reset( m_CardModule->getSerialNumber( ) );
+
+        //        Log::log( "MiniDriver::getSerialNumber - getSerialNumber" );
+
+        //    } catch( ... ) {
+
+        //        Log::error( " MiniDriver::getSerialNumber", "Impossible to get the serial number" );
+        //    }
+        //}
+    }
+
+    t.stop( "MiniDriver::getSerialNumber" );
+    Log::end( "MiniDriver::getSerialNumber" );
+
+    return m_u1aSerialNumber.get( );
+}
+
+
+/*
+*/
+void MiniDriver::createFile(  const std::string& a_stDirectory, const std::string& a_stFile, const bool& a_bIsReadProtected ) {
+
+    Log::begin( "MiniDriver::createFile" );
+    Timer t;
+    t.start( );
+
+    Marshaller::u1Array ac( 3 );
+
+    // Administrator access condition
+    ac.GetBuffer( )[ 0 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    // User access condition
+    ac.GetBuffer( )[ 1 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    // Everyone access condition
+    ac.GetBuffer( )[ 2 ] = ( a_bIsReadProtected ? 0 : MiniDriverFiles::CARD_PERMISSION_READ );
+
+    m_Files.createFile( a_stDirectory, a_stFile, &ac );
+
+    cacheSerialize( );
+
+    t.stop( "MiniDriver::createFile" );
+    Log::end( "MiniDriver::createFile" );
+}
+
+
+/* If a container already exists using the same public key modulus then the container index will be updated with the index of this container.
+The keyspec will also be updated. The file name will anyway build automaticaly
+*/
+void MiniDriver::createCertificate( unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec, std::string& a_stCertificateName, Marshaller::u1Array* a_pValue, Marshaller::u1Array* a_pModulus, const bool& a_bSmartCardLogon ) {
+
+    Log::begin( "MiniDriver::createCertificate" );
+    Timer t;
+    t.start( );
+
+    a_ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+
+    // Try to find a container using the same public key modulus. 
+    // In this case the index & the key spec are updated and must be used.
+    m_Files.containerGetMatching( a_ucContainerIndex, a_ucKeySpec, a_stCertificateName, a_pModulus );
+
+    // No existing container uses that public key modulus. 
+    if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_ucContainerIndex ) {
+
+        // Find an empty container
+        m_Files.containerSearch( a_ucContainerIndex );
+
+        // No empty container 
+        if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_ucContainerIndex ) {
+
+            throw MiniDriverException( SCARD_E_WRITE_TOO_MANY );
+        }
+    }
+
+    // Build the certificate name to associate it to the container 
+    a_stCertificateName = ( MiniDriverContainer::KEYSPEC_EXCHANGE == a_ucKeySpec ) ? std::string( szUSER_KEYEXCHANGE_CERT_PREFIX ) : std::string( szUSER_SIGNATURE_CERT_PREFIX );
+    Util::toStringHex( a_ucContainerIndex, a_stCertificateName );
+
+    // compress the certificate
+    unsigned long ccLen = a_pValue->GetLength( );
+
+    boost::shared_array< unsigned char > cc( new unsigned char[ ccLen + 4 ] );
+    cc[ 0 ] = 0x01;
+    cc[ 1 ] = 0x00;
+    cc[ 2 ] = (BYTE)( ccLen & 0xff ); // Put the low byte of the word
+    cc[ 3 ] = (BYTE)( ( ccLen & 0xff00 ) >> 8 ); // Put the high byte of the word
+
+    // Set compression level at 6, same as Minidriver
+    compress2( (unsigned char*)&cc[ 4 ], &ccLen, a_pValue->GetBuffer( ), ccLen, 6 );
+
+    Marshaller::u1Array compressedCert( ccLen + 4 );
+
+    compressedCert.SetBuffer( cc.get( ) );
+
+    Marshaller::u1Array ac( 3 );
+
+    // Administrator access conditions
+    ac.GetBuffer( )[ 0 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    // User access conditions
+    ac.GetBuffer( )[ 1 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    // Everyone access conditions
+    ac.GetBuffer( )[ 2 ] = MiniDriverFiles::CARD_PERMISSION_READ;
+
+    m_Files.createFile( std::string( szBASE_CSP_DIR ), a_stCertificateName, &ac );
+
+    m_Files.writeFile( std::string( szBASE_CSP_DIR ), a_stCertificateName, &compressedCert );
+
+    // Set the default certificate
+    m_Files.containerSetDefault( a_ucContainerIndex, a_bSmartCardLogon );
+
+    cacheSerialize( );
+
+    t.stop( "MiniDriver::createCertificate" );
+    Log::end( "MiniDriver::createCertificate" );
+}
+
+
+/*
+*/
+void MiniDriver::readCertificate( const std::string& a_stFile, boost::shared_ptr< Marshaller::u1Array >& a_pCertificateValue ) {
+
+    Log::begin( "MiniDriver::readCertificate" );
+    Timer t;
+    t.start( );
+
+    // Read certificate file
+    Marshaller::u1Array* pCompressedCertificate = m_Files.readFile( std::string( szBASE_CSP_DIR ), a_stFile );
+
+    // Decompress the certificate
+    unsigned long ulOrigLen = pCompressedCertificate->ReadU1At( 3 ) * 256 + pCompressedCertificate->ReadU1At( 2 );
+
+    a_pCertificateValue.reset( new Marshaller::u1Array( ulOrigLen ) );
+
+    uncompress( a_pCertificateValue->GetBuffer( ), &ulOrigLen, pCompressedCertificate->GetBuffer( ) + 4, pCompressedCertificate->GetLength( ) - 4 );
+
+    t.stop( "MiniDriver::readCertificate" );
+    Log::end( "MiniDriver::readCertificate" );
+}
+
+
+/*
+*/
+void MiniDriver::createCertificateRoot( std::string& a_stCertificateName, Marshaller::u1Array* a_pValue ) {
+
+    Log::begin( "MiniDriver::createCertificateRoot" );
+    Timer t;
+    t.start( );
+
+    // Try to find a free container index out of the range of the containers managed by the MniDriver
+    unsigned char ucContainerIndex = m_Files.containerGetFreeRoot( );
+
+    // Build the certificate name to associate it to the container 
+    a_stCertificateName = std::string( szUSER_KEYEXCHANGE_CERT_PREFIX );
+    Util::toStringHex( ucContainerIndex, a_stCertificateName );
+
+    // compress the certificate
+    unsigned long ccLen = a_pValue->GetLength( );
+
+    boost::shared_array< unsigned char > cc( new unsigned char[ ccLen + 4 ] );
+    cc[ 0 ] = 0x01;
+    cc[ 1 ] = 0x00;
+    cc[ 2 ] = (BYTE)( ccLen & 0xff ); // Put the low byte of the word
+    cc[ 3 ] = (BYTE)( ( ccLen & 0xff00 ) >> 8 ); // Put the high byte of the word
+
+    // Set compression level at 6, same as Minidriver
+    compress2( (unsigned char*)&cc[ 4 ], &ccLen, a_pValue->GetBuffer( ), ccLen, 6 );
+
+    Marshaller::u1Array compressedCert( ccLen + 4 );
+
+    compressedCert.SetBuffer( cc.get( ) );
+
+    Marshaller::u1Array ac( 3 );
+
+    // Administrator access conditions
+    ac.GetBuffer( )[ 0 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    // User access conditions
+    ac.GetBuffer( )[ 1 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    // Everyone access conditions
+    ac.GetBuffer( )[ 2 ] = MiniDriverFiles::CARD_PERMISSION_READ;
+
+    m_Files.createFile( std::string( szBASE_CSP_DIR ), a_stCertificateName, &ac );
+
+    m_Files.writeFile( std::string( szBASE_CSP_DIR ), a_stCertificateName, &compressedCert );
+
+    cacheSerialize( );
+    
+    //std::string stPathCertificateRoot( szROOT_STORE_FILE );
+    //std::auto_ptr< Marshaller::u1Array > pRoots;
+
+    //try {
+
+    //    pRoots.reset( m_Files.readFile( std::string( szBASE_CSP_DIR ), stPathCertificateRoot ) );
+    //
+    //} catch( ... ) {
+    //
+    //    // The msroot file does not exist. Create it.
+
+    //     Marshaller::u1Array ac( 3 );
+
+    //    // Administrator access conditions
+    //    ac.GetBuffer( )[ 0 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    //    // User access conditions
+    //    ac.GetBuffer( )[ 1 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+    //    // Everyone access conditions
+    //    ac.GetBuffer( )[ 2 ] = MiniDriverFiles::CARD_PERMISSION_READ;
+
+    //   m_Files.createFile( std::string( szBASE_CSP_DIR ), stPathCertificateRoot, &ac );
+    //}
+
+    //unsigned char ucIndex = 0;
+
+    //// Parse the msroot file to get the index of the new root certificate to insert
+    //if( *pRoots ) {
+    //
+    //    unsigned int uiSize = pRoots->GetLength( );
+
+    //    unsigned int uiOffset = 4;
+
+    //    while( uiOffset < uiSize ) {
+
+    //        unsigned char ucTagP7 = pRoots->ReadU1At( uiOffset );
+    //        unsigned char ucTagSize = pRoots->ReadU1At( uiOffset + 1 );
+    //        unsigned int uiSize = 0;
+    //        if( 0x80 == ucTagSize ) {
+    //        
+    //            uiSize = pRoots->ReadU1At( uiOffset + 2 );
+    //        
+    //        } else if( 0x82 == ucTagSize ) {
+    //        
+    //            uiSize = pRoots->ReadU1At( uiOffset + 2 ) * 256 + pRoots->ReadU1At( uiOffset + 3 );
+    //        }
+
+    //        ++ucIndex;
+    //    }
+    //}
+
+    //// Compute the root certificate index file
+    //    Util::toStringHex( ucIndex, a_stCertificateName );
+
+
+    //// Prepare the new msroot file
+
+
+    //// compress the certificate
+    //unsigned long ccLen = a_pValue->GetLength( );
+
+    //boost::shared_array< unsigned char > cc( new unsigned char[ ccLen + 4 ] );
+    //cc[ 0 ] = 0x01;
+    //cc[ 1 ] = 0x00;
+    //cc[ 2 ] = (BYTE)( ccLen & 0xff ); // Put the low byte of the word
+    //cc[ 3 ] = (BYTE)( ( ccLen & 0xff00 ) >> 8 ); // Put the high byte of the word
+
+    //// Set compression level at 6, same as Minidriver
+    //compress2( (unsigned char*)&cc[ 4 ], &ccLen, a_pValue->GetBuffer( ), ccLen, 6 );
+
+    //Marshaller::u1Array compressedCert( ccLen + 4 );
+
+    //compressedCert.SetBuffer( cc.get( ) );
+
+    //std::auto_ptr< Marshaller::u1Array > pNewRoots;
+    //if( *pRoots ) {
+    //
+    //    pNewRoots.reset( new Marshaller::u1Array( compressedCert.GetLength( ) + pRoots->GetLength( ) ) );
+
+    //    pNewRoots += compressedCert;
+
+    //} else {
+    //
+    //    // Populate the msroots file for the first time.
+    //    // The msroots file structure that you need to follow:
+    //    // [01 00]
+    //    // [2 bytes] - the lengths of the following data
+    //    // [data]
+    //    // where [data]  = [compressed PKCS7 empty signature of certificates]
+    //    // The compression algo is ZLIB. The msroots file store all the intermediate and root certificates.
+
+    //    pNewRoots.reset( new Marshaller::u1Array( compressedCert.GetLength( ) + 4 ) );
+    //    pNewRoots->SetU1At( 0, 0x01 );
+    //    pNewRoots->SetU1At( 1, 0x00 );
+    //    unsigned int iSize = compressedCert.GetLength( );
+    //    if ( iSize > 0xFF ) {
+    //    
+    //    } else {
+
+    //        pNewRoots->SetU1At( 2, 0x00 );
+    //        pNewRoots->SetU1At( 3, (unsigned char) iSize );
+    //    }
+
+    //    pNewRoots += compressedCert;
+    //}
+
+    //// Write the msroot file
+    //m_Files.writeFile( std::string( szBASE_CSP_DIR ), stPathCertificateRoot, *pNewRoots );
+
+    //cacheSerialize( );
+
+    t.stop( "MiniDriver::createCertificateRoot" );
+    Log::end( "MiniDriver::createCertificateRoot" );
+}
+
+
+/*
+*/
+void MiniDriver::unblockPin( Marshaller::u1Array* a_PinSo, Marshaller::u1Array* a_PinUser ) {
+
+    Log::begin( "MiniDriver::unblockPin" );
+    Timer t;
+    t.start( );
+
+    m_Authentication.unblockPin( a_PinSo, a_PinUser );
+
+    if( isAuthenticated( ) ) {
+    
+        // Update the MiniDriver Card Cache File
+        m_Files.notifyChange( MiniDriverCardCacheFile::PINS );
+    
+    } else {
+
+        verifyPin( a_PinUser );
+  
+        // Update the MiniDriver Card Cache File
+        if( !isReadOnly( ) ) {
+
+            m_Files.notifyChange( MiniDriverCardCacheFile::PINS );
+        }
+        logOut( );
+
+        if( administratorIsAuthenticated( ) ) {
+
+            administratorLogin( a_PinSo );
+        }
+    }
+    
+    cacheSerialize( );
+
+    t.stop( "MiniDriver::unblockPin" );
+    Log::end( "MiniDriver::unblockPin" );
+}
+
+
+/*
+*/
+void MiniDriver::administratorChangeKey( Marshaller::u1Array* a_OldKey, Marshaller::u1Array* a_NewKey ) {
+
+    Log::begin( "MiniDriver::administratorChangeKey" );
+    Timer t;
+    t.start( );
+
+    m_Authentication.administratorChangeKey( a_OldKey, a_NewKey );
+
+    //// Update the MiniDriver Card Cache File
+    //m_Files.notifyChange( MiniDriverCardCacheFile::PINS );
+
+    cacheSerialize( );
+
+    t.stop( "MiniDriver::administratorChangeKey" );
+    Log::end( "MiniDriver::administratorChangeKey" );
+}
+
+
+/*
+*/
+void MiniDriver::changePin( Marshaller::u1Array* a_pOldPIN, Marshaller::u1Array* a_pNewPIN ) {
+
+    Log::begin( "MiniDriver::changePin" );
+    Timer t;
+    t.start( );
+
+    m_Authentication.changePin( a_pOldPIN, a_pNewPIN );
+
+        if( isAuthenticated( ) ) {
+    
+        // Update the MiniDriver Card Cache File
+        if( !isReadOnly( ) ) {
+        
+            m_Files.notifyChange( MiniDriverCardCacheFile::PINS );
+        }
+    
+    } else {
+
+        verifyPin( a_pNewPIN );
+  
+        // Update the MiniDriver Card Cache File
+        m_Files.notifyChange( MiniDriverCardCacheFile::PINS );
+
+        logOut( );
+    }
+
+    cacheSerialize( );
+
+    t.stop( "MiniDriver::changePin" );
+    Log::end( "MiniDriver::changePin" );
+}
+
+
+/*
+*/
+void MiniDriver::toString( const unsigned char* buffer, std::size_t size, std::string &result ) {
+
+    if( !buffer || ( size <= 0 ) ) {
+
+        result = "";
+
+        return;
+    }
+
+    std::ostringstream oss;
+
+    oss.rdbuf( )->str( "" );
+
+    // Display hexadeciaml uppercase character
+    oss << std::hex << std::uppercase;
+
+    // No blank but zero instead
+    oss << std::setfill('0');
+
+    for( std::size_t i = 0; i < size; ++i ) {
+
+        oss << std::setw( 2 ) << static_cast< int >( buffer[ i ] );
+    }
+
+    result.assign( oss.str( ) );
+}
+
+
+/*
+*/
+void MiniDriver::setSmartCardReader( SmartCardReader* a_pSmartCardReader ) { 
+
+    if( a_pSmartCardReader ) {
+
+        m_Authentication.setSmartCardReader( a_pSmartCardReader ); 
+
+        const std::string& a_stReaderName = a_pSmartCardReader->getReaderName( ); 
+
+        m_CardModule.reset( new CardModuleService( a_stReaderName ) );
+
+//        bool bFalse = false;
+//        m_CardModule->DoTransact( bFalse );
+
+        m_Authentication.setCardModule( m_CardModule.get( ) ); 
+
+        m_Files.setCardModuleService( m_CardModule.get( ) ); 
+
+    }
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriver.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,228 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_MINIDRIVER_FACADE__
+#define __GEMALTO_MINIDRIVER_FACADE__
+
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/ptr_container/serialize_ptr_map.hpp>
+#include <boost/shared_ptr.hpp>
+#include "MiniDriverFiles.hpp"
+#include "MiniDriverContainerMapFile.hpp"
+#include "MiniDriverAuthentication.hpp"
+#include "MiniDriverException.hpp"
+
+
+class SmartCardReader;
+class CardModuleService;
+
+
+/*
+*/
+class MiniDriver {
+
+public:
+
+    const static unsigned int s_iMinLengthKeyRSA;
+
+    const static unsigned int s_iMaxLengthKeyRSA;
+
+    inline virtual ~MiniDriver( ) { }
+
+    inline void saveCache( void ) { try { cacheSerialize( ); } catch( ... ) { } }
+
+    void read( const bool& );
+
+
+    // Smart card management
+
+    // Initialize the object managing the communication with the smart card
+    void setSmartCardReader( SmartCardReader* a_pSmartCardReader  );
+
+    inline const CardModuleService* getCardModule( void ) { return m_CardModule.get( ); }
+
+    inline SCARDHANDLE getCardHandle( void ) { if( m_CardModule.get( ) ) return m_CardModule->getCardHandle( ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    Marshaller::u1Array* getSerialNumber( void );
+
+    inline void forceGarbageCollection( void ) { try { if( m_CardModule.get( ) ) { m_CardModule->forceGarbageCollector( ); } } catch( ... ) { } }
+
+    inline bool isV2Plus( void ) {  try { if( m_CardModule.get( ) ) { return m_CardModule->isV2Plus( ); } } catch( ... ) { } return false; }
+
+    inline void beginTransaction( void ) { if( m_CardModule.get( ) ) { m_CardModule->beginTransaction( ); } }
+
+    inline void endTransaction( void ) { if( m_CardModule.get( ) ) { m_CardModule->endTransaction( ); } }
+
+    inline bool isReadOnly( void ) { bool bRet = false; Marshaller::u1Array* a = getCardProperty( CARD_READ_ONLY, 0 ); if( a ) { bRet = ( 1 == a->ReadU1At( 0 ) ); } return bRet; } 
+
+
+    // Authentification management
+
+    inline unsigned char getPinMaxPinLength( void ) { return m_Authentication.getPinMaxPinLength( ); }
+
+    inline unsigned char getPinMinPinLength( void ) { return m_Authentication.getPinMinPinLength( ); }
+
+    inline bool isPinInitialized( void ) { return m_Authentication.isPinInitialized( ); } 
+
+    inline bool isSSO( void ) { return m_Authentication.isSSO( ); }
+
+    inline bool isNoPin( void ) { return m_Authentication.isNoPin( ); }
+
+    inline bool isAuthenticated( void ) { return m_Authentication.isAuthenticated( ); }
+
+    inline bool isExternalPin( void ) { return m_Authentication.isExternalPin( ); }
+
+    inline bool isModePinOnly( void ) { return m_Authentication.isModePinOnly( ); }
+
+    inline bool isModeNotPinOnly( void ) { return m_Authentication.isModeNotPinOnly( ); }
+
+    inline bool isModePinOrBiometry( void ) { return m_Authentication.isModePinOrBiometry( ); }
+
+    void changePin( Marshaller::u1Array* a_pOldPIN, Marshaller::u1Array* a_pNewPIN );
+
+    void unblockPin( Marshaller::u1Array* a_PinSo, Marshaller::u1Array* a_PinUser );
+
+    inline void verifyPin( Marshaller::u1Array* a_Pin ) { m_Authentication.login( a_Pin ); }
+
+    inline void logOut( void ) { m_Authentication.logOut( ); }
+
+    inline int getTriesRemaining( void ) { return m_Authentication.getTriesRemaining( ); }
+
+    inline void administratorLogin( Marshaller::u1Array* a_pAdministratorKey ) { m_Authentication.administratorLogin( a_pAdministratorKey ); }
+
+    inline void administratorLogout( void ) { m_Authentication.administratorLogout( ); }
+
+    void administratorChangeKey( Marshaller::u1Array* a_OldKey, Marshaller::u1Array* a_NewKey );
+
+    inline unsigned char administratorGetTriesRemaining( void ) { return m_Authentication.administratorGetTriesRemaining( ); }
+
+    inline bool administratorIsAuthenticated( void ) { return m_Authentication.administratorIsAuthenticated( ); }
+
+
+    // Files management
+
+    inline void hasChanged( MiniDriverCardCacheFile::ChangeType& a_Pins, MiniDriverCardCacheFile::ChangeType& a_Containers, MiniDriverCardCacheFile::ChangeType& a_Files ) { m_Files.hasChanged( a_Pins, a_Containers, a_Files ); }
+
+    inline MiniDriverFiles::FILES_NAME& enumFiles( const std::string& a_DirectoryPath ) { return m_Files.enumFiles( a_DirectoryPath ); }
+
+    inline Marshaller::u1Array* readFile( const std::string& a_stDirectory, const std::string& a_stFile ) { return m_Files.readFile( a_stDirectory, a_stFile ); }
+
+    inline void writeFile( const std::string& a_stDirectory, const std::string& a_stFile, Marshaller::u1Array* a_FileData, const bool& a_bAddToCache = true ) { { Log::begin( "MiniDriver::writeFile" ); Log::log( "Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) ); m_Files.writeFile( a_stDirectory, a_stFile, a_FileData, a_bAddToCache ); cacheSerialize( ); Log::end( "MiniDriver::writeFile" ); } }
+
+    void createFile( const std::string&, const std::string&, const bool& );
+
+    inline void deleteFile( const std::string& a_stDirectory, const std::string& a_stFile ) { { Log::begin( "MiniDriver::deleteFile" ); Log::log( "Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) ); m_Files.deleteFile( a_stDirectory, a_stFile ); cacheSerialize( ); Log::end( "MiniDriver::deleteFile" ); } }
+
+    inline void createDirectory( const std::string& a_stDirectoryParent, const std::string& a_stDirectory ) { { Log::begin( "MiniDriver::createDirectory" ); Log::log( "Directory <%s> - Parent <%s>", a_stDirectory.c_str( ), a_stDirectoryParent.c_str( ) ); m_Files.createDirectory( a_stDirectoryParent, a_stDirectory ); cacheSerialize( ); Log::end( "MiniDriver::createDirectory" ); } }
+
+    void createCertificate( unsigned char&, unsigned char&, std::string&, Marshaller::u1Array*, Marshaller::u1Array*, const bool& );
+
+    void createCertificateRoot( std::string& a_stCertificateName, Marshaller::u1Array* a_pValue );
+
+    void readCertificate( const std::string&, boost::shared_ptr< Marshaller::u1Array >& );
+
+    inline void deleteFileStructure( void ) { m_Files.deleteFileStructure( ); }
+
+    inline void certificateDelete( unsigned char& a_ucContainerIndex ) { m_Files.certificateDelete( a_ucContainerIndex ); }
+
+    inline void cacheDisable( const std::string& a_stFileName ) { m_Files.cacheDisable( a_stFileName ); }
+
+    inline void renameFile( const std::string& a_stOldFileDirectory, const std::string& a_stOldFileName, const std::string& a_stNewFileDirectory, const std::string& a_stNewFileName ) { m_Files.renameFile( a_stOldFileDirectory, a_stOldFileName, a_stNewFileDirectory, a_stNewFileName ); } 
+
+
+    // Containers management
+
+    inline const MiniDriverContainer& containerGet( const unsigned char& a_ucContainerIndex ) { return m_Files.containerGet( a_ucContainerIndex ); }
+
+    inline void containerDelete( const unsigned char& a_ucContainerIndex ) { m_Files.containerDelete( a_ucContainerIndex ); }
+
+    inline void containerCreate( unsigned char& a_ucContainerIndex, const bool& a_bKeyImport, unsigned char& a_ucKeySpec, Marshaller::u1Array* a_pPublicKeyModulus, const int& a_KeySize, Marshaller::u1Array* a_pKeyValue ) { m_Files.containerCreate( a_ucContainerIndex, a_bKeyImport, a_ucKeySpec, a_pPublicKeyModulus, a_KeySize, a_pKeyValue ); }
+
+    inline unsigned char containerCount( void ) { return m_Files.containerCount( ); }
+
+    inline bool containerGetMatching( unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec, std::string& a_stFileName, const Marshaller::u1Array* a_pPublicKeyModulus ) { return m_Files.containerGetMatching( a_ucContainerIndex, a_ucKeySpec, a_stFileName, a_pPublicKeyModulus ); }
+
+    inline bool containerIsImportedExchangeKey( const unsigned char& a_ucContainerIndex ) { return m_Files.containerIsImportedExchangeKey( a_ucContainerIndex ); }
+
+    inline bool containerIsImportedSignatureKey( const unsigned char& a_ucContainerIndex ) { return m_Files.containerIsImportedSignatureKey( a_ucContainerIndex ); }
+
+    inline unsigned char containerGetFree( void ) { return m_Files.containerGetFree( ); }
+
+    
+    // Cryptography management
+
+    inline boost::shared_ptr< Marshaller::u1Array > privateKeyDecrypt( const unsigned char& a_ucContainerIndex, const unsigned char& a_ucKeySpec, Marshaller::u1Array* a_pDataToDecrypt ) { if( m_CardModule.get( ) ) { /*m_CardModule->manageGarbageCollector( ); */m_pDataDecrypted.reset( m_CardModule->privateKeyDecrypt( a_ucContainerIndex, a_ucKeySpec, a_pDataToDecrypt ) ); return m_pDataDecrypted; } else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+
+    // Property management
+    inline Marshaller::u1Array* getCardProperty( const unsigned char& a_ucProperty, const unsigned char& a_ucFlags ) { if( m_CardModule.get( ) ) { return m_CardModule->getCardProperty( a_ucProperty, a_ucFlags ); } else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    inline void setCardProperty( const unsigned char& a_ucProperty, Marshaller::u1Array* a_Data, const unsigned char& a_ucFlags ) { if( m_CardModule.get( ) ) { m_CardModule->setCardProperty( a_ucProperty, a_Data, a_ucFlags ); } else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+
+private:    
+
+    void toString( const unsigned char* buffer, std::size_t size, std::string &result );
+
+    boost::shared_ptr< Marshaller::u1Array > m_pDataDecrypted;
+
+    boost::shared_ptr< Marshaller::u1Array > m_u1aSerialNumber;
+
+    boost::shared_ptr< CardModuleService > m_CardModule;
+
+    MiniDriverFiles m_Files;
+
+    MiniDriverAuthentication m_Authentication;
+
+    // Name of the file on the computer disk containing the image of the cache
+    std::string m_stFileName;
+
+    // Enable/disable the on disk serialization/deserialization
+    bool m_bEnableCache;
+
+    void cacheDeserialize( void );
+
+    void cacheSerialize( void );
+
+    // Disk serialization and deserialization
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+
+        //Log::begin( "MiniDriver::serialize" );
+
+        // Append the files information
+        ar & m_Files;
+
+        // Append the authentication information
+        ar & m_Authentication;
+
+        //Log::end( "MiniDriver::serialize" );
+    }
+
+};
+
+
+BOOST_CLASS_VERSION( MiniDriver, 1 )
+
+
+#endif // __GEMALTO_MINIDRIVER__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,597 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto->com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "MiniDriverAuthentication.hpp"
+#include "SmartCardReader.hpp"
+#include "tdes.h"
+#include "Log.hpp"
+#ifdef WIN32
+#include "BioMan.h"
+#else
+#define SCARD_CTL_CODE(code) (0x42000000 + (code))
+#endif
+#include "PCSCMissing.h"
+
+
+bool MiniDriverAuthentication::isSSO( void ) { 
+    
+    return ( m_PinPolicy.getAllowSSO( ) != 0 ); 
+
+}
+
+ 
+/*
+*/
+MiniDriverAuthentication::MiniDriverAuthentication( ) {
+
+    //Log::begin( "MiniDriverAuthentication::MiniDriverAuthentication" );
+
+    // Set the role to use for authentication (default is user)
+    setRole( PIN_USER );
+
+    // Set the default role 
+    m_bIsRoleLogged = false;
+
+    m_bIsAdministratorLogged = false;
+
+    m_wActiveMode = UVM_PIN_ONLY;
+
+    m_ucTypePIN = PIN_TYPE_REGULAR;
+
+    //Log::end( "MiniDriverAuthentication::MiniDriverAuthentication" );
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::read( void ) {
+
+    Log::begin( "MiniDriverAuthentication::read" );
+    Timer t;
+    t.start( );
+
+    if( m_PinPolicy.empty( ) ) {
+        
+        try {
+                // Read the PIN policy
+                m_PinPolicy.read( );
+
+        } catch( ... ) {
+    
+        }
+    }
+
+    // Read the PIN info ex property
+    // Get the active mode (PIN only, Biometry only, PIN and Biometry, PIN or Biometry)
+    // and get the PIN type (external for biometry or secured reader, regular or no pin)
+    if( m_PinInfoEx.IsNull( ) ) {
+
+        try {
+
+            m_PinInfoEx.reset( m_CardModule->getCardProperty( CARD_PROPERTY_PIN_INFO_EX, m_ucRole ) );
+
+            if( !m_PinInfoEx.IsNull( ) ) {
+
+                m_wActiveMode = (unsigned short)( m_PinInfoEx.GetBuffer( )[ 12 ] + ( ( m_PinInfoEx.GetBuffer( )[ 13 ] ) << 8 ) );
+                //Log::log( "Token::getCardMode - Active mode <%ld>", wActiveMode );
+
+                m_ucTypePIN = (unsigned char)m_PinInfoEx.GetBuffer( )[ 0 ];
+
+                //DWORD dwFlagsEx = (DWORD)(
+                //   ba->GetBuffer( )[ 12 ] +
+                //   ( ( ba->GetBuffer( )[ 13 ] ) << 8 ) +
+                //   ( ( ba->GetBuffer( )[ 14 ] ) << 16 ) +
+                //   ( ( ba->GetBuffer( )[ 15 ] ) << 24 )
+                //   );
+                //Log::log( "Token::getCardMode - dwFlagsEx <%#08x>", dwFlagsEx );
+            }
+
+        } catch( ... ) {
+
+            Log::error( "MiniDriverAuthentication::MiniDriverAuthentication", "PIN_INFO_EX not supported - Default values used" );
+
+            m_PinInfoEx.reset( );
+
+            m_wActiveMode = UVM_PIN_ONLY;
+
+            m_ucTypePIN = PIN_TYPE_REGULAR;
+        }
+    }
+
+    t.stop( "MiniDriverAuthentication::read" );
+    Log::end( "MiniDriverAuthentication::read" );
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::login( Marshaller::u1Array* a_pPin/*, const unsigned char& a_ucRole*/ ) {
+
+    Log::begin( "MiniDriverAuthentication::login" );
+    Timer t;
+    t.start( );
+
+    switch( howToAuthenticate( (unsigned char)a_pPin->GetLength( ) ) ) {
+
+    case g_ucAuthenticateRegular:
+        Log::log( "MiniDriverAuthentication::login - Normal login" );
+        verifyPin( a_pPin );
+        break;
+
+    case g_ucAuthenticateSecure:
+        Log::log( "MiniDriverAuthentication::login - PinPad" );
+        m_SmartCardReader->verifyPinSecured( m_ucRole );
+        break;
+
+    case g_AuthenticateBiometry:
+#ifdef WIN32
+        Log::log( "MiniDriverAuthentication::login - BIO" );
+        verifyPinWithBio( );
+#else
+        Log::log( "MiniDriverAuthentication::AuthenticateUser - BIO not supported !!" );
+        throw MiniDriverException( SCARD_E_UNSUPPORTED_FEATURE );
+#endif
+        break;
+
+    default:
+        Log::log( "MiniDriverAuthentication::login - Unknown !!" );
+        throw MiniDriverException( SCARD_F_INTERNAL_ERROR );
+        break;
+    }
+
+    m_bIsRoleLogged = true;
+
+    t.stop( "MiniDriverAuthentication::login" );
+    Log::end( "MiniDriverAuthentication::login" );
+}
+
+
+/*
+*/
+unsigned char MiniDriverAuthentication::howToAuthenticate( unsigned char bPinLen ) {
+
+    Log::begin( "MiniDriverAuthentication::howToAuthenticate" );
+    Timer t;
+    t.start( );
+
+    unsigned char bRet = g_ucAuthenticateRegular;
+
+    Log::log( "MiniDriverAuthentication::AuthenticateUser - PIN type <%ld> (0 = regular ; 1 = external)", isExternalPin( ) );
+    Log::log( "MiniDriverAuthentication::AuthenticateUser - Card mode <%ld> (1 = pin only ; 2 = fp only ; 3 = fp or pin ; 4 = fp and pin)", getPinMode( ) );
+    Log::log( "MiniDriverAuthentication::AuthenticateUser - PIN len <%ld>", bPinLen );
+
+    if( isExternalPin( ) )
+    {
+        if( isModePinOnly( ) )
+        {
+            if( m_SmartCardReader->isVerifyPinSecured( ) ) {
+
+                if( 0 == bPinLen ) {
+
+                    Log::log( "MiniDriverAuthentication::AuthenticateUser - External PIN && UVM1 && PINpad support && null len -> PIN pad" );
+                    bRet = g_ucAuthenticateSecure;
+
+                } else {
+
+                    Log::log( "MiniDriverAuthentication::AuthenticateUser - External PIN && UVM1 && PINpad support && valid len -> PIN normal" );
+                    bRet = g_ucAuthenticateRegular;
+
+                }
+            } else {
+
+                Log::log( "MiniDriverAuthentication::AuthenticateUser - External PIN && UVM1 && NO PINpad support -> ERROR !!!" );
+                bRet = g_ucAuthenticateError;
+            }
+        } else {
+
+            Log::log( "MiniDriverAuthentication::AuthenticateUser - External PIN && (UVM2 || UVM3 || UVM4) -> Bio" );
+            bRet = g_AuthenticateBiometry;
+        }
+    } else {
+
+        if( bPinLen && ( isModePinOnly( ) || isModePinOrBiometry( ) ) ) {
+
+            Log::log( "MiniDriverAuthentication::AuthenticateUser - Regular PIN && (UVM1 || UVM3)  && valid len -> PIN normal" );
+            bRet = g_ucAuthenticateRegular;
+
+        } else {
+
+            Log::log( "MiniDriverAuthentication::AuthenticateUser - Regular PIN && (UVM2 || UVM4)  && NO valid len -> ERROR !!!" );
+            bRet = g_ucAuthenticateError;
+        }
+    }
+
+    t.stop( "MiniDriverAuthentication::howToAuthenticate" );
+    Log::end( "MiniDriverAuthentication::howToAuthenticate" );
+
+    return bRet;
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::verifyPinWithBio( void ) {
+
+    Log::begin( "MiniDriverAuthentication::verifyPinWithBio" );
+
+    long rv = SCARD_F_INTERNAL_ERROR;
+
+#ifdef WIN32
+    // Get the current OS version
+    OSVERSIONINFO osvi;
+    memset( &osvi, 0, sizeof( OSVERSIONINFO ) );
+    osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
+    GetVersionEx(&osvi);
+    // Check if the Os is W7 or W2K8R2
+    if( ( 6 == osvi.dwMajorVersion ) && ( osvi.dwMinorVersion >= 1 ) )
+    {
+        Log::log( "MiniDriverAuthentication::verifyPinWithBio - Os is W7 or W2K8R2" );
+
+        //		CardEndTransaction( );
+
+        // The OS is W7 or W2K8R2
+        HMODULE hDll = NULL;
+        LRESULT lRes = GSC_OK;
+        LRESULT (WINAPI *ptr_SetUITitles) (WCHAR*, WCHAR*);
+        LRESULT (WINAPI *ptr_AuthenticateUserCard) ();
+
+        // Load DLL
+        hDll = LoadLibraryA("GemSelCert.dll");
+        Log::log( "MiniDriverAuthentication::verifyPinWithBio - load lib" );
+
+        if( 0 != hDll )
+        {
+            // Set UI Titles
+            ptr_SetUITitles = (LRESULT (WINAPI *) (WCHAR*, WCHAR*))GetProcAddress(hDll,"SetUITitles");
+            if( NULL != ptr_SetUITitles )
+            {
+                ptr_SetUITitles(L"Smartcard Security", L"User MiniDriverAuthentication");
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - ptr_SetUITitles" );
+
+                // Authenticate Card User
+                ptr_AuthenticateUserCard = (LRESULT (WINAPI *)())GetProcAddress(hDll,"AuthenticateUserCard");
+                if( NULL != ptr_AuthenticateUserCard )
+                {
+                    lRes = ptr_AuthenticateUserCard();
+                    Log::log( "MiniDriverAuthentication::verifyPinWithBio - ptr_AuthenticateUserCard" );
+
+                    switch(lRes)
+                    {
+                    case GSC_OK:
+                        rv = SCARD_S_SUCCESS;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_S_SUCCESS" );
+                        break;
+
+                    case GSC_CANCEL:
+                        rv = SCARD_E_CANCELLED;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_E_CANCELLED" );
+                        break;
+
+                    case GSC_NO_CERT:
+                        rv = SCARD_E_CERTIFICATE_UNAVAILABLE;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_E_CERTIFICATE_UNAVAILABLE" );
+                        break;
+
+                    case GSC_NO_CARD:
+                        rv = SCARD_E_NO_SMARTCARD;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_E_NO_SMARTCARD" );
+                        break;
+
+                    case GSC_WRONG_PIN:
+                        rv = SCARD_W_WRONG_CHV;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_W_WRONG_CHV" );
+                        break;
+
+                    case GSC_READ_CARD:
+                        rv = SCARD_E_NO_ACCESS;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_E_NO_ACCESS" );
+                        break;
+
+                    case GSC_WRITE_CARD:
+                        rv = SCARD_E_NO_ACCESS;
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_E_NO_ACCESS" );
+                        break;
+
+                    default:
+                        Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_F_INTERNAL_ERROR" );
+                        rv = SCARD_F_INTERNAL_ERROR;
+                        break;
+                    }
+                }
+            }
+
+            // Release DLL
+            FreeLibrary(hDll);
+            Log::log( "MiniDriverAuthentication::verifyPinWithBio - FreeLibrary" );
+
+            //		CardBeginTransaction( );
+        }
+        // The OS is Vista or XP
+        else
+        {
+            Log::log( "MiniDriverAuthentication::verifyPinWithBio - Os is Vista or XP" );
+
+            CBioMan* pBioMan = NULL;
+            DWORD dwRes = BIO_ERR_NOT_SUPPORTED;
+
+            // Init BioMan helper
+            pBioMan = new CBioMan( m_CardModule );
+
+            // Biometrics Verification
+            dwRes = pBioMan->VerifyBio( );
+
+            delete pBioMan;
+
+            // Error ?
+            switch( dwRes )
+            {
+            case BIO_ERR_SUCCESS:
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - CKR_OK" );
+                rv = SCARD_S_SUCCESS;
+                break;
+
+            case BIO_ERR_NO_CARD:
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - CKR_TOKEN_NOT_PRESENT" );
+                rv = SCARD_E_NO_SMARTCARD;
+                break;
+
+            case BIO_ERR_NOT_SUPPORTED:
+            case BIO_ERR_NO_FINGER:
+            case BIO_ERR_BIO_NOT_CHECKED:
+            case BIO_ERR_PIN_NOT_CHECKED:
+            case BIO_ERR_BIO_LAST:
+            case BIO_ERR_PIN_LAST:
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_W_WRONG_CHV" );
+                rv = SCARD_W_WRONG_CHV;
+                break;
+
+            case BIO_ERR_BLOCKED:
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_W_CHV_BLOCKED" );
+                rv = SCARD_W_CHV_BLOCKED;
+                break;
+
+            case BIO_ERR_ABORT:
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_E_CANCELLED" );
+                rv = SCARD_E_CANCELLED;
+                break;
+
+            default:
+                Log::log( "MiniDriverAuthentication::verifyPinWithBio - SCARD_F_INTERNAL_ERROR" );
+                rv = SCARD_F_INTERNAL_ERROR;
+                break;
+            }
+        }
+    }
+#endif
+
+    Log::log( "MiniDriverAuthentication::verifyPinWithBio - <END>" );
+
+    if( SCARD_S_SUCCESS != rv ) {
+
+        throw MiniDriverException( rv );
+    } 
+}
+
+
+/*
+*/
+bool MiniDriverAuthentication::isLoggedIn( void ) {
+
+    if( m_bIsRoleLogged ) {
+
+        return true;
+    }
+
+    if(  isSSO( ) && isAuthenticated( ) ) {
+
+        return true;
+    }
+
+    if( isNoPin( ) ) {
+
+        return true;
+    }
+
+    return false;
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::synchronizePIN( void ) {
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::unblockPin( Marshaller::u1Array* a_PinSo, Marshaller::u1Array* a_PinUser ) {
+
+    Log::begin( "MiniDriverAuthentication::unblockPin" );
+    std::string stPinSo;
+    Log::toString( a_PinSo->GetBuffer( ), a_PinSo->GetLength( ), stPinSo );
+    std::string stPinUser;
+    Log::toString( a_PinUser->GetBuffer( ), a_PinUser->GetLength( ), stPinUser );
+    Log::log( "User PIN <%s> - Administrator Key <%s>", stPinUser.c_str( ), stPinSo.c_str( ) );
+
+    Timer t;
+    t.start( );
+
+    // Get a challenge from the smart card
+    boost::shared_ptr< Marshaller::u1Array > pChallenge( m_CardModule->getChallenge( ) );
+
+    // compute a 3DES cryptogramm from the challenge using the administrator key
+    computeCryptogram( pChallenge.get( ), a_PinSo );
+
+    // Unblock the user PIN. The retry counter value is not modified (-1)
+    m_CardModule->changeReferenceData( MODE_UNBLOCK_PIN, PIN_USER, &m_Cryptogram, a_PinUser, -1 );
+
+    t.stop( "MiniDriverAuthentication::unblockPin" );
+    Log::end( "MiniDriverAuthentication::unblockPin" );
+}
+
+
+/// ADMINISTRATOR
+
+
+/*
+*/
+void MiniDriverAuthentication::administratorChangeKey( Marshaller::u1Array* a_OldKey, Marshaller::u1Array* a_NewKey ) {
+
+    Log::begin( "MiniDriverAuthentication::administratorChangeKey" );
+    Timer t;
+    t.start( );
+
+    // Get the challenge from the smart card
+    boost::shared_ptr< Marshaller::u1Array > pChallenge( m_CardModule->getChallenge( ) );
+
+    // Compute the 3DES cryptogram from the challeng using the current adminsitrator key
+    computeCryptogram( pChallenge.get( ), a_OldKey );
+
+    // The new administrator key has to be 24 bytes. if not we just pad rest of bytes as zeros
+    Marshaller::u1Array a( 24 );
+
+    memset( a.GetBuffer( ), 0, 24 );
+
+    memcpy( a.GetBuffer( ), a_NewKey->GetBuffer( ), a_NewKey->GetLength( ) );
+
+    // Change the administrator key
+    m_CardModule->changeReferenceData( MODE_CHANGE_PIN, PIN_ADMIN, &m_Cryptogram, &a, -1 );
+
+    t.stop( "MiniDriverAuthentication::administratorChangeKey" );
+    Log::end( "MiniDriverAuthentication::administratorChangeKey" );
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::administratorLogin( Marshaller::u1Array* a_pAdministratorKey ) {
+
+    Log::begin( "MiniDriverAuthentication::authenticateAdministrator" );
+    Timer t;
+    t.start( );
+
+    // Get a challenge
+    boost::shared_ptr< Marshaller::u1Array > challenge( m_CardModule->getChallenge( ) );
+
+    // Compute a cryptopgram from the challenge using the administror key
+    computeCryptogram( challenge.get( ), a_pAdministratorKey );
+
+    try {
+
+        // Perform the administrator authentication
+        m_CardModule->externalAuthenticate( &m_Cryptogram );
+
+    } catch( MiniDriverException& ) {
+
+        Log::error( "MiniDriverAuthentication::administratorLogin", "externalAuthenticate failed" );
+
+        // first check if pin is locked or not blocked
+        if( !administratorGetTriesRemaining( ) ) {
+
+            throw MiniDriverException( SCARD_W_CHV_BLOCKED );
+        }
+
+        throw;
+    }
+
+    t.stop( "MiniDriverAuthentication::authenticateAdministrator" );
+    Log::end( "MiniDriverAuthentication::authenticateAdministrator" );
+}
+
+
+/* Only accept correct length, otherwise return a zero valued response that is sure to fail authentication.
+*/
+void MiniDriverAuthentication::computeCryptogram( Marshaller::u1Array* a_challenge, Marshaller::u1Array* a_pin ) {
+
+    Log::begin( "MiniDriverAuthentication::computeCryptogram" );
+    Timer t;
+    t.start( );
+
+    m_Cryptogram.reset( );
+
+    if( 24 == a_pin->GetLength( ) ) {
+
+        // compute the response
+        CK_BYTE iv[ 8 ];
+        memset( iv, 0, sizeof( iv ) );
+
+        CTripleDES tdes;
+
+        tdes.SetEncryptMode( ENCRYPT );
+
+        tdes.SetIV( iv );
+
+        tdes.SetCipherMode( CIPHER_MODE_ECB );
+
+        tdes.SetPaddingMode( PADDING_MODE_NONE );
+
+        tdes.SetKey( a_pin->GetBuffer( ), 24 );
+
+        m_Cryptogram.reset( new Marshaller::u1Array( 8 ) );
+
+        tdes.TransformFinalBlock( a_challenge->GetBuffer( ), 0, 8, m_Cryptogram.GetBuffer( ), 0 );
+
+    }
+
+    t.stop( "MiniDriverAuthentication::computeCryptogram" );
+    Log::end( "MiniDriverAuthentication::computeCryptogram" );
+}
+
+
+/*
+*/
+void MiniDriverAuthentication::print( void ) {
+   
+    Log::begin( "MiniDriverAuthentication::print" );
+
+    Log::log( "m_wActiveMode <%ld>", m_wActiveMode );
+
+    Log::log( "m_ucTypePIN <%ld>", m_ucTypePIN );
+
+    m_PinPolicy.print( );
+
+    Log::logCK_UTF8CHAR_PTR( "m_PinInfoEx", m_PinInfoEx.GetBuffer( ), m_PinInfoEx.GetLength( ) );
+
+    Log::log( "m_ucRole <%ld>", m_ucRole );
+
+    Log::end( "MiniDriverAuthentication::print" );
+}
+
+
+bool MiniDriverAuthentication::administratorIsAuthenticated( void ) { 
+    
+    bool b = false; 
+    
+    if( m_CardModule ) {  
+        
+        b = m_CardModule->isAuthenticated( PIN_ADMIN ); 
+        
+        Log::log( "MiniDriverAuthentication - administratorIsAuthenticated <%d>", b ); 
+    
+    } else {
+        
+        throw MiniDriverException( SCARD_E_NO_SMARTCARD ); 
+    }
+
+    return b; 
+
+}
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverAuthentication.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,194 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_MINIDRIVER_AUTHENTICATION__
+#define __GEMALTO_MINIDRIVER_AUTHENTICATION__
+
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include "MiniDriverPinPolicy.hpp"
+#include "Array.hpp"
+#include "MiniDriverException.hpp"
+
+
+class SmartCardReader;
+
+
+const unsigned char CARD_PROPERTY_PIN_INFO_EX = 0x87;
+
+
+/*
+*/
+class MiniDriverAuthentication {
+
+public:
+
+    typedef enum { PIN_NONE = 0x00, PIN_USER = 0x01, PIN_ADMIN = 0x02, PIN_3 = 0x04, PIN_4 = 0x08, PIN_5 = 0x10, PIN_6 = 0x20, PIN_7 = 0x40 } ROLES;
+
+    typedef enum { MODE_CHANGE_PIN = 0x00, MODE_UNBLOCK_PIN = 0x01 } CHANGE_REFERENCE_DATA_MODES;
+
+    typedef enum { UVM_PIN_ONLY = 1, UVM_FP_ONLY, UVM_PIN_OR_FP, UVM_PIN_AND_FP } UVM_MODES;
+
+    typedef enum { PIN_TYPE_REGULAR = 0, PIN_TYPE_EXTERNAL, PIN_TYPE_CHALLENGE_RESPONSE, PIN_TYPE_NO_PIN } PIN_TYPES;
+
+    static const unsigned char g_ucAuthenticateError = 0;
+    static const unsigned char g_ucAuthenticateRegular = 1;
+    static const unsigned char g_ucAuthenticateSecure = 2;
+    static const unsigned char g_AuthenticateBiometry = 3;
+
+    MiniDriverAuthentication( );
+
+    inline void setCardModule( CardModuleService* a_pCardModule ) { m_CardModule = a_pCardModule; m_PinPolicy.setCardModuleService( m_CardModule ); }
+
+    inline void setSmartCardReader( SmartCardReader* a_pSmartCardReader ) { m_SmartCardReader = a_pSmartCardReader; }
+
+    inline void setRole( const unsigned char& a_ucRole = PIN_USER ) { m_ucRole = a_ucRole; m_PinPolicy.setRole( m_ucRole ); }
+
+    void read( void );
+
+
+    // User role management
+
+    bool isSSO( void );
+
+    inline bool isNoPin( void ) { return ( m_ucTypePIN == PIN_TYPE_NO_PIN ); }
+
+    inline bool isAuthenticated( void ) { if( m_CardModule ) return m_CardModule->isAuthenticated( m_ucRole ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    inline bool isPinInitialized( void ) { bool bRet = true; Marshaller::u1Array* a = 0; if( m_CardModule ) { try { a = m_CardModule->getCardProperty( CARD_CHANGE_PIN_FIRST, m_ucRole ); } catch( ... ) { a = 0; } if( a ) { bRet = ( 0 == a->ReadU1At( 0 ) ); } } return bRet; }
+
+    inline bool isExternalPin( void ) { return ( m_ucTypePIN == PIN_TYPE_EXTERNAL ); }
+
+    inline bool isModePinOnly( void ) { return ( m_wActiveMode == UVM_PIN_ONLY ); }
+
+    inline bool isModeNotPinOnly( void ) { return ( m_wActiveMode != UVM_PIN_ONLY ); }
+
+    inline bool isModePinOrBiometry( void ) { return ( m_wActiveMode == UVM_PIN_OR_FP ); }
+
+    void login( Marshaller::u1Array* );
+
+    inline void verifyPin( Marshaller::u1Array* a_Pin ) { if( m_CardModule ) m_CardModule->verifyPin( m_ucRole, a_Pin ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    inline void changePin( Marshaller::u1Array* a_pOldPIN, Marshaller::u1Array* a_pNewPIN ) { if( m_CardModule ) m_CardModule->changeReferenceData( MODE_CHANGE_PIN, m_ucRole, a_pOldPIN, a_pNewPIN, -1 ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    inline void logOut( void ) { if( m_CardModule ) m_CardModule->logOut( m_ucRole ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    void unblockPin( Marshaller::u1Array*, Marshaller::u1Array* );
+
+    bool isLoggedIn( void );
+
+    void synchronizePIN( void );
+
+    inline unsigned char getPinMinPinLength( void ) { return m_PinPolicy.getPinMinLength( ); }
+
+    inline unsigned char getPinMaxPinLength( void ) { return m_PinPolicy.getPinMaxLength( ); }
+
+    inline unsigned char getPinMaxAttempts( void ) { return m_PinPolicy.getMaxAttemps( ); }
+
+    inline unsigned char getPinType( void ) { return m_ucTypePIN; }
+
+    // Get the card mode (1=PIN, 2=FingerPrint, 3=PIN or FP, 4=PIN and FP). The default mode is PIN
+    inline unsigned short getPinMode( void ) { return m_wActiveMode; }
+
+    inline unsigned char getTriesRemaining( void ) { if( m_CardModule ) return (unsigned char)m_CardModule->getTriesRemaining( m_ucRole ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+
+    // Administrator key management
+
+    void administratorLogin( Marshaller::u1Array* );
+
+    inline void administratorLogout( void ) {if( m_CardModule ) m_CardModule->logOut( PIN_ADMIN ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    void administratorChangeKey( Marshaller::u1Array*, Marshaller::u1Array* );
+
+    inline unsigned char administratorGetTriesRemaining( void ) { if( m_CardModule ) return (unsigned char)m_CardModule->getTriesRemaining( PIN_ADMIN ); else throw MiniDriverException( SCARD_E_NO_SMARTCARD ); }
+
+    bool administratorIsAuthenticated( void );
+
+    void print( void );
+    
+private:
+
+    void verifyPinWithBio( void );
+
+    void computeCryptogram( Marshaller::u1Array*, Marshaller::u1Array* );
+
+    unsigned char howToAuthenticate( unsigned char bPinLen );
+
+    void authenticateUser( Marshaller::u1Array* );
+
+    void authenticateAdmin( Marshaller::u1Array* );
+
+    unsigned short m_wActiveMode;
+
+    unsigned char m_ucTypePIN;
+
+    MiniDriverPinPolicy m_PinPolicy;
+
+    CardModuleService* m_CardModule;
+
+    SmartCardReader* m_SmartCardReader;
+
+    Marshaller::u1Array m_PinInfoEx;
+
+    Marshaller::u1Array m_Cryptogram;
+
+    bool m_bIsRoleLogged;
+
+    bool m_bIsAdministratorLogged;
+
+    unsigned char m_ucRole;
+
+    // Disk serialization and deserialization
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+       
+        //Log::begin( "MiniDriverAuthentication::serialize" );
+
+        ar & m_ucRole;
+
+        ar & m_PinInfoEx;
+
+        ar & m_PinPolicy;
+
+        ar & m_wActiveMode;
+
+        ar & m_ucTypePIN;
+
+        //Log::log( "Role <%ld>", m_ucRole );
+        //Log::logCK_UTF8CHAR_PTR( "PIN info Ex %s", m_PinInfoEx.GetBuffer( ), m_PinInfoEx.GetLength( ) );
+        //m_PinPolicy.print( );
+        //Log::log( "Active mode <%ld>", m_wActiveMode );
+        //Log::log( "PIN type <%ld>", m_ucTypePIN );
+
+        //Log::end( "MiniDriverAuthentication::serialize" );
+    }
+
+};
+
+
+BOOST_CLASS_VERSION( MiniDriverAuthentication, 1 )
+
+
+#endif // __GEMALTO_MINIDRIVER_AUTHENTICATION__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,178 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "util.h"
+#include "MiniDriver.hpp"
+#include "MiniDriverCardCacheFile.hpp"
+#include "Log.hpp"
+#include "MiniDriverException.hpp"
+
+
+const unsigned char MAX_RETRY = 2;
+
+
+/*
+*/
+void MiniDriverCardCacheFile::write( void ) {
+
+    // Create a buffer to write the file oncard
+    std::auto_ptr< Marshaller::u1Array > f( new Marshaller::u1Array( 6 ) );
+
+    // Set the version flag
+    f->SetU1At( 0, m_ucVersion );
+
+    // Set the PIN freshness counter
+    f->SetU1At( 1, m_ucPinsFreshness );
+
+    // Set the container freshness counter
+    IntToLittleEndian< unsigned short >( m_wContainersFreshness, f->GetBuffer( ), 2 );
+
+    // Set the file freshness counter
+    IntToLittleEndian< unsigned short >( m_wFilesFreshness, f->GetBuffer( ), 4 );
+
+    // Write cache file back
+	std::string g_stPathCardCF( szCACHE_FILE );
+    m_pCardModuleService->writeFile( &g_stPathCardCF, f.get( ) );
+}
+
+
+/*
+*/
+void MiniDriverCardCacheFile::notifyChange( const ChangeType& a_change ) {
+
+    switch( a_change ) {
+
+    case PINS:
+        m_ucPinsFreshness++;
+        Log::log( "MiniDriverCardCacheFile::notifyChange - PINS" );
+        break;
+
+    case CONTAINERS:
+        m_wContainersFreshness++;
+        Log::log( "MiniDriverCardCacheFile::notifyChange - CONTAINERS" );
+        break;
+
+    case FILES:
+        m_wFilesFreshness++;
+        Log::log( "MiniDriverCardCacheFile::notifyChange - FILES" );
+        break;
+
+    case NONE:
+    default:
+        // No update
+        break;
+    };
+
+    write( );
+}
+
+
+/*
+*/
+void MiniDriverCardCacheFile::hasChanged( ChangeType& a_Pins, ChangeType& a_Containers, ChangeType& a_Files ) {
+
+    Log::begin( "MiniDriverCardCacheFile::hasChanged" );
+    Timer t;
+    t.start( );
+
+    a_Pins = NONE;
+    a_Containers = NONE;
+    a_Files = NONE;
+
+    Log::log( "MiniDriverCardCacheFile::hasChanged - Inner Version <%#02x>", m_ucVersion );
+    Log::log( "MiniDriverCardCacheFile::hasChanged - Inner PIN freshness counter <%#02x>", m_ucPinsFreshness );
+    Log::log( "MiniDriverCardCacheFile::hasChanged - Inner Containers freshness counter <%#04x>", m_wContainersFreshness );
+    Log::log( "MiniDriverCardCacheFile::hasChanged - Inner Files freshness counter <%#04x>", m_wFilesFreshness );
+
+    // Get the file from the smart card
+	std::string g_stPathCardCF( szCACHE_FILE );
+    Marshaller::u1Array* f = m_pCardModuleService->readFileWithoutMemoryCheck( &g_stPathCardCF );
+
+    if( f ) {
+
+        std::string s;
+        Log::toString( f->GetBuffer( ), f->GetLength( ), s );
+        Log::log( "MiniDriverCardCacheFile::hasChanged - cardcf <%s>", s.c_str( ) );
+
+        // Get the version
+        unsigned char ucVersion = f->ReadU1At( 0 );
+        Log::log( "MiniDriverCardCacheFile::hasChanged - Read Version <0x%#02x>", ucVersion );
+        
+        if( ucVersion != m_ucVersion ) {
+        
+            m_ucVersion = ucVersion;
+        }
+
+        // Get the PIN freshness counter
+        unsigned char bPinsFreshness = f->ReadU1At( 1 );
+        Log::log( "MiniDriverCardCacheFile::hasChanged - Read PIN freshness counter <%#02x>", bPinsFreshness );
+
+        if( m_ucPinsFreshness != bPinsFreshness ) {
+
+            Log::log( "MiniDriverCardCacheFile::hasChanged - $$$$$ PIN freshness counter changed $$$$$" );
+            m_ucPinsFreshness = bPinsFreshness;
+            a_Pins = PINS;
+        }
+
+        // Get the container freshness counter
+        unsigned short wContainersFreshness = LittleEndianToInt< unsigned short >( f->GetBuffer( ), 2 );
+        Log::log( "MiniDriverCardCacheFile::hasChanged - Read Containers freshness counter <%#02x>", wContainersFreshness );
+
+        if( m_wContainersFreshness != wContainersFreshness ) {
+
+            Log::log( "MiniDriverCardCacheFile::hasChanged - $$$$$ CONTAINER freshness counter changed $$$$$" );
+            m_wContainersFreshness = wContainersFreshness;
+            a_Containers = CONTAINERS;
+        }
+
+        // Get the file freshness counter
+        unsigned short wFilesFreshness = LittleEndianToInt< unsigned short >( f->GetBuffer( ), 4 );
+        Log::log( "MiniDriverCardCacheFile::hasChanged - Read Files freshness counter <%#02x>", wFilesFreshness );
+
+        if( m_wFilesFreshness != wFilesFreshness ) {
+
+            Log::log( "MiniDriverCardCacheFile::hasChanged - $$$$$ FILE freshness counter changed $$$$$" );
+            m_wFilesFreshness = wFilesFreshness;
+            a_Files = FILES;
+        }
+    }
+
+    t.stop( "MiniDriverCardCacheFile::read" );
+    Log::end( "MiniDriverCardCacheFile::read" );
+}
+
+
+/*
+*/
+void MiniDriverCardCacheFile::print( void ) {
+    
+    Log::begin( "MiniDriverCardCacheFile::print" );
+
+    Log::log( "Version <%ld>", m_ucVersion );
+
+    Log::log( "m_ucPinsFreshness <%ld>", m_ucPinsFreshness );
+
+    Log::log( "m_wContainersFreshness <%ld>", m_wContainersFreshness );
+
+    Log::log( "m_wFilesFreshness <%ld>", m_wFilesFreshness );
+
+    Log::end( "MiniDriverCardCacheFile::print" );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverCardCacheFile.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,91 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_MINIDRIVER_CARD_CACHE_FILE_
+#define __GEMALTO_MINIDRIVER_CARD_CACHE_FILE_
+
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/shared_ptr.hpp>
+#include "CardModuleService.hpp"
+
+
+/*
+*/
+class MiniDriverCardCacheFile {
+
+public:
+
+    typedef enum { NONE = 0, PINS = 4, CONTAINERS = 8, FILES = 16 } ChangeType;
+
+    inline MiniDriverCardCacheFile( ) { m_ucVersion = 0; m_ucPinsFreshness = 0; m_wContainersFreshness = 0; m_wFilesFreshness = 0; }
+
+    inline void setCardModuleService( CardModuleService* const a_pMiniDriver ) { m_pCardModuleService = a_pMiniDriver; }
+
+    void write( void ); 
+
+    void notifyChange( const ChangeType& a_change );
+
+    void hasChanged( ChangeType& a_Pins, ChangeType& a_Containers, ChangeType& a_Files );
+
+    void print( void );
+
+private:
+
+    unsigned char m_ucVersion;
+
+    unsigned char m_ucPinsFreshness;
+
+    unsigned short m_wContainersFreshness;
+
+    unsigned short m_wFilesFreshness;
+
+    CardModuleService* m_pCardModuleService;
+
+    // On computer disk serialization and deserialization
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+
+        //Log::begin( "MiniDriverCardCacheFile::serialize" );
+
+        ar & m_ucVersion;
+
+        ar & m_ucPinsFreshness;
+
+        ar & m_wContainersFreshness;
+
+        ar & m_wFilesFreshness;
+
+        //Log::log( "Version <%ld>", m_ucVersion );
+        //Log::log( "Pins Freshness <%ld>", m_ucPinsFreshness );
+        //Log::log( "Containers Freshness <%ld>", m_wContainersFreshness );
+        //Log::log( "Files Freshness <%ld>", m_wFilesFreshness );
+
+        //Log::end( "MiniDriverCardCacheFile::serialize" );
+    }
+
+};
+
+BOOST_CLASS_VERSION( MiniDriverCardCacheFile, 1 )
+
+#endif // __GEMALTO_MINIDRIVER_CARD_CACHE_FILE_

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,302 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "MiniDriverContainer.hpp"
+#include <boost/foreach.hpp>
+#include <memory>
+#include "Log.hpp"
+
+
+const unsigned char g_ucPublicKeyExponentLen = 4;
+const unsigned char g_ucPublicKeyModulusLen = 4;
+#define CONTAINER_MAP_RECORD_GUID_SIZE 40 * sizeof( WCHAR )
+
+
+/*
+*/
+MiniDriverContainer::MiniDriverContainer( ) {
+
+    clear( );
+}
+
+
+/*
+*/
+void MiniDriverContainer::clear( void ) {
+
+    memset( &m_ContainerMapRecord, 0, sizeof( CONTAINER_MAP_RECORD ) );
+
+    m_bIsSmartCardLogon = false;
+
+    m_ucSignatureContainerType = 0;
+
+    m_ucExchangeContainerType = 0;
+
+    m_PinIdentifier = MiniDriverAuthentication::PIN_USER;
+}
+
+
+/*
+*/
+void MiniDriverContainer::setContainerMapRecord( CONTAINER_MAP_RECORD* a_pContainerMapRecord ) {
+
+    Log::begin( "MiniDriverContainer::setContainerMapRecord" );
+
+    if( a_pContainerMapRecord->wSigKeySizeBits || a_pContainerMapRecord->wKeyExchangeKeySizeBits ) {
+
+        m_ContainerMapRecord.bFlags = a_pContainerMapRecord->bFlags;
+
+        m_ContainerMapRecord.wKeyExchangeKeySizeBits = a_pContainerMapRecord->wKeyExchangeKeySizeBits;
+
+        m_ContainerMapRecord.wSigKeySizeBits = a_pContainerMapRecord->wSigKeySizeBits;
+
+        if( a_pContainerMapRecord->wszGuid ) {
+
+            memcpy( m_ContainerMapRecord.wszGuid, a_pContainerMapRecord->wszGuid, CONTAINER_MAP_RECORD_GUID_SIZE );
+        
+        } else {
+
+            memset( m_ContainerMapRecord.wszGuid, 0, CONTAINER_MAP_RECORD_GUID_SIZE );
+        }
+    }
+
+    //print( );
+    Log::end( "MiniDriverContainer::setContainerMapRecord" );
+}
+
+
+/*
+*/
+void MiniDriverContainer::setContainerInformation( const boost::shared_ptr< Marshaller::u1Array >& a_pContainerInformation ) {
+
+    Log::begin( "MiniDriverContainer::setContainerInformation" );
+    std::string s;
+    Log::toString( a_pContainerInformation->GetBuffer( ), a_pContainerInformation->GetLength( ), s );
+    Log::log( "ContainerInformation <%s>", s.c_str( ) );
+
+    // The container information is a byte array blob containing the public key(s) in the selected container. 
+    // The blob is formatted as follows:  Blob = [Signature_Pub_Key] | [Exchange_Pub_Key] 
+    // Signature_Pub_Key and Exchange_Pub_Key are optional depending on which key exists in the container and it\x92s a sequence of 3 TLV formatted as follows: 
+    
+    //T_Key_Type = 0x03 
+    //L_Key_Type = 0x01 
+    //V_Key_Type = 0x01 for Exchange_Pub_Key or 0x02 for Signature_Pub_Key 
+    
+    //T_Key_Pub_Exp = 0x01 
+    //L_Key_Pub_Exp = 0x04 
+    //V_Key_Pub_Exp = Value of Public key Exponent on 4 bytes. 
+    
+    //T_Key_Modulus = 0x02 
+    //L_Key_Modulus = Key_Size_Bytes >> 4 (1 byte !) 
+    //V_Key_Modulus = Value of Public key Modulus on Key_Size_Bytes bytes.
+
+    // Get the first public key  type
+    unsigned int iOffset = 2;
+    unsigned char ucFirstPublicKeyType = a_pContainerInformation->ReadU1At( iOffset );
+
+    // Read the first public key exponent value
+    iOffset += 2;
+    unsigned int uiFirstPublicKeyExponentLength = a_pContainerInformation->ReadU1At( iOffset );
+
+    // Read the first public key exponent value
+    iOffset += 1;
+    Marshaller::u1Array* pFirstPublicKeyExponent = new Marshaller::u1Array( g_ucPublicKeyExponentLen );
+    
+    // The exponent must be a 4 bytes buffer.
+    if( uiFirstPublicKeyExponentLength < g_ucPublicKeyExponentLen ) {
+    
+        // Add zero at the head of the buffer
+        memset( pFirstPublicKeyExponent->GetBuffer( ), 0, g_ucPublicKeyExponentLen );
+    
+        int iPaddingLength = g_ucPublicKeyExponentLen - uiFirstPublicKeyExponentLength;
+
+        memcpy( pFirstPublicKeyExponent->GetBuffer( ) + iPaddingLength, a_pContainerInformation->GetBuffer( ) + iOffset, uiFirstPublicKeyExponentLength );
+
+    } else {
+    
+        memcpy( pFirstPublicKeyExponent->GetBuffer( ), a_pContainerInformation->GetBuffer( ) + iOffset, g_ucPublicKeyExponentLen );
+    }
+
+    // Read the first public key modulus len.
+    // Keep in mind that the signature public key modulus len is stored as a 4 rigth-shifted byte (>>4) to pass the modulus length on 1 byte ofr values 64 to 256 (512 to 2048bits)
+    iOffset += uiFirstPublicKeyExponentLength + 1;
+    int ucPublicKeyModulusLen = a_pContainerInformation->ReadU1At( iOffset ) << 4;
+
+    // Read the first public key modulus value
+    iOffset += 1;
+    Marshaller::u1Array* pFirstPublicKeyModulus = new Marshaller::u1Array( ucPublicKeyModulusLen );
+    memcpy( pFirstPublicKeyModulus->GetBuffer( ), a_pContainerInformation->GetBuffer( ) + iOffset, ucPublicKeyModulusLen );
+
+    if( KEYSPEC_EXCHANGE == ucFirstPublicKeyType ) {
+
+        m_pExchangePublicKeyExponent.reset( pFirstPublicKeyExponent );
+
+        m_pExchangePublicKeyModulus.reset( pFirstPublicKeyModulus );
+
+    } else {
+
+        m_pSignaturePublicKeyExponent.reset( pFirstPublicKeyExponent );
+
+        m_pSignaturePublicKeyModulus.reset( pFirstPublicKeyModulus );   
+    }
+
+    // Check if the second key information is present into the container information
+    iOffset += ucPublicKeyModulusLen + 1;
+    if( iOffset < a_pContainerInformation->GetLength( ) ) {
+
+        // Read the second public key type
+        iOffset += 2;
+        unsigned char ucSecondPublicKeyType = a_pContainerInformation->ReadU1At( iOffset );
+
+        // Read the second public key exponent value
+        iOffset += 2;
+        unsigned int uiSecondPublicKeyExponentLength = a_pContainerInformation->ReadU1At( iOffset );
+
+        // The exponent must be a 4 bytes buffer.
+        Marshaller::u1Array* pSecondPublicKeyExponent = new Marshaller::u1Array( g_ucPublicKeyExponentLen );
+
+        if( uiSecondPublicKeyExponentLength < g_ucPublicKeyExponentLen ) {
+    
+            // Add zero at the head of the buffer
+            memset( pSecondPublicKeyExponent->GetBuffer( ), 0, g_ucPublicKeyExponentLen );
+    
+            int iPaddingLength = g_ucPublicKeyExponentLen - uiSecondPublicKeyExponentLength;
+
+            memcpy( pSecondPublicKeyExponent->GetBuffer( ) + iPaddingLength, a_pContainerInformation->GetBuffer( ) + iOffset, uiSecondPublicKeyExponentLength );
+
+        } else {
+    
+            memcpy( pSecondPublicKeyExponent->GetBuffer( ), a_pContainerInformation->GetBuffer( ) + iOffset, g_ucPublicKeyExponentLen );
+        }
+
+        // Read the second public key modulus len.
+        // Keep in mind that the signature public key modulus len is stored as a 4 rigth-shifted byte (>>4) to pass the modulus length on 1 byte ofr values 64 to 256 (512 to 2048bits)
+        iOffset += uiSecondPublicKeyExponentLength + 1;
+
+        ucPublicKeyModulusLen = a_pContainerInformation->ReadU1At( iOffset ) << 4;
+
+        // Read the second public key modulus value
+        ++iOffset;
+        Marshaller::u1Array* pSecondPublicKeyModulus = new Marshaller::u1Array( ucPublicKeyModulusLen );
+        memcpy( pSecondPublicKeyModulus->GetBuffer( ), a_pContainerInformation->GetBuffer( ) + iOffset, ucPublicKeyModulusLen );
+
+        if( KEYSPEC_EXCHANGE == ucSecondPublicKeyType ) {
+
+            m_pExchangePublicKeyExponent.reset( pSecondPublicKeyExponent );
+
+            m_pExchangePublicKeyModulus.reset( pSecondPublicKeyModulus );
+
+        } else {
+
+            m_pSignaturePublicKeyExponent.reset( pSecondPublicKeyExponent );
+
+            m_pSignaturePublicKeyModulus.reset( pSecondPublicKeyModulus );   
+        }
+    }
+
+    //print( );
+    Log::end( "MiniDriverContainer::setContainerInformation" );
+}
+
+
+/*
+*/ 
+void MiniDriverContainer::print( void ) {
+
+    if( !Log::s_bEnableLog ) {
+    
+        return;
+    }
+
+    Log::log( "MiniDriverContainer - ===" );
+
+    Log::log( "MiniDriverContainer - [SmartCard Logon <%d>]", m_bIsSmartCardLogon );
+
+    Log::log( "MiniDriverContainer - Flag <%#02x>", m_ContainerMapRecord.bFlags );
+
+    Log::log( "MiniDriverContainer - wKeyExchangeKeySizeBits <%#02x>", m_ContainerMapRecord.wKeyExchangeKeySizeBits );
+
+    Log::log( "MiniDriverContainer - wSigKeySizeBits <%#02x>", m_ContainerMapRecord.wSigKeySizeBits );
+
+    std::string s;
+    Log::toString( (const unsigned char*)m_ContainerMapRecord.wszGuid, (size_t)sizeof( m_ContainerMapRecord.wszGuid ), s );
+    Log::log( "MiniDriverContainer - wszGuid <%s>", s.c_str( ) );
+
+    s = "";
+    if( m_pSignaturePublicKeyExponent ) {
+
+        Log::toString( m_pSignaturePublicKeyExponent->GetBuffer( ), m_pSignaturePublicKeyExponent->GetLength( ), s );
+        Log::log( "MiniDriverContainer - SignaturePublicKeyExponent <%s>", s.c_str( ) );
+
+    } else {
+
+        Log::log( "MiniDriverContainer - SignaturePublicKeyExponent <0>" );
+    }
+
+    if( m_pSignaturePublicKeyModulus ) {
+
+        Log::toString( m_pSignaturePublicKeyModulus->GetBuffer( ), m_pSignaturePublicKeyModulus->GetLength( ), s );
+        Log::log( "MiniDriverContainer - SignaturePublicKeyModulus <%s>", s.c_str( ) );
+
+    } else {
+
+        Log::log( "MiniDriverContainer - SignaturePublicKeyModulus <0>" );
+    }    
+
+    if( m_pExchangePublicKeyExponent ) {
+
+        Log::toString( m_pExchangePublicKeyExponent->GetBuffer( ), m_pExchangePublicKeyExponent->GetLength( ), s );
+        Log::log( "MiniDriverContainer - ExchangePublicKeyExponent <%s>", s.c_str( ) );
+
+    } else {
+
+        Log::log( "MiniDriverContainer - ExchangePublicKeyExponent <0>" );
+    }    
+
+    if( m_pExchangePublicKeyModulus ) {
+
+        Log::toString( m_pExchangePublicKeyModulus->GetBuffer( ), m_pExchangePublicKeyModulus->GetLength( ), s );
+        Log::log( "MiniDriverContainer - ExchangePublicKeyModulus <%s>", s.c_str( ) );
+
+    } else {
+
+        Log::log( "MiniDriverContainer - ExchangePublicKeyModulus <0>" );
+    }  
+}
+
+
+void MiniDriverContainer::setGUID( const std::string& a_stGUID ) { 
+    
+   memset( m_ContainerMapRecord.wszGuid, 0, sizeof( m_ContainerMapRecord.wszGuid ) );
+
+   size_t length = ( a_stGUID.size( ) > 39 ) ? 39 : a_stGUID.size( );
+
+    for( size_t i = 0 ; i < length; ++i ) {
+
+        m_ContainerMapRecord.wszGuid[ i ] = (WCHAR)a_stGUID[ i ];
+    }
+
+   //for( size_t i = 0 ; i < length; ++i ) {
+
+   //   // Convert to wchar, little endian.
+   //   m_ContainerMapRecord.wszGuid[ 2*i ]  = a_stGUID[ i ]; 
+   //}
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainer.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,174 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_MINIDRIVER_CONTAINER__
+#define __GEMALTO_MINIDRIVER_CONTAINER__
+
+
+#include <memory>
+#include <string>
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/shared_ptr.hpp>
+#include "Array.hpp"
+#include "cardmod.h"
+#include "Log.hpp"
+#include "MiniDriverAuthentication.hpp"
+
+
+/*
+*/
+class MiniDriverContainer {
+
+public:
+
+    typedef enum { KEYSPEC_EXCHANGE = 0x01, KEYSPEC_SIGNATURE = 0x02 } KEYSPEC;
+
+    typedef enum { CMAPFILE_FLAG_EMPTY = 0x00, CMAPFILE_FLAG_VALID = 0x01, CMAPFILE_FLAG_VALID_AND_DEFAULT = 0x03 } FLAG;
+
+    MiniDriverContainer( );
+
+    void clear( void );
+
+    void setContainerMapRecord( CONTAINER_MAP_RECORD* );
+
+    void setContainerInformation( const boost::shared_ptr< Marshaller::u1Array >& );
+
+    void setGUID( const std::string& a_stGUID );
+
+    inline void setFlags( const FLAG& a_ucFlags ) { m_ContainerMapRecord.bFlags = (unsigned char)a_ucFlags; }
+
+    inline bool empty( void ) { return ( !m_ContainerMapRecord.wSigKeySizeBits && !m_ContainerMapRecord.wKeyExchangeKeySizeBits ); }
+
+    inline const CONTAINER_MAP_RECORD& getContainerMapRecord( void ) { print( ); return m_ContainerMapRecord; }
+
+    inline unsigned char getFlags( void ) { return m_ContainerMapRecord.bFlags; }
+
+    inline WORD getKeyExchangeSizeBits( void ) { return m_ContainerMapRecord.wKeyExchangeKeySizeBits; }
+
+    inline WORD getKeySignatureSizeBits( void ) { return m_ContainerMapRecord.wSigKeySizeBits; }
+
+    inline void setKeyExchangeSizeBits( const WORD& a_wSize ) { m_ContainerMapRecord.wKeyExchangeKeySizeBits = a_wSize; }
+
+    inline void setKeySignatureSizeBits( const WORD& a_wSize ) { m_ContainerMapRecord.wSigKeySizeBits = a_wSize; }
+
+    inline boost::shared_ptr< Marshaller::u1Array >& getSignaturePublicKeyExponent( void ) { return m_pSignaturePublicKeyExponent; }
+
+    inline boost::shared_ptr< Marshaller::u1Array >& getSignaturePublicKeyModulus( void ) { return m_pSignaturePublicKeyModulus; }
+
+    inline boost::shared_ptr< Marshaller::u1Array >& getExchangePublicKeyExponent( void ) { return m_pExchangePublicKeyExponent; }
+
+    inline boost::shared_ptr< Marshaller::u1Array >& getExchangePublicKeyModulus( void ) { return m_pExchangePublicKeyModulus; }
+
+    inline bool getFlagSmartCardLogon( void ) { return m_bIsSmartCardLogon; }
+
+    inline void setFlagSmartCardLogon( const bool& a_bIsSmartCardLogon ) { m_bIsSmartCardLogon = a_bIsSmartCardLogon; }
+
+
+    inline void setContainerTypeForSignatureKey( const unsigned char& a_ContainerTypeForSignatureKey ) { m_ucSignatureContainerType = a_ContainerTypeForSignatureKey; }
+
+    inline void setContainerTypeForExchangeKey( const unsigned char& a_ContainerTypeForExchangeKey ) { m_ucExchangeContainerType = a_ContainerTypeForExchangeKey; }
+
+    inline void setPinIdentifier( const MiniDriverAuthentication::ROLES& a_ContainerPinIdentifier ) { m_PinIdentifier = a_ContainerPinIdentifier; }
+
+    inline bool isImportedSignatureKey( void ) { return ( m_ucSignatureContainerType == 0x00 ); }
+
+    inline bool isImportedExchangeKey( void ) { return ( 0x00 == m_ucExchangeContainerType ); }
+
+    inline MiniDriverAuthentication::ROLES getPinIdentifier( void ) { return m_PinIdentifier; }
+
+private:
+
+    CONTAINER_MAP_RECORD m_ContainerMapRecord;
+
+    boost::shared_ptr< Marshaller::u1Array > m_pSignaturePublicKeyExponent;
+
+    boost::shared_ptr< Marshaller::u1Array > m_pSignaturePublicKeyModulus;
+
+    boost::shared_ptr< Marshaller::u1Array > m_pExchangePublicKeyExponent;
+
+    boost::shared_ptr< Marshaller::u1Array > m_pExchangePublicKeyModulus;
+
+    bool m_bIsSmartCardLogon;
+
+    unsigned char m_ucSignatureContainerType;
+
+    unsigned char m_ucExchangeContainerType;
+
+    MiniDriverAuthentication::ROLES m_PinIdentifier;
+
+    void print( void );	
+
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+
+        ar & m_pSignaturePublicKeyModulus;
+        ar & m_pSignaturePublicKeyExponent;
+        ar & m_pExchangePublicKeyExponent;
+        ar & m_pExchangePublicKeyModulus;
+        ar & m_ContainerMapRecord.bFlags;
+        ar & m_ContainerMapRecord.bReserved;
+        ar & m_ContainerMapRecord.wKeyExchangeKeySizeBits;
+        ar & m_ContainerMapRecord.wSigKeySizeBits;
+        ar & m_ContainerMapRecord.wszGuid;
+        ar & m_bIsSmartCardLogon;
+        ar & m_ucSignatureContainerType;
+        ar & m_ucExchangeContainerType;
+        ar & m_PinIdentifier;
+            
+        //if( m_ContainerMapRecord.bFlags ) {
+
+        // Log::begin( "MiniDriverContainer::serialize" );
+        //   if( m_pSignaturePublicKeyExponent.get( ) ) {
+
+        //        Log::logCK_UTF8CHAR_PTR( "SignaturePublicKeyExponent", m_pSignaturePublicKeyExponent->GetBuffer( ), m_pSignaturePublicKeyExponent->GetLength( ) );
+        //    }
+        //    if( m_pSignaturePublicKeyModulus.get( ) ) {
+        //    
+        //        Log::logCK_UTF8CHAR_PTR( "SignaturePublicKeyModulus", m_pSignaturePublicKeyModulus->GetBuffer( ), m_pSignaturePublicKeyModulus->GetLength( ) );
+        //    }
+        //    if( m_pExchangePublicKeyExponent.get( ) ) {
+        //     
+        //        Log::logCK_UTF8CHAR_PTR( "ExchangePublicKeyExponent", m_pExchangePublicKeyExponent->GetBuffer( ), m_pExchangePublicKeyExponent->GetLength( ) );
+        //    }
+        //    if( m_pExchangePublicKeyModulus.get( ) ) {
+
+        //        Log::logCK_UTF8CHAR_PTR( "ExchangePublicKeyModulus", m_pExchangePublicKeyModulus->GetBuffer( ), m_pExchangePublicKeyModulus->GetLength( ) );
+        //    }
+        //    Log::log( "ContainerMapRecord.bFlags <%ld>", m_ContainerMapRecord.bFlags );
+        //    Log::log( "ContainerMapRecord.bReserved <%ld>", m_ContainerMapRecord.bReserved );
+        //    Log::log( "ContainerMapRecord.wKeyExchangeKeySizeBits <%ld>", m_ContainerMapRecord.wKeyExchangeKeySizeBits );
+        //    Log::log( "ContainerMapRecord.wSigKeySizeBits <%ld>", m_ContainerMapRecord.wSigKeySizeBits );
+        //    Log::logCK_UTF8CHAR_PTR( "m_ContainerMapRecord.wszGuid", (unsigned char*) m_ContainerMapRecord.wszGuid, 80 /*sizeof( m_ContainerMapRecord.wszGuid )*/ );
+        //    Log::log( "m_bIsSmartCardLogon <%ld>", m_bIsSmartCardLogon );
+        //    Log::log( "m_ucSignatureContainerType <%ld>", m_ucSignatureContainerType );
+        //    Log::log( "m_ucExchangeContainerType <%ld>", m_ucExchangeContainerType );
+        //    Log::log( "m_PinIdentifier <%ld>", m_PinIdentifier );
+        // Log::end( "MiniDriverContainer::serialize" );
+       //}
+    }
+
+};
+
+BOOST_CLASS_VERSION( MiniDriverContainer, 1 )
+
+#endif // __GEMALTO_MINIDRIVER_CONTAINER__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,875 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto->com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <cstdio>
+#include <boost/foreach.hpp>
+#include <memory>
+#include "cardmod.h"
+#include "MiniDriverContainerMapFile.hpp"
+#include "MiniDriverFiles.hpp"
+#include "Log.hpp"
+#include "Timer.hpp"
+#include "MiniDriverException.hpp"
+#include "sha1.h"
+/*
+ #ifdef __APPLE__
+#include "PCSC/winscard.h"
+#else
+#include "winscard.h"
+#endif
+*/
+
+#include "PCSCMissing.h"
+
+const int g_iContainerSize = 0x56; //sizeof( CONTAINER_MAP_RECORD );
+unsigned char MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID = 0xFF;
+const int CARD_PROPERTY_CONTAINER_TYPE = 0x80;
+const int CARD_PROPERTY_PIN_IDENTIFIER = 0x01;
+
+
+/*
+*/
+void MiniDriverContainerMapFile::containerRead( void ) {
+
+    Log::begin( "MiniDriverContainerMapFile::containerRead" );
+    Timer t;
+    t.start( );
+
+    if( !m_MiniDriverFiles ) {
+    
+        Log::error( "MiniDriverContainerMapFile::containerRead", "Invalid file system object" );
+        return;
+    }
+
+    CardModuleService* m = m_MiniDriverFiles->getCardModuleService( );
+
+    if( !m ) {
+         
+        Log::error( "MiniDriverContainerMapFile::containerRead", "Invalid card module service object" );
+
+        return;
+    }
+
+    // Reset the stored containers table
+    BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+        c.clear( );
+    }
+
+    // Read the CMap file
+    m_ContainerMapFileBinary.reset( m_MiniDriverFiles->readFile( std::string( szBASE_CSP_DIR ), std::string( szCONTAINER_MAP_FILE ) ) );
+
+    // Populate the container Map records
+    unsigned int uiLen = m_ContainerMapFileBinary.GetLength( );
+
+    bool bContainerPresent = false;
+
+    for( unsigned int i = 0 ; i < uiLen ; ++i ) {
+    
+        if( m_ContainerMapFileBinary.ReadU1At( i ) ) {
+
+            bContainerPresent = true;
+
+            break;
+        }
+    }
+
+    if( uiLen && bContainerPresent ) {
+
+        unsigned char iContainersCount = ( unsigned char )( uiLen / g_iContainerSize );
+
+        unsigned char* b = m_ContainerMapFileBinary.GetBuffer( );
+
+        for( unsigned char i = 0; i < iContainersCount; ++i ) {
+        
+            try {
+
+                // Populate the container info (throws if the container is empty)
+                boost::shared_ptr< Marshaller::u1Array > ci( m->getContainer( i ) );
+
+                std::string stContainer;
+                Log::toString( ci->GetBuffer( ), ci->GetLength( ), stContainer );
+                Log::log( "MiniDriverContainerMapFile::containerRead - index <%d> - container <%s>", i, stContainer.c_str( ) );
+
+                m_Containers[ i ].setContainerInformation( ci );
+
+                // Populate the container map record
+                m_Containers[ i ].setContainerMapRecord( (CONTAINER_MAP_RECORD*)( b + ( i * g_iContainerSize ) ) );
+
+                CardModuleService* cms = m_MiniDriverFiles->getCardModuleService( );
+                if( cms ) {
+
+                    unsigned char f = 0;
+                    
+                    std::auto_ptr< Marshaller::u1Array > containerType( cms->getContainerProperty( i, CARD_PROPERTY_CONTAINER_TYPE, f ) );
+                    
+                    if( containerType.get( ) ) {
+
+                        m_Containers[ i ].setContainerTypeForSignatureKey( containerType->ReadU1At( 0 ) );
+                        
+                        m_Containers[ i ].setContainerTypeForExchangeKey( containerType->ReadU1At( 1 ) );
+                    }
+
+                    f = 0;
+
+                    std::auto_ptr< Marshaller::u1Array > containerPinIdentifier( cms->getContainerProperty( i, CARD_PROPERTY_PIN_IDENTIFIER, f ) );
+                    
+                    if( containerPinIdentifier.get( ) ) {
+                    
+                        MiniDriverAuthentication::ROLES r = (MiniDriverAuthentication::ROLES)containerPinIdentifier->ReadU1At( 0 );
+                    
+                        m_Containers[ i ].setPinIdentifier( r );
+                    }
+                }
+
+            } catch( MiniDriverException& x ) {
+
+                // The container is empty
+                Log::error( "MiniDriverContainerMapFile::containerRead", "Unable to read the container" );
+                
+                switch( x.getError( ) ) {
+                
+                case SCARD_E_INVALID_PARAMETER:
+                    // The container does not exist
+                    m_Containers[ i ].clear( );
+                    break;
+
+                default:
+                    // The container cannot be read
+                    throw;
+                }
+            }
+        }
+    }
+
+    //print( );
+    t.stop( "MiniDriverContainerMapFile::containerRead" );
+    Log::end( "MiniDriverContainerMapFile::containerRead" );
+}
+
+
+/*
+*/
+void MiniDriverContainerMapFile::write( void ) {
+
+    Log::begin( "MiniDriverContainerMapFile::write" );
+    Timer t;
+    t.start( );
+
+        if( !m_MiniDriverFiles ) {
+    
+        Log::error( "MiniDriverContainerMapFile::write", "Invalid file system object" );
+        return;
+    }
+
+    //print( );
+
+    // Create a new CMap file
+    Marshaller::u1Array* p = new Marshaller::u1Array( );
+
+    // Populate the new CMap file
+    int iOffset = 0;
+
+    unsigned int sz = (unsigned int)m_Containers.size( );
+
+    int i = 0;
+
+    bool bMoreRecordToWrite = false;
+
+    CONTAINER_MAP_RECORD cmr;
+
+    BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+        // Try to locate a record to write after the current one
+        bMoreRecordToWrite = false;
+
+        for( unsigned int j = i + 1 ; j < sz; ++j ) {
+
+            if( !m_Containers.at( j ).empty( ) ) {
+
+                bMoreRecordToWrite = true;
+                break;
+            }
+        }
+
+        Marshaller::u1Array b( g_iContainerSize );
+
+        if( c.empty( ) ) {
+            
+            if( bMoreRecordToWrite ) {
+
+                // The current record is empty but one the following records is not
+                // Add an empty one to guaranrty that the CMapFile parsing based on the
+                // jump of the record size will work
+                *p += b;
+            }
+
+        } else {
+
+            cmr = c.getContainerMapRecord( );
+            
+            memcpy( b.GetBuffer( ), &cmr, g_iContainerSize );
+
+            *p += b;
+        }
+
+        // No more record to write after the current one
+        if( !bMoreRecordToWrite ) {
+
+            // So the operation is stopped here to avoid to add empty records into the CMapFile
+            break;
+        }
+
+        iOffset += g_iContainerSize;
+
+        ++i;
+    }
+
+    // No record to write.
+    if( !p->GetLength( ) ) {
+    
+        // Add an empty record to get a valid CMapFile
+        Marshaller::u1Array b( g_iContainerSize );
+        *p += b;
+    }
+
+    // Store the new CMap file
+    m_ContainerMapFileBinary.reset( p );
+
+    std::string s;
+    Log::toString( p->GetBuffer( ), p->GetLength( ), s );
+    Log::log( " CMapfile <%s>", s.c_str( ) );
+
+    // Check the CMapFile exists
+    std::string stCMapFile( szCONTAINER_MAP_FILE );
+    
+    std::string stMscpDirectory( szBASE_CSP_DIR );
+
+    MiniDriverFiles::FILES_NAME fs = m_MiniDriverFiles->enumFiles( stMscpDirectory );
+    
+    MiniDriverFiles::FILES_NAME::const_iterator it = fs.find( stCMapFile );
+    
+    if( it == fs.end( ) ) {
+    
+        // The CMapFile does not exist. It must be create before to write the content
+        // Create the access conditions for the CMapFile
+         Marshaller::u1Array ac( 3 );
+
+        // Administrator access condition
+        ac.GetBuffer( )[ 0 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+        // User access condition
+        ac.GetBuffer( )[ 1 ] = MiniDriverFiles::CARD_PERMISSION_READ | MiniDriverFiles::CARD_PERMISSION_WRITE;
+
+        // Everyone access condition
+        ac.GetBuffer( )[ 2 ] = MiniDriverFiles::CARD_PERMISSION_READ;
+
+        m_MiniDriverFiles->createFile( stMscpDirectory, stCMapFile, &ac );
+    }
+
+    // Write the new CMap file
+    m_MiniDriverFiles->writeFile( stMscpDirectory, stCMapFile, p, true, true );
+
+    //print( );
+    t.stop( "MiniDriverContainerMapFile::write" );
+    Log::end( "MiniDriverContainerMapFile::write" );
+}
+
+
+/*
+*/
+void MiniDriverContainerMapFile::containerDelete( const unsigned char& a_ucContainerIndex ) {
+
+    Log::begin( "MiniDriverContainerMapFile::containerDelete" );
+    Timer t;
+    t.start( );
+
+    if( a_ucContainerIndex >= m_Containers.size( ) ) {
+
+        Log::error( "MiniDriverContainerMapFile::containerDelete", "Invalid container index" );
+
+        return;
+    }
+
+    if( !m_MiniDriverFiles ) {
+    
+        Log::error( "MiniDriverContainerMapFile::containerDelete", "Invalid file system object" );
+
+        return;
+    }
+
+    CardModuleService * p = m_MiniDriverFiles->getCardModuleService( );
+    
+    if( !p ) {
+    
+        Log::error( "MiniDriverContainerMapFile::containerDelete", "Invalid card module service object" );
+
+        return;
+    }
+
+    // Check the flag of this record to know if the default certificate is going to be removed
+    unsigned char ucFlags = m_Containers[ a_ucContainerIndex ].getFlags( );
+
+    // Clear the record
+    m_Containers[ a_ucContainerIndex ].clear( );
+
+    // Delete the oncard container  
+    p->deleteContainer( a_ucContainerIndex );
+
+    // Set a new default container
+    if( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT == ucFlags ) {
+
+        containerSetDefault( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID, false );
+    }
+
+    // write the new cmap file
+    write( );
+
+    //print( );
+    t.stop( "MiniDriverContainerMapFile::containerDelete" );
+    Log::end( "MiniDriverContainerMapFile::containerDelete" );
+}
+
+
+/*
+*/
+void MiniDriverContainerMapFile::containerCreate( unsigned char& a_ucContainerIndex, const bool& a_bKeyImport, unsigned char& a_ucKeySpec, Marshaller::u1Array* a_pKeyModulus, const int& a_KeySize, Marshaller::u1Array* a_pKeyValue ) {
+
+    Log::begin( "MiniDriverContainerMapFile::containerCreate" );
+    Timer t;
+    t.start( );
+
+    if( !m_MiniDriverFiles ) {
+    
+        Log::error( "MiniDriverContainerMapFile::containerCreate", "Invalid file system object" );
+                
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+
+        //return;
+    }
+
+    CardModuleService * p = m_MiniDriverFiles->getCardModuleService( );
+    
+    if( !p ) {
+    
+        Log::error( "MiniDriverContainerMapFile::containerCreate", "Invalid card module service object" );
+
+        throw MiniDriverException( SCARD_E_UNEXPECTED );
+        //return;
+    }
+
+// LCA: Remove this!
+/*
+// DOUBLE IMPORT
+    // Check if an existing container using the same public key modulus exists
+    containerGetMatching( a_ucContainerIndex, a_ucKeySpec, a_pKeyModulus );
+
+    if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID != a_ucContainerIndex ) {
+
+        // A container already uses this publick key modulus
+        return;
+    }
+// DOUBLE IMPORT
+*/
+
+    // Search for a free container
+    containerSearch( a_ucContainerIndex );
+
+    if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_ucContainerIndex ) {
+
+        // No free container
+        throw MiniDriverException( SCARD_E_WRITE_TOO_MANY );
+        //return;
+    }
+
+    // Create the key pair container into the smart card to import or generate the private key
+    p->createContainer( a_ucContainerIndex, a_bKeyImport, a_ucKeySpec, a_KeySize, a_pKeyValue );
+
+    // Populate the container info
+    
+    MiniDriverContainer& c = m_Containers[ a_ucContainerIndex ];
+
+    c.setFlags( MiniDriverContainer::CMAPFILE_FLAG_VALID );
+
+    if( MiniDriverContainer::KEYSPEC_EXCHANGE == a_ucKeySpec ) {
+
+        c.setKeyExchangeSizeBits( (WORD)a_KeySize );
+
+        c.setKeySignatureSizeBits( 0 );
+
+    } else {
+
+        c.setKeyExchangeSizeBits( 0 );
+
+        c.setKeySignatureSizeBits( (WORD)a_KeySize );
+    }
+
+    // Load the information from the smart card
+    boost::shared_ptr< Marshaller::u1Array > ci( p->getContainer( a_ucContainerIndex ) );
+
+    std::string stContainer;
+    Log::toString( ci->GetBuffer( ), ci->GetLength( ), stContainer );
+    Log::log( "MiniDriverContainerMapFile::containerWrite - index <%d> - container <%s>", a_ucContainerIndex, stContainer.c_str( ) );
+
+    c.setContainerInformation( ci );
+
+    std::string stContainerName;
+    
+    if( MiniDriverContainer::KEYSPEC_EXCHANGE == a_ucKeySpec ) {
+
+        stContainerName = computeContainerName( c.getExchangePublicKeyModulus( )->GetBuffer( ), c.getExchangePublicKeyModulus( )->GetLength( ) );
+    
+    } else {
+    
+        stContainerName = computeContainerName( c.getSignaturePublicKeyModulus( )->GetBuffer( ), c.getSignaturePublicKeyModulus( )->GetLength( ) );    
+    }
+
+    c.setGUID( stContainerName );
+
+    // write the new cmap file
+    write( );
+
+    //print( );
+    t.stop( "MiniDriverContainerMapFile::containerCreate" );
+    Log::end( "MiniDriverContainerMapFile::containerCreate" );
+}
+
+
+/*
+*/
+void MiniDriverContainerMapFile::containerSearch( unsigned char& a_ucContainerIndex ) {
+
+    Log::begin( "MiniDriverContainerMapFile::containerSearch" );
+    Timer t;
+    t.start( );
+
+    // The index is false. A new index has to be found.
+    a_ucContainerIndex = 0;
+
+    // Find an empty container
+    BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+        if( c.empty( ) ) {
+
+            Log::log( "container <%d> is empty", a_ucContainerIndex );
+
+            return;
+        }
+        Log::log( "container <%d> <%#02x>", a_ucContainerIndex, c.getFlags( ) );
+
+        ++a_ucContainerIndex;
+    }
+
+    if( a_ucContainerIndex >= m_Containers.size( ) ) {
+
+        a_ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+    }
+
+    t.stop( "MiniDriverContainerMapFile::containerSearch" );
+    Log::end( "MiniDriverContainerMapFile::containerSearch" );
+}
+
+
+/* Retreive the first certificate with the Smart Card Logn OID or anyone if not found update the CMapFile to set as default the choosen certificate
+*/
+void MiniDriverContainerMapFile::containerSetDefault( const unsigned char& a_ucIndex, const bool& a_IsSmartCardLogon ) {
+
+    Log::begin( " **************** MiniDriverContainerMapFile::containerSetDefault" );
+    Timer t;
+    t.start( );
+
+    //print( );
+
+    bool bJobDone = false;
+
+    bool bWrite = false;
+
+    // A new container has been created. We need to know if this is the new default one.
+    if( a_IsSmartCardLogon && ( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID != a_ucIndex ) ) {
+
+        // Does a default container exist ? In this case put it to a valid state
+        BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+            if( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT == c.getFlags( ) ) {
+
+                c.setFlags( MiniDriverContainer::CMAPFILE_FLAG_VALID );
+            }
+        }
+            
+        // Set the smart card logon flag for the new container
+        m_Containers[ a_ucIndex ].setFlagSmartCardLogon( a_IsSmartCardLogon );
+
+        // Declare the new valid & default container
+        m_Containers[ a_ucIndex ].setFlags( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT );
+
+        Log::log( "MiniDriverContainerMapFile::containerSetDefault - A new default container has been declared <%d>", a_ucIndex );
+
+        bJobDone = true;
+        
+        bWrite = true;
+    }
+
+    // A container has been deleted OR the new container is not able to become the default one.
+    // We may be need to find a new default one.
+
+    if( !bJobDone ) {
+
+        // Does a default container exist ?
+        BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+            if( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT == c.getFlags( ) ) {
+
+                Log::log( "MiniDriverContainerMapFile::containerSetDefault - Found a default container already existing" );
+
+                // A valid container already default
+                bJobDone = true;
+
+                break;  
+            }
+        }
+    }
+
+    if( !bJobDone ) {
+
+        // Does a container associated to a certificate with Smart Card Logon OID exists ?
+        BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+            //Log::log( "MiniDriverContainerMapFile::UpdateCMap - Certificate - Name <%s> - Container index <%ld> - Smart card logon <%ld>", c->_certName.c_str( ), s4CMapFileIndex, bIsSmartCardLogon );
+            if( c.getFlagSmartCardLogon( ) ) {
+
+                // Set the new default certificate
+                c.setFlags( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT );
+
+                Log::log( "MiniDriverContainerMapFile::containerSetDefault - Set the new default certificate" );
+
+                bJobDone = true;
+
+                bWrite = true;
+
+                break;
+            }
+        }
+    }
+ 
+    if( !bJobDone ) {
+
+        // Does a default container exist ?
+        BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+            if( MiniDriverContainer::CMAPFILE_FLAG_VALID == c.getFlags( ) ) {
+
+                //Log::log( "MiniDriverContainerMapFile::UpdateCMap - Found a valid container - Associated record <%ld> - old flags <%ld> - NEW Flags <%ld>", i, u1CMapFileRecordFlags, CMAPFILE_FLAG_VALID_AND_DEFAULT );
+
+                // Take the first valid container
+                c.setFlags( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT );
+
+                Log::log( "MiniDriverContainerMapFile::containerSetDefault - Take the first valid container" );
+
+                bWrite = true;
+
+                bJobDone = true;
+
+                break;  
+            }
+        }
+    }
+
+    if( bJobDone && bWrite ) {
+    
+        // write the new cmap file
+        write( );
+    }
+
+    //print( );
+    t.stop( "MiniDriverContainerMapFile::containerSetDefault" );
+    Log::end( "MiniDriverContainerMapFile::containerSetDefault" );
+}
+
+
+/*
+*/
+void MiniDriverContainerMapFile::clear( void ) { 
+
+    m_ContainerMapFileBinary.reset( ); 
+
+    BOOST_FOREACH( MiniDriverContainer& c, m_Containers ) {
+
+        c.clear( ); 
+    }
+}
+
+
+/*
+*/
+void MiniDriverContainerMapFile::print( void ) {
+
+    Log::begin( "MiniDriverContainerMapFile" );
+
+    int i = 0;
+    BOOST_FOREACH( MiniDriverContainer c, m_Containers ){
+
+        unsigned char ucFlags = c.getFlags( );
+
+        if( MiniDriverContainer::CMAPFILE_FLAG_VALID_AND_DEFAULT == ucFlags )
+        {
+            Log::log( "index <%ld> - flags <%ld> [DEFAULT]", i, ucFlags );
+        }
+        else
+        {
+            Log::log( "index <%ld> - flags <%ld>", i, ucFlags );
+        }
+
+        ++i;		
+    }
+
+    Log::end( "MiniDriverContainerMapFile" );
+}
+
+
+/*
+*/
+bool MiniDriverContainerMapFile::containerGetMatching( unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec, const Marshaller::u1Array* a_pPublicKeyModulus ) {
+
+    Log::begin( "MiniDriverContainerMapFile::containerGetMatching" );
+    Timer t;
+    t.start( );
+
+    bool bRet = false;
+
+    a_ucContainerIndex = CONTAINER_INDEX_INVALID;
+
+    if( !a_pPublicKeyModulus ) {
+     
+        return bRet;
+    }
+
+    unsigned char i = 0;
+
+    unsigned char* p = (unsigned char*)a_pPublicKeyModulus->GetBuffer( );
+
+    unsigned int l = a_pPublicKeyModulus->GetLength( );
+    
+    std::string stIncomingExchangePublicKeyModulus;
+    Log::toString( p, l, stIncomingExchangePublicKeyModulus );
+    Log::log( "MiniDriverContainerMapFile::containerGetMatching - incoming  <%s>", stIncomingExchangePublicKeyModulus.c_str( ) );
+    
+    std::string stMscpDirectory( szBASE_CSP_DIR );
+
+    MiniDriverFiles::FILES_NAME fs = m_MiniDriverFiles->enumFiles( stMscpDirectory );
+
+    char szCertX[ 10 ];
+
+    char szCertS[ 10 ];
+
+    BOOST_FOREACH( MiniDriverContainer c, m_Containers ) {
+
+        if( MiniDriverContainer::CMAPFILE_FLAG_EMPTY == c.getFlags( ) ) {
+
+            ++i;		
+
+            continue;
+        }
+
+        // LCA: Skip container if already has a certificate attached
+        memset( szCertX, 0, sizeof( szCertX ) );
+
+        memset( szCertS, 0, sizeof( szCertX ) );
+
+        sprintf( szCertX, "kxc%02x", i );
+
+        sprintf( szCertS, "ksc%02x", i );
+        
+        std::string stCertX(szCertX);
+        
+        std::string stCertS(szCertS);
+                
+        MiniDriverFiles::FILES_NAME::const_iterator itX = fs.find( stCertX );
+        
+        MiniDriverFiles::FILES_NAME::const_iterator itS = fs.find( stCertS );
+
+        if( ( itX != fs.end( ) ) || ( itS != fs.end( ) ) ) {
+
+            ++i;		
+            
+            continue;
+        }
+        
+        if( c.getKeyExchangeSizeBits( ) ) {
+
+            std::string stContainerExchangePublicKeyModulus;
+            Log::toString( c.getExchangePublicKeyModulus( )->GetBuffer( ), c.getExchangePublicKeyModulus( )->GetLength( ), stContainerExchangePublicKeyModulus );
+            Log::log( "MiniDriverContainerMapFile::containerGetMatching - container <%s>", stContainerExchangePublicKeyModulus.c_str( ) );
+ 
+            if( 0 == memcmp( p, c.getExchangePublicKeyModulus( )->GetBuffer( ), l ) ) {
+
+                bRet = true;
+
+                a_ucContainerIndex = i;
+
+                a_ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+
+                break;
+            }
+
+        } else if( c.getKeySignatureSizeBits( ) ) {
+
+            std::string stContainerSignaturePublicKeyModulus;
+            Log::toString( c.getSignaturePublicKeyModulus( )->GetBuffer( ), c.getSignaturePublicKeyModulus( )->GetLength( ), stContainerSignaturePublicKeyModulus );
+            Log::log( "MiniDriverContainerMapFile::containerGetMatching - container <%s>", stContainerSignaturePublicKeyModulus.c_str( ) );
+
+            if( 0 == memcmp( p, c.getSignaturePublicKeyModulus( )->GetBuffer( ), l ) ) {
+
+                bRet = true;
+
+                a_ucContainerIndex = i;
+
+                a_ucKeySpec = MiniDriverContainer::KEYSPEC_SIGNATURE;
+
+                break;            
+            }
+        }
+
+        ++i;		
+}
+
+    t.stop( "MiniDriverContainerMapFile::containerGetMatching" );
+    Log::end( "MiniDriverContainerMapFile::containerGetMatching" );
+
+    return bRet;
+}
+
+
+/*
+*/
+std::string MiniDriverContainerMapFile::computeContainerName( const unsigned char* a_pBuffer, const size_t& a_BufferLength ) {
+
+    // Hash the buffer
+    unsigned char hash[ 20 ];
+
+    memset( &hash[ 0 ], 0, sizeof( hash ) ) ;
+    
+    CSHA1 sha1;
+    
+    sha1.hashCore( const_cast< CK_BYTE_PTR >( a_pBuffer ), 0, static_cast< CK_LONG >( a_BufferLength ) );
+    
+    sha1.hashFinal( hash );
+
+
+    // Format a string from the hash
+    char name[ 40 ]; memset( name, 0, sizeof( name ) );
+
+    unsigned char* id = hash;
+
+    int i, n = 0;
+
+    char *c = name;
+
+    for( i = 0 ; i < 4 ; ++i ) {
+
+        sprintf( c, "%02x", id[ n ] );
+    
+        n++;
+        
+        c += 2;
+    }
+
+    sprintf(c,"-");
+
+    c++;
+
+    for( i = 0; i < 2 ; ++i ) {
+
+        sprintf( c, "%02x", id[ n ] );
+        
+        n++; 
+        
+        c += 2;
+    }
+
+    sprintf( c, "-" );
+    
+    c++;
+    
+    for( i = 0 ; i < 2 ; ++i ) {
+
+        sprintf( c, "%02x", id[ n ] );
+        
+        n++;
+        
+        c += 2;
+    }
+
+    sprintf( c, "-" );
+
+    c++;
+    
+    for( i = 0 ; i < 2 ; ++i ) {
+
+        sprintf( c, "%02x", id [ n ] );
+        
+        n++; 
+        
+        c += 2;
+    }
+
+    sprintf( c, "-" );
+    
+    c++;
+
+    for( i = 0 ; i < 6 ; ++i ) {
+
+        sprintf( c, "%02x", id[ n ] );
+
+        n++; 
+        
+        c += 2;
+    }
+
+    return std::string(name);
+}
+
+
+/*
+*/
+unsigned char MiniDriverContainerMapFile::containerGetFree( void ) {
+
+    unsigned char i = 0;
+    
+    bool bFound = false;
+
+    BOOST_FOREACH( MiniDriverContainer c, m_Containers ) {
+
+        if( MiniDriverContainer::CMAPFILE_FLAG_EMPTY == c.getFlags( ) ) {
+         
+            bFound = true;
+            break;
+        }
+
+        ++i;
+    }
+
+    if( !bFound ) {
+    
+        i = CONTAINER_INDEX_INVALID;
+    }
+
+    return i;
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverContainerMapFile.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,127 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_MINIDRIVER_CONTAINER_MAP_FILE__
+#define __GEMALTO_MINIDRIVER_CONTAINER_MAP_FILE__
+
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/serialization/array.hpp>
+#include <boost/array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <string>
+#include "MiniDriverContainer.hpp"
+#include "Array.hpp"
+#include "CardModuleService.hpp"
+
+
+const int g_MaxContainer = 15;
+
+
+class MiniDriverFiles;
+
+
+/*
+*/
+class MiniDriverContainerMapFile {
+
+public:
+
+    static unsigned char CONTAINER_INDEX_INVALID;
+
+    typedef boost::array< MiniDriverContainer, g_MaxContainer > ARRAY_CONTAINERS;
+
+    MiniDriverContainerMapFile( ) { }
+
+    inline void setMiniDriverFiles( MiniDriverFiles* p ) { m_MiniDriverFiles = p; }
+
+    void clear( void );
+
+    void containerDelete( const unsigned char& );
+
+    inline const MiniDriverContainer& containerGet( const unsigned char& a_ucContainerIndex ) { if( a_ucContainerIndex > m_Containers.size( ) ) { throw MiniDriverException( ); } return m_Containers[ a_ucContainerIndex ]; }
+
+    void containerSearch( unsigned char& );
+
+    inline const ARRAY_CONTAINERS& containerGet( void ) { return m_Containers; }
+
+    void containerRead( void );
+
+    void containerCreate( unsigned char&, const bool&, unsigned char&, Marshaller::u1Array*, const int&, Marshaller::u1Array* );
+
+    void containerSetDefault( const unsigned char&, const bool& );
+
+    bool containerGetMatching( unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec, const Marshaller::u1Array* a_pPublicKeyModulus );
+
+    inline unsigned char containerCount( void ) { return (unsigned char)m_Containers.size( ); }
+
+    inline void containerSetTypeForSignatureKey( const unsigned char& a_ucContainerIndex, const unsigned char& a_ContainerTypeForSignatureKey ) { m_Containers[ a_ucContainerIndex ].setContainerTypeForSignatureKey( a_ContainerTypeForSignatureKey ); }
+
+    inline void containerSetTypeForExchangeKey( const unsigned char& a_ucContainerIndex, const unsigned char& a_ContainerTypeForExchangeKey ) { m_Containers[ a_ucContainerIndex ].setContainerTypeForExchangeKey( a_ContainerTypeForExchangeKey ); }
+
+    inline void containerSetPinIdentifier( const unsigned char& a_ucContainerIndex, const MiniDriverAuthentication::ROLES& a_ContainerPinIdentifier ) { m_Containers[ a_ucContainerIndex ].setPinIdentifier( a_ContainerPinIdentifier ); }
+
+    inline bool containerIsImportedSignatureKey( const unsigned char& a_ucContainerIndex ) { return m_Containers[ a_ucContainerIndex ].isImportedSignatureKey( ); }
+
+    inline bool containerIsImportedExchangeKey( const unsigned char& a_ucContainerIndex ) { return m_Containers[ a_ucContainerIndex ].isImportedExchangeKey( ); }
+
+    inline MiniDriverAuthentication::ROLES containerGetPinIdentifier( const unsigned char& a_ucContainerIndex ) { return m_Containers[ a_ucContainerIndex ].getPinIdentifier( ); }
+
+    unsigned char containerGetFree( void );
+ 
+    void print( void );
+
+private:
+
+    std::string computeContainerName( const unsigned char* a_pBuffer, const size_t& a_BufferLength );
+
+    void write( void );
+
+    // Containers managed by the MiniDriver
+    ARRAY_CONTAINERS m_Containers;
+
+    Marshaller::u1Array m_ContainerMapFileBinary;
+
+    MiniDriverFiles* m_MiniDriverFiles;
+
+    // Disk serialization and deserialization
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+
+        //Log::begin( "MiniDriverContainerMapFile::serialize" );
+
+        ar & m_Containers;
+        //print( );
+
+        ar & m_ContainerMapFileBinary;
+        //Log::logCK_UTF8CHAR_PTR( "Container Map File Binary", m_ContainerMapFileBinary.GetBuffer( ), m_ContainerMapFileBinary.GetLength( ) );
+
+        //Log::end( "MiniDriverContainerMapFile::serialize" );
+    }
+
+};
+
+BOOST_CLASS_VERSION( MiniDriverContainerMapFile, 1 )
+
+
+#endif // __GEMALTO_CARD_CACHE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverException.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverException.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverException.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,53 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifndef __GEMALTO_MINIDRIVER_EXCEPTION__
+#define __GEMALTO_MINIDRIVER_EXCEPTION__
+
+
+#include <string>
+#include <stdexcept>
+#include "Log.hpp"
+
+
+/*
+*/
+class MiniDriverException : public std::runtime_error {
+
+public:
+    
+	inline MiniDriverException( ) : std::runtime_error( "MiniDriverException(1)" ), m_ulError( 0 ) { Log::log( " ============ MiniDriverException" ); }
+    
+    inline MiniDriverException( long a_ulError ) : std::runtime_error( "MiniDriverException(2)" ), m_ulError( a_ulError ) { Log::log( " ============ MiniDriverException - Error <%#02x>", m_ulError ); }
+    
+    inline MiniDriverException( const std::string& a_stMessage, long a_ulError = 0 ) : std::runtime_error( a_stMessage ), m_ulError( a_ulError ) {  Log::log( " ============ MiniDriverException - Error <%#02x> <%s>", m_ulError, a_stMessage.c_str( ) );}
+
+    inline MiniDriverException( const MiniDriverException& a_Exception ) : std::runtime_error( "MiniDriverException(3)" ), m_ulError( a_Exception.m_ulError ) {  Log::log( " ============ MiniDriverException - Error <%#02x>", m_ulError );}
+
+    inline unsigned long getError( void ) const { return m_ulError; }
+
+private:
+
+    long m_ulError;
+
+};
+
+#endif // __GEMALTO_MINIDRIVER_EXCEPTION__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,1016 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <boost/foreach.hpp>
+#include <fstream>
+#include <memory>
+#include "MiniDriverFiles.hpp"
+#include "MiniDriverException.hpp"
+#include "Log.hpp"
+#include "util.h"
+#include "Array.hpp"
+#include<boost/tokenizer.hpp>
+#include "Timer.hpp"
+#include "Device.hpp"
+
+#include "PCSCMissing.h"
+
+
+const int MAX_RETRY = 2;
+
+
+/* Constructor
+*/
+MiniDriverFiles::MiniDriverFiles( ) { 
+
+    m_ContainerMapFile.setMiniDriverFiles( this );
+
+    m_stPathCertificateRoot = szROOT_STORE_FILE;
+
+	s_stPathSeparator = "\\";
+
+	s_stPathMscp = szBASE_CSP_DIR;
+}
+
+
+/*
+*/
+void MiniDriverFiles::hasChanged( MiniDriverCardCacheFile::ChangeType& a_Pins, MiniDriverCardCacheFile::ChangeType& a_Containers, MiniDriverCardCacheFile::ChangeType& a_Files ) {
+
+    Log::begin( "MiniDriverFiles::hasChanged" );
+    Timer t;
+    t.start( );
+
+    try {
+
+        // Check if the smart card content read from the disk is still up to date
+        a_Pins = MiniDriverCardCacheFile::NONE;
+        a_Containers = MiniDriverCardCacheFile::NONE;
+        a_Files = MiniDriverCardCacheFile::NONE;
+        m_CardCacheFile.hasChanged( a_Pins, a_Containers, a_Files );
+
+        // Reset objects content if the cache has changed
+        if( MiniDriverCardCacheFile::NONE != a_Pins ) {
+        }
+
+        if( ( MiniDriverCardCacheFile::NONE != a_Containers ) || ( MiniDriverCardCacheFile::NONE != a_Files ) ) {
+
+            m_BinaryFiles.clear( );
+
+            m_Directories.clear( );
+
+            m_ContainerMapFile.clear( );
+
+            m_ContainerMapFile.containerRead( );
+        }
+
+    } catch( ... ) { }
+
+    t.stop( "MiniDriverFiles::hasChanged" );
+    Log::end( "MiniDriverFiles::hasChanged" );
+}
+
+
+/* Write the incoming data into the incoming pointed path into the smartcard and then into the cache
+*/
+void MiniDriverFiles::writeFile( const std::string& a_stDirectory, const std::string& a_stFile, Marshaller::u1Array* a_pData, const bool& a_bAddToCache, const bool& a_bUpdateContainerCounter ) {
+
+    Log::begin( "MiniDriverFiles::writeFile" );
+    Log::log( "MiniDriverFiles::writeFile - Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) );
+    Timer t;
+    t.start( );
+
+
+    int ntry = 0;
+
+    std::string stPath = a_stDirectory + s_stPathSeparator + a_stFile;
+
+    while( ntry < MAX_RETRY ) {
+
+        try {
+
+            ntry++;
+
+            // Write to the smart card
+            if( !m_CardModule ) {
+
+                throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+            }
+            m_CardModule->writeFile( (std::string*)&stPath, a_pData );
+
+            break;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "MiniDriverFiles::writeFile", "WriteFile failed" );
+
+            unsigned long ulError = x.getError( );
+
+            if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                // be re-tried with high chance of success.
+                if( ntry >= MAX_RETRY ) {
+
+                    m_BinaryFiles.erase( a_stFile );
+
+                    throw MiniDriverException( SCARD_E_NO_MEMORY );
+                }
+
+            } else {
+
+                throw MiniDriverException( x );
+            }
+        }
+    }
+
+    // Add the file to the directory cache
+    DIRECTORIES::iterator directoryIterator =  m_Directories.find( a_stDirectory );
+
+    if( directoryIterator != m_Directories.end( ) ) {
+
+        directoryIterator->second->insert( a_stFile );
+    } 
+
+    // Prepare the binary file content
+    Marshaller::u1Array* f = new Marshaller::u1Array( a_pData->GetLength( ) );
+    
+    f->SetBuffer( a_pData->GetBuffer( ) );
+
+    FILES_BINARY::iterator filesIterator = m_BinaryFiles.find( a_stFile );
+
+    if( filesIterator == m_BinaryFiles.end( ) ) {
+    
+        // Add the new file to the cache
+        std::string stFile = a_stFile;
+        m_BinaryFiles.insert( stFile, f );
+    
+    } else {
+    
+        // Update the new file to the cache
+        m_BinaryFiles[ a_stFile ] = *f;
+    }
+
+    m_CardCacheFile.notifyChange( MiniDriverCardCacheFile::FILES );
+
+    if( a_bUpdateContainerCounter ) {
+    
+        m_CardCacheFile.notifyChange( MiniDriverCardCacheFile::CONTAINERS );
+    }
+
+    std::string s = "";
+    Log::toString( a_pData->GetBuffer( ), a_pData->GetLength( ), s );
+    Log::log( "MiniDriverFiles::writeFile - path <%s> (Added to cache) - data <%s>", a_stFile.c_str( ), s.c_str( ) );
+
+    t.stop( "MiniDriverFiles::writeFile" );
+    Log::end( "MiniDriverFiles::writeFile" );
+}
+
+
+/*
+*/
+void MiniDriverFiles::cacheDisableWrite( void ) {
+
+    BOOST_FOREACH( const std::string& s, m_FilesToNotCache ) {
+        
+        m_BinaryFiles.erase( s );
+    }
+}
+
+
+/* Retreive the list of the files contained into the incoming directory path and returns a string vectors
+*/
+MiniDriverFiles::FILES_NAME & MiniDriverFiles::enumFiles( const std::string& a_stDirectory ) {
+
+    Log::begin( "MiniDriverFiles::enumFiles" );
+    Log::log( "MiniDriverFiles::enumFiles - Directory <%s>", a_stDirectory.c_str( ) );
+    Timer t;
+    t.start( );
+
+
+    // Log
+    std::string stFrom = "cache";
+
+    DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+
+    if( i == m_Directories.end( ) ) {
+
+        // Log
+        stFrom = "!! CARD !!";
+
+        int ntry = 0;
+
+        while( ntry < MAX_RETRY ) {
+
+            try {
+
+                ntry++;
+
+                // Read the directory files from the smart card
+                if( !m_CardModule ) {
+
+                    throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+                }
+                boost::shared_ptr< Marshaller::StringArray > f( m_CardModule->getFiles( (std::string*)&a_stDirectory ) );
+
+                // Fill the cache with the list of the files of this directory
+                size_t l = f->GetLength( );
+
+                // Create a new list of this directory files
+                FILES_NAME fs;
+
+                // Populate the list of files
+                for( u4 i = 0; i < l ; ++i ) {
+
+                    fs.insert( *(f->GetStringAt( i )) );
+                }
+
+                // Register the list of files into the list of directory
+                m_Directories[ a_stDirectory ] = fs;
+
+                break;
+
+            } catch( MiniDriverException& x ) {
+
+                Log::error( "MiniDriverFiles::enumFiles", "getFiles failed" );
+
+                unsigned long ulError = x.getError( );
+                if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                    // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                    // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                    // be re-tried with high chance of success.
+                    if( ntry >= MAX_RETRY ) {
+
+                        throw MiniDriverException( SCARD_E_NO_MEMORY );
+                    }
+
+                } else {
+
+                    throw MiniDriverException( x );
+                }
+            }
+        } 
+    }
+
+    // Log
+    std::string msg = "";
+    BOOST_FOREACH( const std::string& s, m_Directories[ a_stDirectory ] ) {
+
+        msg += s;
+        msg += " ";
+    }
+    Log::log( "MiniDriverFiles::enumFiles - path <%s> (Read from %s) - data <%s>", a_stDirectory.c_str( ), stFrom.c_str( ), msg.c_str( ) );
+
+    t.stop( "MiniDriverFiles::enumFiles" );
+    Log::end( "MiniDriverFiles::enumFiles" );
+
+    return m_Directories[ a_stDirectory ];
+}
+
+
+/* clearCache
+Remove elements from the cache according the required type
+*/
+void MiniDriverFiles::clear( const MiniDriverCardCacheFile::ChangeType& a_ChangeType ) {
+
+    if( MiniDriverCardCacheFile::NONE == a_ChangeType ) {
+
+        return;
+    }
+
+    // ??? TO DO ???
+    if( MiniDriverCardCacheFile::PINS == a_ChangeType ) {
+        
+        return;
+    }
+
+    if( MiniDriverCardCacheFile::FILES == a_ChangeType ) {
+
+        m_BinaryFiles.clear( );
+
+        m_Directories.clear( );
+    }
+
+    if( MiniDriverCardCacheFile::CONTAINERS == a_ChangeType ) {
+
+        std::string s( szCONTAINER_MAP_FILE );
+        m_BinaryFiles.erase( s );
+
+        m_ContainerMapFile.clear( );
+
+        m_ContainerMapFile.containerRead( );
+    }
+}
+
+
+/*
+*/
+void MiniDriverFiles::createDirectory( const std::string& a_stDirectoryParent, const std::string& a_stDirectory ) {
+
+    Log::begin( "MiniDriverFiles::createDirectory" );
+    Log::log( "MiniDriverFiles::createDirectory - Directory <%s>", a_stDirectory.c_str( ) );
+    Timer t;
+    t.start( );
+
+    if( !m_CardModule ) {
+
+        throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+    }
+
+    // Add first the current directory as a file owned by its parent directory
+    DIRECTORIES::const_iterator iteratorDirectoryParent = m_Directories.find( a_stDirectoryParent );
+    
+    if( iteratorDirectoryParent != m_Directories.end( ) ) {
+
+        ((FILES_NAME*)iteratorDirectoryParent->second)->insert( a_stDirectory );
+    }
+
+    // Add the current directory as also a stand alone directory
+    DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+
+    if( i == m_Directories.end( ) ) {
+
+        Marshaller::u1Array ac( 3 );
+
+        // Administrator access condition
+        ac.GetBuffer( )[ 0 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;
+
+        // User access condition
+        ac.GetBuffer( )[ 1 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;
+
+        // Everyone access condition
+        ac.GetBuffer( )[ 2 ] = CARD_PERMISSION_READ;
+
+        // Create directory into the smart card
+        int ntry = 0;
+        while( ntry < MAX_RETRY ) {
+
+            try {
+
+                ntry++;
+
+                // Create directory into the smart card
+                if( !m_CardModule ) {
+
+                    throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+                }
+                m_CardModule->createDirectory( (std::string*)&a_stDirectory, &ac );
+
+                break;
+
+            } catch( MiniDriverException& x ) {
+
+                Log::error( "MiniDriverFiles::createDirectory", "createDirectory failed" );
+
+                unsigned long ulError = x.getError( );
+                if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                    // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                    // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                    // be re-tried with high chance of success.
+                    if( ntry >= MAX_RETRY ) {
+
+                        throw MiniDriverException( SCARD_E_NO_MEMORY );
+                    }
+
+                } else {
+
+                    throw MiniDriverException( x );
+                }
+            }
+        }
+
+        // Add the directory into the directory cache
+        std::string s = a_stDirectory;
+        m_Directories.insert( s, new FILES_NAME );
+
+        // Update the minidriver cache file
+        m_CardCacheFile.notifyChange( MiniDriverCardCacheFile::FILES );
+    }
+
+    t.stop( "MiniDriverFiles::createDirectory" );
+    Log::end( "MiniDriverFiles::createDirectory" );
+}
+
+
+/*
+*/
+void MiniDriverFiles::createFile( const std::string& a_stDirectory, const std::string& a_stFile, Marshaller::u1Array* a_pAccessConditions ) {
+
+    Log::begin( "MiniDriverFiles::createFile" );
+    Log::log( "MiniDriverFiles::createFile - Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) );
+    Timer t;
+    t.start( );
+
+
+    // Build the full file path
+    std::string sFilePath = a_stDirectory + s_stPathSeparator + a_stFile;
+
+    // Create the file into the smart card file structure
+    int ntry = 0;
+    while( ntry < MAX_RETRY ) {
+
+        try {
+
+            ntry++;
+
+            // Create the file into the smart card file structure
+            if( !m_CardModule ) {
+
+                throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+            }
+            m_CardModule->createFile( (std::string*)&sFilePath, a_pAccessConditions, 0 );
+
+            break;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "MiniDriverFiles::createFile", "createFile failed" );
+
+            unsigned long ulError = x.getError( );
+
+            if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                // be re-tried with high chance of success.
+                if( ntry >= MAX_RETRY ) {
+
+                    throw MiniDriverException( SCARD_E_NO_MEMORY );
+                }
+
+            } else {
+
+                throw MiniDriverException( x );
+            }
+        }
+    }
+
+    // Add the file into the directory cache
+    DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+    if( i != m_Directories.end( ) ) {
+
+        ((FILES_NAME*)i->second)->insert( a_stFile );
+
+    } else {
+
+        // Add the directory into the directory cache
+        std::string s = a_stDirectory;
+        m_Directories.insert( s, new FILES_NAME );
+
+        // Add the file into the directory
+        DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+        ((FILES_NAME*)i->second)->insert( a_stFile );
+    }
+
+    // Prepare the binary file content
+    Marshaller::u1Array* f = new Marshaller::u1Array( 0 );
+
+    FILES_BINARY::iterator filesIterator = m_BinaryFiles.find( a_stFile );
+
+    if( filesIterator == m_BinaryFiles.end( ) ) {
+    
+        // Add the new file to the cache
+        std::string stFile = a_stFile;
+        m_BinaryFiles.insert( stFile, f );
+    
+    } else {
+    
+        // Update the new file to the cache
+        m_BinaryFiles[ a_stFile ] = *f;
+    }
+
+    // Update the minidriver cache file
+    m_CardCacheFile.notifyChange( MiniDriverCardCacheFile::FILES );
+
+    t.stop( "MiniDriverFiles::createFile" );
+    Log::end( "MiniDriverFiles::createFile" );
+}
+
+
+/*
+*/
+void  MiniDriverFiles::deleteFile( const std::string& a_stDirectory, const std::string& a_stFile ) { 
+
+    Log::begin( "MiniDriverFiles::deleteFile" );
+    Log::log( "MiniDriverFiles::deleteFile - Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) );
+    Timer t;
+    t.start( );
+
+    if( a_stFile.empty( ) ) {
+    
+        Log::error( "MiniDriverFiles::deleteFile", "no file name supplied" );
+        return;
+    }
+
+    std::string s = a_stDirectory + s_stPathSeparator + a_stFile; 
+
+    int ntry = 0;
+    while( ntry < MAX_RETRY ) {
+
+        try {
+
+            ntry++;
+
+            if( !m_CardModule ) {
+
+                throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+            }
+            m_CardModule->deleteFile( (std::string*)&s ); 
+
+            break;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "MiniDriverFiles::deleteFile", "deleteFile failed" );
+
+            unsigned long ulError = x.getError( );
+
+            if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                // be re-tried with high chance of success.
+                if( ntry >= MAX_RETRY ) {
+
+                    throw MiniDriverException( SCARD_E_NO_MEMORY );
+                }
+
+            } else {
+
+                throw MiniDriverException( x );
+            }
+        }
+    }
+
+    // Delete the file from the directory cache
+    DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+    
+    if( i != m_Directories.end( ) ) {
+        
+        if( i->second ) {
+        
+            ((FILES_NAME*)i->second)->erase( a_stFile );
+        }
+    }
+
+    // Delete the file from the binary file cache
+    m_BinaryFiles.erase( a_stFile ); 
+
+    for( std::vector< std::string >::iterator it = m_FilesToNotCache.begin( ); it != m_FilesToNotCache.end( ) ; ++it ) {
+
+        if( 0 == (*it).compare( a_stFile ) ) {
+        
+            m_FilesToNotCache.erase( it );
+            break;
+        }
+    }
+
+    // Update the minidriver cache file
+    m_CardCacheFile.notifyChange( MiniDriverCardCacheFile::FILES );
+
+    t.stop( "MiniDriverFiles::deleteFile" );
+    Log::end( "MiniDriverFiles::deleteFile" );
+}
+
+
+/*
+*/
+void MiniDriverFiles::deleteFileStructure( void ) {
+
+    Log::begin( "MiniDriverFiles::deleteFileStructure" );
+    Timer t;
+    t.start( );
+
+    std::string stCMapFile( szCONTAINER_MAP_FILE );
+    std::string stPath = "";
+    FILES_NAME fs = enumFiles( s_stPathMscp ); 
+    BOOST_FOREACH( const std::string& f, fs ) {
+
+        if( 0 == f.compare( stCMapFile ) ) {
+
+            continue;
+        }
+
+        deleteFile( s_stPathMscp, f );
+    }
+
+    t.stop( "MiniDriverFiles::deleteFileStructure" );
+    Log::end( "MiniDriverFiles::deleteFileStructure" );
+}
+
+
+/*
+*/
+void MiniDriverFiles::certificateDelete( unsigned char& a_ucContainerIndex ) {
+
+    Log::begin( "MiniDriver::certificateDelete" );
+    Timer t;
+    t.start( );
+
+    // Get the container information
+    MiniDriverContainer c = containerGet( a_ucContainerIndex );
+
+    if( c.empty( ) ) {
+
+        throw MiniDriverException( SCARD_E_NO_SUCH_CERTIFICATE );
+    }
+
+    // Build the certificate name to associate it to the container 
+    std::string stCertificateName = ( c.getKeyExchangeSizeBits( ) ? std::string ( szUSER_KEYEXCHANGE_CERT_PREFIX ) : std::string( szUSER_SIGNATURE_CERT_PREFIX ) );
+    Util::toStringHex( a_ucContainerIndex, stCertificateName );
+
+    // Delete the file
+    deleteFile( std::string( szBASE_CSP_DIR ) , stCertificateName );
+
+    t.stop( "MiniDriver::certificateDelete" );
+    Log::end( "MiniDriver::certificateDelete" );
+}
+
+
+/*
+*/
+bool MiniDriverFiles::containerGetMatching( unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec, std::string& a_stFileName, const Marshaller::u1Array* a_pPublicKeyModulus ) {
+
+    bool bRet = m_ContainerMapFile.containerGetMatching( a_ucContainerIndex, a_ucKeySpec, a_pPublicKeyModulus );
+
+    // Build the public key name to associate it to the container 
+    if( bRet ) {
+
+        // Add the same as associated certificate prefix
+        a_stFileName = ( a_ucKeySpec ? std::string ( szUSER_KEYEXCHANGE_CERT_PREFIX ) : std::string( szUSER_SIGNATURE_CERT_PREFIX ) );
+
+        // Add the index
+        Util::toStringHex( a_ucContainerIndex, a_stFileName );
+    }
+
+    return bRet;
+}
+
+
+/*
+*/
+void MiniDriverFiles::renameFile( const std::string& a_stOldFileDirectory, const std::string& a_stOldFileName, const std::string& a_stNewFileDirectory, const std::string& a_stNewFileName ) {
+
+    // First read the old file
+    Marshaller::u1Array* p = readFile( a_stOldFileDirectory, a_stOldFileName );
+
+    // Compute the access conditions for the new file
+    Marshaller::u1Array ac( 3 );
+
+    // Administrator access condition
+    ac.GetBuffer( )[ 0 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;
+
+    // User access condition
+    ac.GetBuffer( )[ 1 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;
+
+    // Everyone access condition
+    ac.GetBuffer( )[ 2 ] = CARD_PERMISSION_READ;
+
+    // Create the new file
+    createFile( a_stNewFileDirectory, a_stNewFileName, &ac );
+
+    // Write the new file
+    writeFile( a_stNewFileDirectory, a_stNewFileName, p );
+
+    // Delete the old file
+  	deleteFile( a_stOldFileDirectory, a_stOldFileName );
+}
+
+
+void MiniDriverFiles::print( void ) {
+
+    Log::begin( "MiniDriverFiles::print" );
+
+    m_ContainerMapFile.print( );
+    
+    std::string stFileContent;
+    for( FILES_BINARY::const_iterator i = m_BinaryFiles.begin( ) ; i != m_BinaryFiles.end( ) ; ++i ) {
+    
+        stFileContent = "";
+        Log::toString( i->second->GetBuffer( ), i->second->GetLength( ), stFileContent );
+        Log::log( "Binary files <%s> <%s>", i->first.c_str( ), stFileContent.c_str( ) );
+    }
+
+    std::string s = "";
+    for( DIRECTORIES::const_iterator i = m_Directories.begin( ) ; i != m_Directories.end( ) ; ++i ) {
+        s = "";
+        for( FILES_NAME::iterator j = i->second->begin( ); j != i->second->end( ); ++j ) {
+            s += *j;
+            s += " ";
+        }
+        Log::log( "Directories <%s> - Files <%s>", i->first.c_str( ), s.c_str( ) );
+    }
+
+    m_CardCacheFile.print( );
+    s = "";
+    for( std::vector< std::string >::const_iterator i = m_FilesToNotCache.begin( ) ; i != m_FilesToNotCache.end( ) ; ++i ) {
+    
+        s += (*i);
+        s += " ";
+    }
+    Log::log( "FilesToNotCache <%s>", s.c_str( ) );
+
+    Log::end( "MiniDriverFiles::print" );
+}
+
+
+/*
+*/
+unsigned char MiniDriverFiles::containerGetFreeRoot( void ) {
+
+    // Scan the mscp directory to find a free root index
+    std::string a_stDirectory( szBASE_CSP_DIR );
+
+    MiniDriverFiles::FILES_NAME f = enumFiles( a_stDirectory );
+
+    unsigned char ucContainerMax = m_ContainerMapFile.containerCount( );
+
+    unsigned char ucIndexMax = 0;
+    
+    unsigned char ucIndexCourant = 0;
+
+    BOOST_FOREACH( const std::string& v, f ) {
+    
+        if( v.substr( 0, 3).compare( "kxc" ) ) {
+        
+            continue;
+        }
+
+        ucIndexCourant = computeIndex( v );
+
+        if( ucIndexCourant > ucIndexMax ) {
+         
+            ucIndexMax = ucIndexCourant;
+        }
+    }
+
+    if( ucIndexMax <= ucContainerMax ) {
+
+        ucIndexMax = ucContainerMax;
+    }
+    ++ucIndexMax;
+
+    return ucIndexMax;
+}
+
+
+/*
+*/
+unsigned char MiniDriverFiles::computeIndex( const std::string& a_stFileName ) {
+
+    // Get the container index set into the file name
+    unsigned char h1 = a_stFileName[ a_stFileName.length( ) - 2 ];
+    unsigned char h2 = a_stFileName[ a_stFileName.length( ) - 1 ];
+
+    unsigned char a = ( ( h1 >= 0x41 ) ? ( h1 - 0x41 + 10 ) : ( h1 - 0x30 ) ) * 16;
+    unsigned char b = ( h2 >= 0x41 ) ? ( h2 - 0x41 + 10 ) : ( h2 - 0x30 );
+
+    unsigned char ucKeyContainerIndexInFileName = a + b;
+
+    return ucKeyContainerIndexInFileName;
+}
+
+
+/*
+*/
+Marshaller::u1Array* MiniDriverFiles::readFileWithoutCheck( const std::string& a_stDirectory, const std::string& a_stFile ) {
+
+    Log::begin( "MiniDriverFiles::readFileWithoutCheck" );
+    Log::log( "MiniDriverFiles::readFileWithoutCheck - Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) );
+    Timer t;
+    t.start( );
+
+    Marshaller::u1Array* f = NULL;
+
+    int ntry = 0;
+
+    std::string stPath = a_stDirectory + s_stPathSeparator + a_stFile;
+    if( a_stDirectory.empty( ) ) {
+
+        stPath = a_stFile;
+    }
+
+    while( ntry < MAX_RETRY ) {
+
+        try {
+
+            ntry++;
+
+            if( !m_CardModule ) {
+
+                throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+            }
+
+            f = m_CardModule->readFileWithoutMemoryCheck( (std::string*)&stPath );
+            
+            break;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "MiniDriverFiles::readFileWithoutCheck", "readFile failed" );
+
+            unsigned long ulError = x.getError( );
+
+            if ( SCARD_E_COMM_DATA_LOST == ulError ) {
+            
+                if( ntry >= MAX_RETRY ) {
+
+                    throw MiniDriverException( SCARD_E_COMM_DATA_LOST );
+                }
+
+            } else if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                // be re-tried with high chance of success.
+                if( ntry >= MAX_RETRY ) {
+
+                    throw MiniDriverException( SCARD_E_NO_MEMORY );
+                }
+
+            } else if( SCARD_E_FILE_NOT_FOUND == ulError ) {
+
+                // Delete the file from the directory cache
+                DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+
+                if( i != m_Directories.end( ) ) {
+
+                    if( i->second ) {
+
+                        ((FILES_NAME*)i->second)->erase( a_stFile );
+                    }
+                }
+
+                // Delete the file from the binary file cache
+                m_BinaryFiles.erase( a_stFile ); 
+
+                for( std::vector< std::string >::iterator it = m_FilesToNotCache.begin( ); it != m_FilesToNotCache.end( ) ; ++it ) {
+
+                    if( 0 == (*it).compare( a_stFile ) ) {
+
+                        m_FilesToNotCache.erase( it );
+                        break;
+                    }
+                }
+            }
+
+            throw MiniDriverException( x );
+        }
+    }
+
+    // Log
+    if( f ) {
+    
+        std::string s = "";
+    
+        Log::toString( f->GetBuffer( ), f->GetLength( ), s );
+    
+        Log::log( "MiniDriverFiles::readFileWithoutCheck - path <%s> - data <%s>", a_stFile.c_str( ), s.c_str( ) );
+    }
+
+    t.stop( "MiniDriverFiles::readFileWithoutCheck" );
+    Log::end( "MiniDriverFiles::readFileWithoutCheck" );
+
+    return f;
+}
+
+
+/* ReadFile
+*/
+Marshaller::u1Array* MiniDriverFiles::readFile( const std::string& a_stDirectory, const std::string& a_stFile ) {
+
+    Log::begin( "MiniDriverFiles::readFile" );
+    Log::log( "MiniDriverFiles::readFile - Directory <%s> - File <%s>", a_stDirectory.c_str( ), a_stFile.c_str( ) );
+    Timer t;
+    t.start( );
+
+    // Log
+    std::string stFrom = "cache"; 
+
+    FILES_BINARY::const_iterator i = m_BinaryFiles.find( a_stFile );
+
+    if( i == m_BinaryFiles.end( ) ) {
+
+        //Log
+        stFrom = "!! CARD !!"; 
+
+        int ntry = 0;
+
+        std::string stPath = a_stDirectory + s_stPathSeparator + a_stFile;
+
+        while( ntry < MAX_RETRY ) {
+
+            try {
+
+                ntry++;
+
+                 if( !m_CardModule ) {
+
+                    throw MiniDriverException( SCARD_E_NO_SMARTCARD );
+                }
+               Marshaller::u1Array* f = m_CardModule->readFile( (std::string*)&stPath );
+
+                // Store the binary file content
+                FILES_BINARY::iterator filesIterator = m_BinaryFiles.find( a_stFile );
+
+                if( filesIterator == m_BinaryFiles.end( ) ) {
+    
+                    // Add the new file to the cache
+                    std::string stFile = a_stFile;
+                    m_BinaryFiles.insert( stFile, f );
+    
+                } else {
+    
+                    // Update the new file to the cache
+                    m_BinaryFiles[ a_stFile ] = *f;
+                }
+
+                break;
+
+            } catch( MiniDriverException& x ) {
+
+                Log::error( "MiniDriverFiles::readFile", "readFile failed" );
+
+                unsigned long ulError = x.getError( );
+            if ( SCARD_E_COMM_DATA_LOST == ulError ) {
+            
+                if( ntry >= MAX_RETRY ) {
+
+                    throw MiniDriverException( SCARD_E_COMM_DATA_LOST );
+                }
+
+            } else if ( SCARD_E_NO_MEMORY == ulError ) {
+
+                    // V2+ cards may throw OutOfMemoryException from ReadFile, however it may recover from this by forcing the garbage collection to
+                    // occur. In fact as a result of a ReadFile command that throws OutOfMemoryException, GC has already occured, so the command may
+                    // be re-tried with high chance of success.
+                    if( ntry >= MAX_RETRY ) {
+
+                        throw MiniDriverException( SCARD_E_NO_MEMORY );
+                    }
+
+                } else {
+
+                    if( SCARD_E_FILE_NOT_FOUND == ulError ) {
+                    
+                        // Delete the file from the directory cache
+                        DIRECTORIES::const_iterator i = m_Directories.find( a_stDirectory );
+    
+                        if( i != m_Directories.end( ) ) {
+        
+                            if( i->second ) {
+        
+                                ((FILES_NAME*)i->second)->erase( a_stFile );
+                            }
+                        }
+
+                        // Delete the file from the binary file cache
+                        m_BinaryFiles.erase( a_stFile ); 
+
+                        for( std::vector< std::string >::iterator it = m_FilesToNotCache.begin( ); it != m_FilesToNotCache.end( ) ; ++it ) {
+
+                            if( 0 == (*it).compare( a_stFile ) ) {
+        
+                                m_FilesToNotCache.erase( it );
+                                break;
+                            }
+                        }
+                    }
+
+                    throw MiniDriverException( x );
+                }
+            }
+        }
+    }
+
+    // Log
+    std::string s = "";
+    Log::toString( m_BinaryFiles[ a_stFile ].GetBuffer( ), m_BinaryFiles[ a_stFile ].GetLength( ), s );
+    Log::log( "MiniDriverFiles::readFile - path <%s> (Read from %s) - data <%s>", a_stFile.c_str( ), stFrom.c_str( ), s.c_str( ) );
+
+    t.stop( "MiniDriverFiles::readFile" );
+    Log::end( "MiniDriverFiles::readFile" );
+
+    return &m_BinaryFiles[ a_stFile ];
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverFiles.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,192 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_CARD_CACHE__
+#define __GEMALTO_CARD_CACHE__
+
+
+#include <boost/ptr_container/serialize_ptr_map.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/serialization/string.hpp>
+#include <boost/serialization/vector.hpp>
+#include <boost/serialization/set.hpp>
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/array.hpp>
+#include <map>
+#include <string>
+#include <set>
+#include "CardModuleService.hpp"
+#include "MiniDriverCardCacheFile.hpp"
+#include "MiniDriverContainerMapFile.hpp"
+#include "Except.h"
+
+
+/*
+*/
+class MiniDriverFiles {
+
+public:
+
+    typedef std::set< std::string > FILES_NAME;
+
+    typedef boost::ptr_map< std::string, Marshaller::u1Array > FILES_BINARY;
+
+    typedef boost::ptr_map< std::string, FILES_NAME > DIRECTORIES;
+
+    typedef enum { CARD_PERMISSION_READ = 0x04, CARD_PERMISSION_WRITE = 0x02, CARD_PERMISSION_EXECUTE = 0x01 } PERMISSIONS;
+
+    MiniDriverFiles( );
+
+    inline CardModuleService* const getCardModuleService( void ) { return m_CardModule; }
+
+    inline void setCardModuleService( CardModuleService* a_pCardModule ) { m_CardModule = a_pCardModule; m_CardCacheFile.setCardModuleService( m_CardModule ); }
+
+
+    // Files operations
+    void certificateDelete( unsigned char& );
+
+    void writeFile( const std::string&, const std::string&, Marshaller::u1Array*, const bool& a_bAddToCache = true, const bool& a_bUpdateContainerCounter = false );
+
+    void deleteFile( const std::string&, const std::string& );
+
+    void createFile( const std::string&, const std::string&, Marshaller::u1Array* );
+
+    Marshaller::u1Array* readFile( const std::string&, const std::string& );
+
+    Marshaller::u1Array* readFileWithoutCheck( const std::string&, const std::string& );
+
+    void clearFile( std::string const & );
+
+    FILES_NAME& enumFiles( const std::string& );
+
+    void createDirectory( const std::string&, const std::string& );
+
+    void deleteFileStructure( void );
+
+    void renameFile( const std::string& a_stOldFileDirectory, const std::string& a_stOldFileName, const std::string& a_stNewFileDirectory, const std::string& a_stNewFileName );
+
+
+    // Container operations
+    inline const MiniDriverContainer& containerGet( const unsigned char& a_ucContainerIndex ) { return m_ContainerMapFile.containerGet( a_ucContainerIndex ); }
+
+    inline const MiniDriverContainerMapFile::ARRAY_CONTAINERS& containerGet( void ) { return m_ContainerMapFile.containerGet( ); }
+
+    inline void containerSearch( unsigned char& a_ucContainerIndex ) { m_ContainerMapFile.containerSearch( a_ucContainerIndex ); }
+
+    inline void containerCreate( unsigned char& a_ucContainerIndex, const bool& a_bKeyImport, unsigned char& a_ucKeySpec, Marshaller::u1Array* a_pPublicKeyModulus, const int& a_KeySize, Marshaller::u1Array* a_pKeyValue ) { m_ContainerMapFile.containerCreate( a_ucContainerIndex, a_bKeyImport, a_ucKeySpec, a_pPublicKeyModulus, a_KeySize, a_pKeyValue ); }
+
+    void containerDelete( const unsigned char& a_ucContainerIndex ) { m_ContainerMapFile.containerDelete( a_ucContainerIndex ); }
+
+    const MiniDriverContainer& containerRead( const int& );
+
+    inline void containerSetDefault( const unsigned char& a_ucContainerIndex, const bool& a_bIsSmartCardLogon ) { m_ContainerMapFile.containerSetDefault( a_ucContainerIndex, a_bIsSmartCardLogon ); }
+
+    inline unsigned char containerCount( void ) { return m_ContainerMapFile.containerCount( ); }
+
+    bool containerGetMatching( unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec, std::string& a_stFileName, const Marshaller::u1Array* a_pPublicKeyModulus );
+
+    inline bool containerIsImportedExchangeKey( const unsigned char& a_ucContainerIndex ) { return m_ContainerMapFile.containerIsImportedExchangeKey( a_ucContainerIndex ); }
+
+    inline bool containerIsImportedSignatureKey( const unsigned char& a_ucContainerIndex ) { return m_ContainerMapFile.containerIsImportedSignatureKey( a_ucContainerIndex ); }
+
+    inline unsigned char containerGetFree( void ) { return m_ContainerMapFile.containerGetFree( ); }
+
+    unsigned char containerGetFreeRoot( void );
+
+
+    // Cache operations
+    void clear( const MiniDriverCardCacheFile::ChangeType& );
+
+    void serialize( void );
+
+    void deserialize( void );
+
+    //inline void hasChanged( MiniDriverCardCacheFile::ChangeType& a_Pins, MiniDriverCardCacheFile::ChangeType& a_Containers, MiniDriverCardCacheFile::ChangeType& a_Files ) { m_CardCacheFile.hasChanged( a_Pins, a_Containers, a_Files ); }
+    void hasChanged( MiniDriverCardCacheFile::ChangeType& a_Pins, MiniDriverCardCacheFile::ChangeType& a_Containers, MiniDriverCardCacheFile::ChangeType& a_Files );
+
+    inline void notifyChange( const MiniDriverCardCacheFile::ChangeType& a_change ) { m_CardCacheFile.notifyChange( a_change ); }
+
+    inline void cacheDisable( const std::string& a_stFileName ) { m_FilesToNotCache.insert( m_FilesToNotCache.begin( ), a_stFileName ); }
+
+    void cacheDisableWrite( void );
+
+    void print( void );
+
+private:
+
+    std::string s_stPathSeparator;
+
+    std::string s_stPathMscp;
+
+    std::string m_stPathCertificateRoot;
+
+    // Service to access the oncard MiniDriver
+    CardModuleService* m_CardModule;
+
+    // Reflect the state of the Container Map File (CMapFile)
+    MiniDriverContainerMapFile m_ContainerMapFile;
+
+    // Reflect the binary content of the files in the smart card
+    FILES_BINARY m_BinaryFiles;
+
+    // Reflect the list of files contained by a directory into the smart card
+    DIRECTORIES m_Directories;
+
+    // Reflects state of card cache file (CardCF)
+    MiniDriverCardCacheFile m_CardCacheFile;
+
+    unsigned long checkException( Marshaller::Exception &x );
+
+    std::vector< std::string > m_FilesToNotCache;
+
+    unsigned char computeIndex( const std::string& );
+
+    //////
+    // Disk cache management
+    //////
+
+    // On computer disk serialization and deserialization
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+
+        //Log::begin( "MiniDriverFiles::serialize" );
+
+        ar & m_ContainerMapFile;
+
+        ar & m_BinaryFiles;
+
+        ar & m_Directories;
+
+        ar & m_CardCacheFile;
+
+        ar & m_FilesToNotCache;
+
+        //Log::end( "MiniDriverFiles::serialize" );
+    }
+
+};
+
+BOOST_CLASS_VERSION( MiniDriverFiles, 1 )
+
+#endif // __GEMALTO_CARD_CACHE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,123 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <memory>
+#include "MiniDriverPinPolicy.hpp"
+#include "MiniDriverException.hpp"
+#include "Log.hpp"
+
+
+const unsigned char CP_CARD_PIN_POLICY = 0x80;
+
+
+/*
+*/
+void MiniDriverPinPolicy::write( void ) { 
+    
+    Marshaller::u1Array b( g_PolicyLenght );
+
+    b.SetBuffer( m_ucaPinPolicy.c_array( ) );
+
+    try {
+
+        m_CardModule->setCardProperty( CP_CARD_PIN_POLICY, &b, m_ucRole );
+    
+    } catch( MiniDriverException& ) {
+    
+            Log::error( "MiniDriverPinPolicy::write", "setCardProperty 0x80 failed" );
+
+        // PIN policy not supported
+        //m_ucaPinPolicy.fill( 0 );
+    }
+}
+
+    
+/*
+*/
+void MiniDriverPinPolicy::read( void ) { 
+    
+    std::auto_ptr< Marshaller::u1Array > b;
+
+    try {
+
+        b.reset( m_CardModule->getCardProperty( CP_CARD_PIN_POLICY, m_ucRole ) );
+    
+        if( b.get( ) ) {
+
+            memcpy( m_ucaPinPolicy.c_array( ), b->GetBuffer( ), m_ucaPinPolicy.size( ) );
+        }
+
+    } catch( MiniDriverException& ) {
+
+        Log::error( "MiniDriverPinPolicy::read", "getCardProperty 0x80 failed" );
+
+        // PIN policy not supported
+        reset( );
+    }
+}
+
+
+/*
+*/
+void MiniDriverPinPolicy::print( void ) {
+
+   unsigned char a_ucParameterValue = get( PARAMETER_KEY_MAX_ATTEMPS );
+   Log::log( "PARAMETER_KEY_MAX_ATTEMPS <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_MIN_LENGTH );
+   Log::log( "PARAMETER_KEY_MIN_LENGTH <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_MAX_LENGTH );
+   Log::log( "PARAMETER_KEY_MAX_LENGTH <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_CHAR_SET );
+   Log::log( "PARAMETER_KEY_CHAR_SET <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_COMPLEXITY_RULE_1 );
+   Log::log( "PARAMETER_KEY_COMPLEXITY_RULE_1 <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_COMPLEXITY_RULE_2 );
+   Log::log( "PARAMETER_KEY_COMPLEXITY_RULE_2 <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_ADJACENT_ALLOWED );
+   Log::log( "PARAMETER_KEY_ADJACENT_ALLOWED <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_HISTORY );
+   Log::log( "PARAMETER_KEY_HISTORY <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_ALLOW_UNBLOCK );
+   Log::log( "PARAMETER_KEY_ALLOW_UNBLOCK <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_ALLOW_SSO );
+   Log::log( "PARAMETER_KEY_ALLOW_SSO <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_ONE_OF_EACH_CHAR_SET );
+   Log::log( "PARAMETER_KEY_ONE_OF_EACH_CHAR_SET <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_MANDATORY_CHAR_SET );
+   Log::log( "PARAMETER_KEY_MANDATORY_CHAR_SET <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_MAX_SEQUENCE_LEN );
+   Log::log( "PARAMETER_KEY_MAX_SEQUENCE_LEN <%#02x>", a_ucParameterValue );
+
+   a_ucParameterValue = get( PARAMETER_KEY_MAX_ADJACENT_NB );
+   Log::log( "PARAMETER_KEY_MAX_ADJACENT_NB <%#02x>", a_ucParameterValue );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MiniDriverPinPolicy.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,135 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_PIN_POLICY__
+#define __GEMALTO_PIN_POLICY__
+
+
+#include <boost/serialization/serialization.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/array.hpp>
+#include <boost/array.hpp>
+#include <boost/foreach.hpp>
+#include <memory>
+#include "CardModuleService.hpp"
+
+
+const unsigned char g_PolicyLenght = 14;
+const unsigned char PARAMETER_KEY_MAX_ATTEMPS  = 0;
+const unsigned char PARAMETER_KEY_MIN_LENGTH  = 1;
+const unsigned char PARAMETER_KEY_MAX_LENGTH  = 2;
+const unsigned char PARAMETER_KEY_CHAR_SET  = 3;
+const unsigned char PARAMETER_KEY_COMPLEXITY_RULE_1  = 4;
+const unsigned char PARAMETER_KEY_COMPLEXITY_RULE_2  = 5;
+const unsigned char PARAMETER_KEY_ADJACENT_ALLOWED = 6;
+const unsigned char PARAMETER_KEY_HISTORY = 7;
+const unsigned char PARAMETER_KEY_ALLOW_UNBLOCK = 8;
+const unsigned char PARAMETER_KEY_ALLOW_SSO = 9;
+const unsigned char PARAMETER_KEY_ONE_OF_EACH_CHAR_SET = 10;
+const unsigned char PARAMETER_KEY_MANDATORY_CHAR_SET = 11;
+const unsigned char PARAMETER_KEY_MAX_SEQUENCE_LEN = 12;
+const unsigned char PARAMETER_KEY_MAX_ADJACENT_NB = 13;
+
+
+/*
+*/
+class MiniDriverPinPolicy {
+
+public:
+
+    MiniDriverPinPolicy( ) { reset( ); }
+
+    inline void setCardModuleService( CardModuleService* a_pCardModule ) { m_CardModule = a_pCardModule; }
+
+    inline void setRole( unsigned char const &a_ucRole ) { m_ucRole = a_ucRole; }
+
+    void read( void );
+
+    inline const unsigned char& getMaxAttemps( void ) { return get( PARAMETER_KEY_MAX_ATTEMPS ); }
+
+    inline const unsigned char& getPinMinLength( void ) { return get( PARAMETER_KEY_MIN_LENGTH ); }
+
+    inline const unsigned char& getPinMaxLength(  void ) { return get( PARAMETER_KEY_MAX_LENGTH ); }
+
+    inline const unsigned char& getCharSet( void ) { return get( PARAMETER_KEY_CHAR_SET ); }
+
+    inline const unsigned char& getComplexityRule1( void ) { return get( PARAMETER_KEY_COMPLEXITY_RULE_1 ); }
+
+    inline const unsigned char& getComplexityRule2( void ) { return get( PARAMETER_KEY_COMPLEXITY_RULE_2 ); }
+
+    inline const unsigned char& getAdjacentAllowed( void ) { return get( PARAMETER_KEY_ADJACENT_ALLOWED ); }
+
+    inline const unsigned char& getHistory( void ) { return get( PARAMETER_KEY_HISTORY ); }
+
+    inline const unsigned char& getAllowUnblock( void ) { return get( PARAMETER_KEY_ALLOW_UNBLOCK ); }
+
+    inline const unsigned char& getAllowSSO( void ) { return get( PARAMETER_KEY_ALLOW_SSO ); }
+
+    inline const unsigned char& getOneCharForEachCharSet( void ) { return get( PARAMETER_KEY_ONE_OF_EACH_CHAR_SET ); }
+
+    inline const unsigned char& getMandatoryCharSet( void ) { return get( PARAMETER_KEY_MANDATORY_CHAR_SET ); }
+
+    inline const unsigned char& getMaxSequenceLen( void ) { return get( PARAMETER_KEY_MAX_SEQUENCE_LEN ); }
+
+    inline const unsigned char& getMaxAdjacent( void ) { return get( PARAMETER_KEY_MAX_ADJACENT_NB ); }
+
+    inline bool empty( void ) { BOOST_FOREACH( unsigned char& e, m_ucaPinPolicy ) { if( e ) { return false; } } return true; }
+
+    void print( void );
+
+    friend class boost::serialization::access;
+
+    template< class Archive > void serialize( Archive &ar, const unsigned int /*version*/ ) {
+
+        //Log::begin( "MiniDriverPinPolicy::serialize" );
+
+        ar & m_ucRole;
+
+        ar & m_ucaPinPolicy;
+
+        //Log::log( "Role <%ld>", m_ucRole );
+        //Log::logCK_UTF8CHAR_PTR( "Pin policy", m_ucaPinPolicy.c_array( ), m_ucaPinPolicy.size( ) );
+        //Log::end( "MiniDriverPinPolicy::serialize" );
+    }
+
+protected:
+
+    inline void reset( void ) { memset( m_ucaPinPolicy.c_array( ), 0, sizeof( m_ucaPinPolicy ) ); }
+
+    inline void set( unsigned char const & a_ucParameterIndex, unsigned char const & a_ucParameterValue ) { m_ucaPinPolicy[ a_ucParameterIndex ] = a_ucParameterValue; }
+
+    inline unsigned char & get( unsigned char const &a_ucParameterIndex ) { return m_ucaPinPolicy[ a_ucParameterIndex ]; }
+
+    void write( void );
+
+    CardModuleService* m_CardModule;
+
+    boost::array< unsigned char, g_PolicyLenght > m_ucaPinPolicy;
+
+    unsigned char m_ucRole;
+
+};
+
+
+BOOST_CLASS_VERSION( MiniDriverPinPolicy, 1 )
+
+
+#endif // __GEMALTO_PIN_POLICY__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Module.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Module.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Module.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,35 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifdef WIN32
+
+#include <Windows.h>
+
+
+BOOL APIENTRY DllMain( HANDLE /*hModule*/,
+                       DWORD  /*ul_reason_for_call*/,
+                       LPVOID /*lpReserved*/
+                     )
+{
+    return TRUE;
+}
+
+#endif

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,22 +1,22 @@
 /*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
 
 #ifdef WIN32
 #include <Windows.h>
@@ -29,7 +29,12 @@
 #ifdef __APPLE__
 #include <PCSC/wintypes.h>
 #include <PCSC/winscard.h>
-#else
+
+#ifdef MACOSX_LEOPARD
+#define SCardIsValidContext(x) SCARD_S_SUCCESS
+#endif
+
+#else 
 #include <winscard.h>
 #endif
 
@@ -39,28 +44,23 @@
 #include <string.h>
 #include <stdexcept>
 #include "MarshallerCfg.h"
-#include "Array.h"
+#include "Array.hpp"
 #include "PCSC.h"
 #include "Except.h"
 
-
 #ifdef __sun
 typedef LPSTR LPTSTR;
 #endif
 
-// JCD
-#include "log.h"
+#include "Log.hpp"
+#include "Timer.hpp"
 
 
-
 MARSHALLER_NS_BEGIN
 
-extern u4 CheckForException(u1Array answer, u4 nameSpace, u2 type);
-extern u4 ComReadU4At(u1Array &array, u4 pos);
-
 #define SUPPORT_BETA_VERSION
 
-const u1 isNetCardAPDU[] = {0x80,0xC2,0x00,0x00,0x1C,0xD8,0x00,0x01,0x6F,0x00,0xF5,0xEF,0xBF,0xB1,0x8C,0xDD,0xC2,0x00,0x0E,0x43,0x6F,0x6E,0x74,0x65,0x6E,0x74,0x4D,0x61,0x6E,0x61,0x67,0x65,0x72};
+    const u1 isNetCardAPDU[] = {0x80,0xC2,0x00,0x00,0x1C,0xD8,0x00,0x01,0x6F,0x00,0xF5,0xEF,0xBF,0xB1,0x8C,0xDD,0xC2,0x00,0x0E,0x43,0x6F,0x6E,0x74,0x65,0x6E,0x74,0x4D,0x61,0x6E,0x61,0x67,0x65,0x72};
 
 #define APDU_TO_CARD_MAX_SIZE                                                       0xFF
 #define CARDMANAGER_SERVICE_PORT                                                    1
@@ -73,487 +73,544 @@
 #define HIVECODE_TYPE_SYSTEM_INT32                                                  0x61C0
 
 
-// *******************
-// PCSC class
-// *******************
-PCSC::PCSC(M_SAL_IN std::string* readerName)
-{
-   DWORD activeProtocol;
-   LONG lReturn;
+/*
+*/
+PCSC::PCSC( std::string& a_stReaderName ) {
 
-   this->hContext      = 0;
-   this->hCard	        = 0;
+    m_hContextPCSC = 0;
 
-   lReturn = SCardEstablishContext(0, NULL, NULL, &this->hContext);
-   if(lReturn != SCARD_S_SUCCESS) {
-      throw RemotingException((lpCharPtr)"PCSC: SCardEstablishContext error",lReturn);
-   }
+    m_hCardPCSC = 0;
 
-   lReturn = SCardConnect(this->hContext, (LPTSTR)readerName->c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &this->hCard, &activeProtocol);
-   if (lReturn != SCARD_S_SUCCESS) {
-      throw RemotingException((lpCharPtr)"PCSC: SCardConnect error",lReturn);
-   }
+    m_bDoTransact = true;
 
-   this->readerName = new std::string(readerName->c_str());
+    LONG lReturn = SCardEstablishContext( 0, NULL, NULL, &m_hContextPCSC );
+
+    if( SCARD_S_SUCCESS != lReturn ) {
+
+        Log::log( "PCSC::PCSC - SCardEstablishContext <%#02x>", lReturn );
+
+        throw RemotingException( "PCSC::PCSC - SCardEstablishContext error", lReturn );
+    }
+
+    DWORD dwActiveProtocol = SCARD_PROTOCOL_T0;
+
+    lReturn = SCardConnect( m_hContextPCSC, (LPTSTR)a_stReaderName.c_str( ), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &m_hCardPCSC, &dwActiveProtocol );
+
+    if( SCARD_S_SUCCESS != lReturn ) {
+
+        Log::log( "PCSC::PCSC - SCardConnect <%#02x>", lReturn );
+
+        throw RemotingException( (lpCharPtr)"PCSC: SCardConnect error", lReturn );
+    }
+
+    m_stReaderName = a_stReaderName;
 }
 
-PCSC::PCSC(M_SAL_IN std::string* inputReaderName, u2* portNumber, M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode, u4 index)
-{
-   Log::begin( "PCSC::PCSC" );
 
-   std::string selfDiscover("selfdiscover");
-   std::string* identifiedReaderName;
-   LPTSTR pReaderList = NULL;
-   LONG lReturn;
+/*
+*/
+PCSC::PCSC( std::string& a_stInputReaderName, u2& a_u2PortNumber, std::string& a_stURI, u4& a_NameSpaceHivecode, u2& a_TypeHivecode, u4& a_Index ) {
 
-   if (inputReaderName == NULL) {
-      inputReaderName = &selfDiscover;
-   }
+    Log::begin( "PCSC::PCSC" );
 
-   identifiedReaderName = NULL;
-   this->hContext    = 0;
-   this->hCard       = 0;
+    m_bDoTransact = true;
 
-   lReturn = SCardEstablishContext(0, NULL, NULL, &this->hContext);
-   Log::log( "PCSC::PCSC - SCardEstablishContext <%#02x>", lReturn );
-   if(lReturn != SCARD_S_SUCCESS)
-   {
-      Log::log( "PCSC::PCSC - ## ERROR ## SCardEstablishContext <%#02x>", lReturn );
-      throw RemotingException((lpCharPtr)"PCSC: SCardEstablishContext error",lReturn);
-   }
+    std::string stIdentifiedReaderName = "";
 
-   // self-discovery mechanism
+    LPTSTR pReaderList = NULL;
+
+    if( a_stInputReaderName.empty( ) ) {
+
+        a_stInputReaderName = "selfdiscover";
+    }
+
+    m_hContextPCSC = 0;
+
+    m_hCardPCSC = 0;
+
+    LONG lReturn = SCardEstablishContext( 0, NULL, NULL, &m_hContextPCSC );
+
+    if( SCARD_S_SUCCESS != lReturn )
+    {
+        std::string msg = "";
+        Log::toString( msg, "SCardEstablishContext <%#02x>", lReturn );
+        Log::error( "PCSC::PCSC", msg.c_str( ) );
+
+        throw RemotingException((lpCharPtr)"PCSC: SCardEstablishContext error",lReturn);
+    }
+
+    // self-discovery mechanism
 #ifdef WIN32
-   if (_stricmp("selfdiscover", inputReaderName->c_str()) == 0) {
+    if (_stricmp("selfdiscover", a_stInputReaderName.c_str()) == 0) {
 #else
-   if (strncasecmp("selfdiscover", inputReaderName->c_str(),inputReaderName->length()) == 0) {
+    if (strncasecmp("selfdiscover", a_stInputReaderName.c_str(),a_stInputReaderName.length()) == 0) {
 #endif
-      // In Windows SCARD_AUTOALLOCATE (-1) as a value of readerListChatLength
-      // would signal the SCardListReaders to determine the size of reader string
-      // This is not available in Linux so we call the SCardListReaders twice. First
-      // to get the length and then the reader names.
+        // In Windows SCARD_AUTOALLOCATE (-1) as a value of readerListChatLength
+        // would signal the SCardListReaders to determine the size of reader string
+        // This is not available in Linux so we call the SCardListReaders twice. First
+        // to get the length and then the reader names.
 #ifdef WIN32
-      DWORD readerListCharLength = SCARD_AUTOALLOCATE;
-      lReturn = SCardListReaders(this->hContext, NULL, (LPTSTR)&pReaderList, &readerListCharLength);
-      Log::log( "PCSC::PCSC - SCardListReaders <%#02x>", lReturn );
+        DWORD readerListCharLength = SCARD_AUTOALLOCATE;
+        lReturn = SCardListReaders( m_hContextPCSC, NULL, (LPTSTR)&pReaderList, &readerListCharLength);
 
 #else
-      DWORD readerListCharLength = 0;
+        DWORD readerListCharLength = 0;
 
-      lReturn = SCardListReaders(this->hContext,NULL,NULL,&readerListCharLength);
-      if(lReturn != SCARD_S_SUCCESS)
-         throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn);
+        lReturn = SCardListReaders(m_hContextPCSC,NULL,NULL,&readerListCharLength);
+        if(lReturn != SCARD_S_SUCCESS)
+            throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn);
 
-      pReaderList = (lpCharPtr)malloc(sizeof(char)*readerListCharLength);
-      lReturn = SCardListReaders(this->hContext, NULL,pReaderList, &readerListCharLength);
+        pReaderList = (lpCharPtr)malloc(sizeof(char)*readerListCharLength);
+        lReturn = SCardListReaders(m_hContextPCSC, NULL,pReaderList, &readerListCharLength);
 #endif
 
 
-      if(lReturn != SCARD_S_SUCCESS)
-      {
-         Log::log( "PCSC::PCSC - ## ERROR ## SCardListReaders <%#02x>", lReturn );
-         throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn);
-      }
-      else
-      {
-         u4 count = 0;
-         u1 foundReader = FALSE;
-         SCARDHANDLE finalCardHandle = 0;
-         try
-         {
-            lpTCharPtr pReader = pReaderList;
-            while ('\0' != *pReader )
-            {
-               size_t readerNameLen = strlen((const char*)pReader);
-               SCARD_READERSTATE readerStates[1];
-               readerStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
-               readerStates[0].szReader = pReader;
-               if (SCardGetStatusChange(this->hContext, 0, readerStates, 1) == SCARD_S_SUCCESS)
-               {
-                  if ((readerStates[0].dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT)
-                  {
-                     // we found a card in this reader
-                     if (identifiedReaderName != NULL)
-                     {
-                        delete identifiedReaderName;
-                        identifiedReaderName = NULL;
-                     }
+        if(lReturn != SCARD_S_SUCCESS) {
 
-                     identifiedReaderName = new std::string((lpCharPtr)pReader);
-                     DWORD activeProtocol;
+            std::string msg = "";
+            Log::toString( msg, "SCardListReaders <%#02x>", lReturn );
+            Log::error( "PCSC::PCSC", msg.c_str( ) );
+            throw RemotingException((lpCharPtr)"PCSC: SCardListReaders error",lReturn);
 
-                     Log::log( "PCSC::PCSC SCardConnect..." );
-                     lReturn = SCardConnect(this->hContext, (LPTSTR)identifiedReaderName->c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &this->hCard, &activeProtocol);
-                     Log::log( "PCSC::PCSC - SCardConnect <%#02x>", lReturn );
+        } else {
 
-                     if (lReturn == SCARD_S_SUCCESS)
-                     {
-                        // try to identify if we're dealing with a .NetCard
-                        u1 answerData[258];
-                        DWORD answerLen = 258;
+            u4 count = 0;
+            u1 foundReader = FALSE;
+            SCARDHANDLE finalCardHandle = 0;
 
-                        Log::log( "PCSC::PCSC SCardTransmit..." );
-                        lReturn = SCardTransmit(hCard, SCARD_PCI_T0, isNetCardAPDU, sizeof(isNetCardAPDU), NULL, (LPBYTE)answerData, &answerLen);
-                        Log::log( "PCSC::PCSC - SCardTransmit <%#02x>", lReturn );
+            try {
 
-                        if (lReturn == SCARD_S_SUCCESS)
-                        {
-                           u1 rethrowException = FALSE;
-                           try {
-                              if (answerData[answerLen - 2] == 0x61)
-                              {
-                                 if (answerData[answerLen - 1] > 10)
-                                 {
-                                    u1Array invokeAPDU(0);
-                                    invokeAPDU += (u1)0xD8;
-                                    invokeAPDU += (u2)CARDMANAGER_SERVICE_PORT;
-                                    invokeAPDU += (u1)0x6F;
-                                    invokeAPDU += (u4)HIVECODE_NAMESPACE_SMARTCARD;
-                                    invokeAPDU += (u2)HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER;
-                                    invokeAPDU += (u2)HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT;
-                                    std::string* cmServiceUri = new std::string(CARDMANAGER_SERVICE_NAME);
-                                    invokeAPDU.Append(cmServiceUri);
-                                    delete cmServiceUri;
-                                    invokeAPDU += (u4)nameSpaceHivecode;
-                                    invokeAPDU += (u2)typeHivecode;
-                                    invokeAPDU.Append(uri);
+                lpTCharPtr pReader = pReaderList;
 
-                                    // construct call
-                                    if(invokeAPDU.GetLength() <= (s4)APDU_TO_CARD_MAX_SIZE) {
-                                       u1Array apdu(5);
-                                       apdu.GetBuffer()[0] = 0x80;
-                                       apdu.GetBuffer()[1] = 0xC2;
-                                       apdu.GetBuffer()[2] = 0x00;
-                                       apdu.GetBuffer()[3] = 0x00;
-                                       apdu.GetBuffer()[4] = (u1)invokeAPDU.GetLength();
-                                       apdu += invokeAPDU;
+                while ('\0' != *pReader ) {
 
-                                       u1Array answer(0);
+                    size_t readerNameLen = strlen((const char*)pReader);
+                    SCARD_READERSTATE readerStates[1];
+                    readerStates[0].dwCurrentState = SCARD_STATE_UNAWARE;
+                    readerStates[0].szReader = pReader;
 
-                                       Log::log( "PCSC::PCSC - ExchangeData..." );
-                                       this->ExchangeData(apdu, answer);
-                                       Log::log( "PCSC::PCSC - ExchangeData ok" );
+                    if ( SCardGetStatusChange( m_hContextPCSC, 0, readerStates, 1) == SCARD_S_SUCCESS) {
 
-                                       Log::log( "PCSC::PCSC - CheckForException..." );
-                                       u4 protocolOffset = CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32);
-                                       Log::log( "PCSC::PCSC - CheckForException ok" );
+                        if ((readerStates[0].dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) {
 
-                                       u4 discoveredPortNumber = ComReadU4At(answer, protocolOffset);
-                                       if ((*portNumber == 0) || (discoveredPortNumber == *portNumber))
-                                       {
-                                          *portNumber = (u2)discoveredPortNumber;
+                            // we found a card in this reader
+                            stIdentifiedReaderName = pReader;
 
-                                          if (foundReader == TRUE)
-                                          {
-                                             if (index == 0)
-                                             {
-                                                // this is the second reader/card/app that matches - we error at this point
-                                                rethrowException = TRUE;
-                                                char errorMessage[255];
-                                                strcpy(errorMessage, "At least 2 cards posses \"");
-                                                strcat(errorMessage, uri->c_str());
-                                                strcat(errorMessage, "\" service\r\nRemove conflicting cards from your system");
+                            DWORD activeProtocol;
 
-                                                Log::error( "PCSC::PCSC", errorMessage );
+                            lReturn = SCardConnect( m_hContextPCSC, (LPTSTR)stIdentifiedReaderName.c_str(), SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &m_hCardPCSC, &activeProtocol);
 
-                                                throw RemotingException(errorMessage);
-                                             }
-                                          }
+                            if (lReturn == SCARD_S_SUCCESS) {
 
-                                          foundReader = TRUE;
-                                          finalCardHandle = this->hCard;
+                                // try to identify if we're dealing with a .NetCard
+                                u1 answerData[258];
+                                DWORD answerLen = 258;
 
-                                          // Advance to the next value.
-                                          count++;
+                                Log::log( "PCSC::PCSC SCardTransmit..." );
+                                lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, isNetCardAPDU, sizeof(isNetCardAPDU), NULL, (LPBYTE)answerData, &answerLen);
+                                Log::log( "PCSC::PCSC - SCardTransmit <%#02x>", lReturn );
 
-                                          if (count == index)
-                                          {
-                                             // we enumerate one by one the valid readers - so stop here
-                                             break;
-                                          }
+                                if (lReturn == SCARD_S_SUCCESS)
+                                {
+                                    u1 rethrowException = FALSE;
+                                    try {
+                                        if (answerData[answerLen - 2] == 0x61)
+                                        {
+                                            if (answerData[answerLen - 1] > 10)
+                                            {
+                                                u1Array invokeAPDU(0);
+                                                invokeAPDU += (u1)0xD8;
+                                                invokeAPDU += (u2)CARDMANAGER_SERVICE_PORT;
+                                                invokeAPDU += (u1)0x6F;
+                                                invokeAPDU += (u4)HIVECODE_NAMESPACE_SMARTCARD;
+                                                invokeAPDU += (u2)HIVECODE_TYPE_SMARTCARD_CONTENTMANAGER;
+                                                invokeAPDU += (u2)HIVECODE_METHOD_SMARTCARD_CONTENTMANAGER_GETASSOCIATEDPORT;
+                                                std::string* cmServicem_stURI = new std::string(CARDMANAGER_SERVICE_NAME);
+                                                invokeAPDU.Append(cmServicem_stURI);
+                                                delete cmServicem_stURI;
+                                                invokeAPDU += (u4)a_NameSpaceHivecode;
+                                                invokeAPDU += (u2)a_TypeHivecode;
+                                                invokeAPDU.Append(&a_stURI);
 
-                                          pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
-                                          continue;
-                                       }
+                                                // construct call
+                                                if(invokeAPDU.GetLength() <= (s4)APDU_TO_CARD_MAX_SIZE) {
+                                                    u1Array apdu(5);
+                                                    apdu.GetBuffer()[0] = 0x80;
+                                                    apdu.GetBuffer()[1] = 0xC2;
+                                                    apdu.GetBuffer()[2] = 0x00;
+                                                    apdu.GetBuffer()[3] = 0x00;
+                                                    apdu.GetBuffer()[4] = (u1)invokeAPDU.GetLength();
+                                                    apdu += invokeAPDU;
+
+                                                    u1Array answer(0);
+
+                                                    Log::log( "PCSC::PCSC - ExchangeData..." );
+                                                    exchangeData(apdu, answer);
+                                                    Log::log( "PCSC::PCSC - ExchangeData ok" );
+
+                                                    Log::log( "PCSC::PCSC - CheckForException..." );
+                                                    u4 protocolOffset = m_MarshallerUtil.CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32);
+                                                    Log::log( "PCSC::PCSC - CheckForException ok" );
+
+                                                    u4 discoveredPortNumber = m_MarshallerUtil.ComReadU4At(answer, protocolOffset);
+                                                    if ((a_u2PortNumber == 0) || (discoveredPortNumber == a_u2PortNumber))
+                                                    {
+                                                        a_u2PortNumber = (u2)discoveredPortNumber;
+
+                                                        if (foundReader == TRUE)
+                                                        {
+                                                            if (a_Index == 0)
+                                                            {
+                                                                // this is the second reader/card/app that matches - we error at this point
+                                                                rethrowException = TRUE;
+                                                                std::string errorMessage( "At least 2 cards posses \"");
+                                                                errorMessage += a_stURI.c_str( );
+                                                                errorMessage += "\" service\r\nRemove conflicting cards from your system";
+                                                                Log::error( "PCSC::PCSC", errorMessage.c_str( ) );
+
+                                                                throw RemotingException(errorMessage);
+                                                            }
+                                                        }
+
+                                                        foundReader = TRUE;
+                                                        finalCardHandle = m_hCardPCSC;
+
+                                                        // Advance to the next value.
+                                                        count++;
+
+                                                        if (count == a_Index)
+                                                        {
+                                                            // we enumerate one by one the valid readers - so stop here
+                                                            break;
+                                                        }
+
+                                                        pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
+                                                        continue;
+                                                    }
+                                                }
+                                            }
+                                        }
                                     }
-                                 }
-                              }
-                           }
-                           catch (...)
-                           {
-                              if (rethrowException == TRUE)
-                              {
-                                 throw;
-                              }
-                              else
-                              {
-                                 // swallow exception
-                              }
-                           }
+                                    catch (...)
+                                    {
+                                        if (rethrowException == TRUE)
+                                        {
+                                            throw;
+                                        }
+                                        else
+                                        {
+                                            // swallow exception
+                                        }
+                                    }
 
-                           SCardDisconnect(this->hCard, SCARD_LEAVE_CARD);
-                           this->hCard = 0;
+                                    SCardDisconnect( m_hCardPCSC, SCARD_LEAVE_CARD);
+                                    m_hCardPCSC = 0;
+                                }
+                                // this is not a .NetCard, or the service was not found - let's try another reader/card
+                                else
+                                {
+                                    Log::error( "PCSC::PCSC", "SCardTransmit failed" );
+                                }
+                            }
+                            else
+                            {
+                                Log::error( "PCSC::PCSC", "SCardConnect failed" );
+                            }
                         }
-                        // this is not a .NetCard, or the service was not found - let's try another reader/card
                         else
                         {
-                           Log::error( "PCSC::PCSC", "SCardTransmit failed" );
+                            Log::error( "PCSC::PCSC", "SCARD_STATE_PRESENT not present" );
                         }
-                     }
-                     else
-                     {
-                        Log::error( "PCSC::PCSC", "SCardConnect failed" );
-                     }
-                  }
-                  else
-                  {
-                     Log::error( "PCSC::PCSC", "SCARD_STATE_PRESENT not present" );
-                  }
-               }
-               else
-               {
-                  Log::error( "PCSC::PCSC", "SCardGetStatusChange != SCARD_S_SUCCESS" );
-               }
+                    }
+                    else
+                    {
+                        Log::error( "PCSC::PCSC", "SCardGetStatusChange != SCARD_S_SUCCESS" );
+                    }
 
-               // Advance to the next value.
-               pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
-            }
-         } catch (...) {
-            if (identifiedReaderName != NULL) {
-               delete identifiedReaderName;
-            }
+                    // Advance to the next value.
+                    pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
+                }
+            } catch (...) {
 
+                stIdentifiedReaderName = "";
+
 #ifdef WIN32
-            lReturn = SCardFreeMemory(this->hContext, pReaderList);
-            if(lReturn != SCARD_S_SUCCESS) {
-               throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
-            }
+                /*lReturn = */SCardFreeMemory( m_hContextPCSC, pReaderList);
+                /*if(lReturn != SCARD_S_SUCCESS) {
+                throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
+                }*/
 #else
-            if(pReaderList != NULL)
-               free(pReaderList);
+                if( pReaderList ) {
+
+                    free(pReaderList);
+                }
 #endif
-            throw;
-         }
-
-         // have we found anything ?
-         if (foundReader == FALSE) {
-            if (identifiedReaderName != NULL) {
-               delete identifiedReaderName;
+                throw;
             }
 
+            // have we found anything ?
+            if( !foundReader) {
+
+                stIdentifiedReaderName = "";
+
 #ifdef WIN32
-            lReturn = SCardFreeMemory(this->hContext, pReaderList);
-            if(lReturn != SCARD_S_SUCCESS) {
-               throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
-            }
+                /*lReturn = */SCardFreeMemory( m_hContextPCSC, pReaderList);
+                //if(lReturn != SCARD_S_SUCCESS) {
+                //    throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
+                //}
 #else
-            if(pReaderList != NULL)
-               free(pReaderList);
+                if(pReaderList ) {
+
+                    free(pReaderList);
+                }
 #endif
 
-            throw RemotingException((lpCharPtr)"Could not find any Cryptoflex .NET smart card",SCARD_E_NO_SMARTCARD);
-         }
+                throw RemotingException((lpCharPtr)"Could not find any .NET smart card", SCARD_E_NO_SMARTCARD );
+            }
 
-         this->hCard = finalCardHandle;
-      }
+            m_hCardPCSC = finalCardHandle;
+        }
 
-      this->readerName = new std::string(identifiedReaderName->c_str());
+        m_stReaderName = stIdentifiedReaderName;
 
-      delete identifiedReaderName;
+    } else {
 
-   } else {
-      this->readerName = new std::string(inputReaderName->c_str());
-   }
+        m_stReaderName = a_stInputReaderName;
+    }
 
-   Log::end( "PCSC::PCSC" );
+    Log::end( "PCSC::PCSC" );
 }
 
-PCSC::PCSC(SCARDHANDLE cardHandle)
-{
-   this->hContext   = 0;
-   this->hCard		 = cardHandle;
-   this->readerName = NULL;
-   this->fDoTransact = true;
-}
 
-std::string* PCSC::GetReaderName(void)
-{
-   return this->readerName;
-}
+/*
+*/
+void PCSC::exchangeData( u1Array &dataIn, u1Array &dataout ) {
 
-void PCSC::BeginTransaction(void)
-{
-   if(fDoTransact) // TODO: TEST RETURN CODE!!
-      SCardBeginTransaction(this->hCard);
-}
+    // check validity of handle
+    if ( SCARD_S_SUCCESS != SCardIsValidContext( m_hContextPCSC ) ) {
 
-void PCSC::EndTransaction(void)
-{
-   if(fDoTransact) // TODO: TEST RETURN CODE!!
-      SCardEndTransaction(this->hCard, SCARD_LEAVE_CARD);
-}
+        throw RemotingException( (lpCharPtr)"PCSC: Invalid handle", SCARD_E_INVALID_HANDLE );
+    }
 
-SCARDHANDLE PCSC::GetCardHandle(void)
-{
-   return this->hCard;
-}
+    try {
 
-void PCSC::SetCardHandle(SCARDHANDLE hCard)
-{
-   this->hCard = hCard;
-}
+        if( m_bDoTransact ) { 
 
-void PCSC::DoTransact(bool flag)
-{
-   this->fDoTransact = flag;
-}
+            beginTransaction( );
+        }
 
-void PCSC::ExchangeData(u1Array &dataIn, u1Array &dataout)
-{
-   u1 answerData[258];
+        unsigned char ucRetry = 0;
 
-   // check validity of handle
-   if (this->hCard == 0) {
-      throw RemotingException((lpCharPtr)"PCSC: Invalid card handle", SCARD_E_INVALID_HANDLE);
-   }
+        do {
 
+            ucRetry++;
+
+            unsigned char answerData[ 258 ];
+            memset( answerData, 0, sizeof( answerData ) );
+
+            DWORD answerLen = sizeof( answerData );
+
 #ifdef __DEBUG_APDU__
-   //FILE *pFile = fopen("C:\\AxaltoProtocolAnalyzer.txt","a");
-   FILE *pFile = fopen("C:\\Gemalto.NET.PKCS11.log","a");
+            Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Command", dataIn.GetBuffer( ), dataIn.GetLength( ) );
+            Timer t;
+            t.start( );
 #endif
 
-   try {
+            LONG lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, dataIn.GetBuffer( ), dataIn.GetLength( ), NULL, (lpByte)answerData, &answerLen );
 
-      BeginTransaction();
+            if( SCARD_S_SUCCESS != lReturn ) {
 
-      DWORD answerLen = sizeof(answerData);
+                std::string msg = "";
+                Log::toString( msg, "SCardTransmit <%#02x>", lReturn );
+                Log::error( "PCSC::ExchangeData", msg.c_str( ) );
+            }
 
-#ifdef __DEBUG_APDU__
-      fprintf(pFile, "\nCmd DataIn\n");
-      for(int i=0; i < (s4)dataIn.GetLength(); i++) {
-         fprintf(pFile, "%02x",dataIn.GetBuffer()[i]);
-      }
-      fprintf(pFile, "\n");
-      unsigned long ulStart = GetTickCount( );
-#endif
+            if( ( SCARD_W_REMOVED_CARD == lReturn ) || ( SCARD_W_RESET_CARD == lReturn ) ) {
 
-      s4 lReturn = SCardTransmit(hCard, SCARD_PCI_T0, dataIn.GetBuffer(), dataIn.GetLength(), NULL, (lpByte)answerData, &answerLen);
-      if (lReturn != SCARD_S_SUCCESS) {
-         throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error",lReturn);
-      }
+                DWORD dwActiveProtocol = SCARD_PROTOCOL_T0;
 
-      if (answerLen < 2) {
-         throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned",SCARD_F_COMM_ERROR);
-      }
+                lReturn = SCardReconnect( m_hCardPCSC, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol );
 
-      if (answerLen > 2) {
-         u1Array temp(answerLen - 2);
-         temp.SetBuffer(answerData);
-         dataout += temp;
-#ifdef __DEBUG_APDU__
-         fprintf(pFile, "Cmd DataOut\n");
-         for(int i=0; i< (s4)temp.GetLength(); i++) {
-            fprintf(pFile, "%02x",temp.GetBuffer()[i]);
-         }
-         fprintf(pFile, "\n");
-#endif
-      }
+                if( SCARD_S_SUCCESS != lReturn ) {
 
-      u1 sw1 = answerData[answerLen - 2];
-      u1 sw2 = answerData[answerLen - 1];
+                    std::string msg = "";
+                    Log::toString( msg, "SCardReconnect <%#02x>", lReturn );
+                    Log::error( "PCSC::ExchangeData", msg.c_str( ) );
 
-#ifdef __DEBUG_APDU__
-      fprintf( pFile, "Cmd Status => %02x%02x\n", sw1, sw2 );
-      fprintf( pFile, "Cmd Time   => %ld ms\n", GetTickCount( ) - ulStart );
-#endif
+                    throw RemotingException( (lpCharPtr)"PCSC: SCardReconnect error", lReturn );
+                }
 
-      while ((sw1 == 0x61) || (sw1 == 0x9F))
-      {
-         u1 GetResponse[5];
-         if (sw1 == 0x9F) {
-            GetResponse[0] = 0xA0;
-         } else {
-            GetResponse[0] = 0x00;
-         }
-         GetResponse[1] = 0xC0;
-         GetResponse[2] = 0x00;
-         GetResponse[3] = 0x00;
-         GetResponse[4] = sw2;
-         answerLen = 258;
+                lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, dataIn.GetBuffer( ), dataIn.GetLength( ), NULL, (lpByte)answerData, &answerLen );
 
-#ifdef __DEBUG_APDU__
-         fprintf(pFile, "GetResponse DataIn\n");
-         for(int i=0; i<5; i++) {
-            fprintf(pFile, "%02x",GetResponse[i]);
-         }
-         fprintf(pFile, "\n");
-         ulStart = GetTickCount( );
-#endif
+                if( SCARD_S_SUCCESS != lReturn ) {
 
-         lReturn = SCardTransmit(hCard, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen);
-         if (lReturn != SCARD_S_SUCCESS) {
-            throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error",lReturn);
-         }
+                    Log::log( "PCSC::ExchangeData - SCardTransmit <%#02x>", lReturn );
+                }
 
-         if (answerLen < 2) {
-            throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned",SCARD_F_COMM_ERROR);
-         }
+            } else if( SCARD_S_SUCCESS != lReturn ) {
 
-         if (answerLen > 2) {
-            u1Array temp(answerLen - 2);
-            temp.SetBuffer(answerData);
-            dataout += temp;
-#ifdef __DEBUG_APDU__
-            fprintf(pFile, "GetResponse DataOut\n");
-            for(int i=0; i< (s4)temp.GetLength(); i++) {
-               fprintf(pFile, "%02x ",temp.GetBuffer()[i]);
+                std::string s;
+                Log::toString( s, "SCardTransmit failed <%#02x>", lReturn );
+                Log::error( "PCSC::ExchangeData", s.c_str( ) );
+
+                throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error", lReturn );
             }
-            fprintf(pFile, "\n");
 
-#endif
-         }
-         sw1 = answerData[answerLen - 2];
-         sw2 = answerData[answerLen - 1];
+            if (answerLen < 2) {
 
+                Log::error( "PCSC::ExchangeData", "Incorrect length returned" );
+
+                throw RemotingException((lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned",SCARD_F_COMM_ERROR);
+            }
+
+            if (answerLen > 2) {
+
+                u1Array temp(answerLen - 2);
+
+                temp.SetBuffer(answerData);
+
+                dataout += temp;
+            }
+
+            u1 sw1 = answerData[answerLen - 2];
+
+            u1 sw2 = answerData[answerLen - 1];
+
 #ifdef __DEBUG_APDU__
-         fprintf( pFile, "GetResponse Status => %02x%02x\n ", sw1, sw2 );
-         fprintf( pFile, "GetResponse Time   => %ld ms\n", GetTickCount( ) - ulStart );
+            Log::log( "PCSC::ExchangeData - Status (1) <%02x%02x>", sw1, sw2 );
+            Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Response", answerData, answerLen );
+            t.stop( "PCSC::ExchangeData - Response" );
 #endif
-      }
-   } catch (...) {
+
+            while( (sw1 == 0x61 ) || ( sw1 == 0x9F ) ) {
+
+                memset( answerData, 0, sizeof( answerData ) );
+
+                unsigned char GetResponse[ 5 ];
+
+                memset( GetResponse, 0, sizeof( GetResponse ) );
+
+                if (sw1 == 0x9F) {
+
+                    GetResponse[0] = 0xA0;
+
+                } else {
+
+                    GetResponse[0] = 0x00;
+                }
+
+                GetResponse[1] = 0xC0;
+
+                GetResponse[2] = 0x00;
+
+                GetResponse[3] = 0x00;
+
+                GetResponse[4] = sw2;
+
+                answerLen = 258;
+
 #ifdef __DEBUG_APDU__
-      fflush(pFile);
-      fclose(pFile);
+                Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Command", GetResponse, sizeof( GetResponse ) );
+                t.start( );
 #endif
-      EndTransaction();
-      throw;
-   }
 
+                lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen );
+
+                if( ( SCARD_W_REMOVED_CARD == lReturn ) || ( SCARD_W_RESET_CARD == lReturn ) ) {
+
+                    DWORD dwActiveProtocol = SCARD_PROTOCOL_T0;
+
+                    lReturn = SCardReconnect( m_hCardPCSC, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+                    lReturn = SCardTransmit( m_hCardPCSC, SCARD_PCI_T0, (lpCByte)GetResponse, 5, NULL, (lpByte)answerData, &answerLen );
+
+                } else if( SCARD_S_SUCCESS != lReturn ) {
+
+                    std::string s;
+                    Log::toString( s, "SCardTransmit failed <%02x>", lReturn );
+                    Log::error( "PCSC::ExchangeData", s.c_str( ) );
+
+                    throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error", lReturn );
+                }
+
+                if( answerLen < 2 ) {
+
+                    Log::error( "PCSC::ExchangeData", "Incorrect length returned" );
+
+                    throw RemotingException( (lpCharPtr)"PCSC: SCardTransmit error - Incorrect length returned", SCARD_F_COMM_ERROR );
+                }
+
+                if( answerLen > 2 ) {
+
+                    u1Array temp( answerLen - 2 );
+
+                    temp.SetBuffer( answerData );
+
+                    dataout += temp;
+                }
+
+                sw1 = answerData[ answerLen - 2 ];
+
+                sw2 = answerData[ answerLen - 1 ];
+
 #ifdef __DEBUG_APDU__
-   fflush(pFile);
-   fclose(pFile);
+                Log::log( "PCSC::ExchangeData - Status (2) <%02x%02x>", sw1, sw2 );
+                Log::logCK_UTF8CHAR_PTR( "PCSC::ExchangeData - Response", answerData, answerLen );
+                t.stop( "PCSC::ExchangeData - Response" );
 #endif
+            }
 
-   EndTransaction();
+            // The response is not acceptable. We have to retry the data transmission
+            if( ( 0x63 == sw1 ) || ( ( 0x69 == sw1 ) && ( 0x99 == sw2 ) ) ) {
+
+                Log::log( "PCSC::ExchangeData - Invalid response. Retry" );
+
+            } else {
+
+                break;
+            }
+
+ /*               if( ( 0x90 == sw1 ) && ( 0x00 == sw2 ) ) {
+
+                break;
+            }*/
+
+        } while ( 3 > ucRetry );
+
+    } catch (...) {
+
+        if( m_bDoTransact ) { 
+
+            endTransaction( );
+        }
+
+        throw;
+    }
+
+    if( m_bDoTransact ) { 
+
+        endTransaction( );
+    }
 }
 
-PCSC::~PCSC(void)
-{
-   // we cleanup the various context and card handle only if we allocated it (depends of constructor)
-   if (hContext != 0) {
-      if (hCard != 0) {
-         SCardDisconnect(hCard, SCARD_LEAVE_CARD);
-         hCard = 0;
-      }
-      SCardReleaseContext(hContext);
-      hContext = 0;
-   }
 
-   if (this->readerName != NULL) {
-      delete this->readerName;
-      this->readerName = NULL;
-   }
+/* Cleanup the context and card handle
+*/
+PCSC::~PCSC( ) {
+
+    if( m_hCardPCSC ) {
+
+        SCardDisconnect( m_hCardPCSC, SCARD_LEAVE_CARD );
+
+        m_hCardPCSC = 0;
+    }
+
+    if( m_hContextPCSC ) {
+
+        SCardReleaseContext( m_hContextPCSC );
+
+        m_hContextPCSC = 0;
+    }
 }
 
 MARSHALLER_NS_END
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,36 +18,64 @@
  *
  */
 
-#ifndef _include_marshaller_pcsc_h
-#define _include_marshaller_pcsc_h
 
+#ifndef __GEMALTO_PCSC__
+#define __GEMALTO_PCSC__
+
+
+#include "MarshallerUtil.h"
+#ifdef __APPLE__
+#include <PCSC/winscard.h>
+#include <PCSC/wintypes.h>
+#else
+#include <winscard.h>
+#endif
+
+
 MARSHALLER_NS_BEGIN
 
-class PCSC
-{
 
+class PCSC {
+
 private:
-    SCARDCONTEXT hContext;
-    SCARDHANDLE  hCard;
-    std::string*    readerName;
-    bool fDoTransact;
 
+    SCARDCONTEXT m_hContextPCSC;
+    
+	SCARDHANDLE m_hCardPCSC;
+    
+	std::string m_stReaderName;
+    
+	bool m_bDoTransact;
+
+	Marshaller::MarshallerUtil m_MarshallerUtil;
+
 public:
-    PCSC(SCARDHANDLE cardHandle);
-	PCSC(M_SAL_IN std::string* readerName);
-	PCSC(M_SAL_IN std::string* readerName, u2* portNumber, M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode, u4 index);
-    SCARDHANDLE GetCardHandle(void);
-    void SetCardHandle(SCARDHANDLE hCard);
-    void DoTransact(bool flag);
-    std::string* GetReaderName(void);
-    void BeginTransaction(void);
-    void EndTransaction(void);
-    void ExchangeData(u1Array &dataIn, u1Array &dataout);
-    ~PCSC(void);
+    	
+	PCSC( std::string& );
+	
+	PCSC( std::string&, u2&, std::string&, u4&, u2&, u4& );
+    
+	inline SCARDHANDLE getCardHandle( void ) { return m_hCardPCSC; }
+    
+	inline void setCardHandle( SCARDHANDLE a_hCard ) { m_hCardPCSC = a_hCard; }
+    
+	inline void doTransact( bool& a_bDoTransact ) { m_bDoTransact = a_bDoTransact; }
+    
+	inline std::string& getReaderName( void ) { return m_stReaderName; }
+    
+	inline void beginTransaction( void ) { SCardBeginTransaction( m_hCardPCSC ); }
+    
+	inline void endTransaction( void ) { SCardEndTransaction( m_hCardPCSC, SCARD_LEAVE_CARD ); }
+    
+	void exchangeData( Marshaller::u1Array&, Marshaller::u1Array& );
+    
+	virtual ~PCSC( );
 
+
 };
 
 MARSHALLER_NS_END
 
-#endif
 
+#endif //__GEMALTO_PCSC__
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/PCSCMissing.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PCSCMissing.h	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PCSCMissing.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,79 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifndef __GEMALTO_PCSC_MISSING__
+#define __GEMALTO_PCSC_MISSING__
+
+
+#ifndef SCARD_E_NO_SUCH_CERTIFICATE
+#define SCARD_E_NO_SUCH_CERTIFICATE ((LONG)0x8010002C)
+#endif
+
+#ifndef SCARD_E_FILE_NOT_FOUND
+#define SCARD_E_FILE_NOT_FOUND ((LONG)0x80100024)
+#endif
+
+#ifndef SCARD_E_COMM_DATA_LOST
+#define SCARD_E_COMM_DATA_LOST ((LONG)0x8010002F)
+#endif
+
+#ifndef SCARD_W_CHV_BLOCKED
+#define SCARD_W_CHV_BLOCKED ((LONG)0x8010006C)
+#endif
+
+#ifndef SCARD_E_UNEXPECTED
+#define SCARD_E_UNEXPECTED ((LONG)0x8010001F)
+#endif
+
+#ifndef SCARD_E_WRITE_TOO_MANY
+#define SCARD_E_WRITE_TOO_MANY ((LONG)0x80100028)
+#endif
+
+#ifndef SCARD_W_CANCELLED_BY_USER
+#define SCARD_W_CANCELLED_BY_USER ((LONG)0x8010006E)
+#endif
+
+#ifndef SCARD_W_WRONG_CHV
+#define SCARD_W_WRONG_CHV ((LONG)0x8010006B)
+#endif
+
+#ifndef SCARD_W_CARD_NOT_AUTHENTICATED
+#define SCARD_W_CARD_NOT_AUTHENTICATED  ((LONG)0x8010006F)
+#endif
+
+#ifndef SCARD_E_DIR_NOT_FOUND
+#define SCARD_E_DIR_NOT_FOUND ((LONG)0x80100023)
+#endif
+
+#ifndef SCARD_E_INVALID_CHV
+#define SCARD_E_INVALID_CHV ((LONG)0x8010002A)
+#endif
+
+#ifndef SCARD_E_CERTIFICATE_UNAVAILABLE
+#define SCARD_E_CERTIFICATE_UNAVAILABLE ((LONG)0x8010002D)
+#endif
+
+#ifndef SCARD_E_NO_ACCESS
+#define SCARD_E_NO_ACCESS ((LONG)0x80100027)
+#endif
+
+#endif //__GEMALTO_PCSC_MISSING__
+

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,3917 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#define CRYPTOKIVERSION_INTERFACE_MAJOR  0x02
+#define CRYPTOKIVERSION_INTERFACE_MINOR  0x14
+
+
+#include <string>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
+#include <boost/foreach.hpp>
+#include <boost/array.hpp>
+#include "cryptoki.h"
+#include "Application.hpp"
+#include "Log.hpp"
+#include "PKCS11Exception.hpp"
+#include "version.hpp"
+
+
+boost::condition_variable g_WaitForSlotEventCondition;
+
+boost::mutex g_WaitForSlotEventMutex;
+
+bool g_bWaitForSlotEvent = false;
+
+// Must be a 32 max length string
+const CK_UTF8CHAR g_stManufacturedId[ ] = "Gemalto";
+
+// Must be a 32 max length string
+const CK_UTF8CHAR g_stLibraryDescription[ ] = "Gemalto .NET PKCS11";
+
+boost::mutex io_mutex;
+
+Application g_Application;
+
+CK_BBOOL g_isInitialized = FALSE;
+
+
+static const CK_FUNCTION_LIST FunctionList = {
+
+    { CRYPTOKIVERSION_LIBRARY_MAJOR, CRYPTOKIVERSION_LIBRARY_MINOR },
+
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+
+#define CK_PKCS11_FUNCTION_INFO(func) func,
+
+#include "pkcs11f.h"
+
+#undef CK_PKCS11_FUNCTION_INFO
+#undef CK_NEED_ARG_LIST
+};
+
+
+extern "C"
+{
+    /**
+    * C_GetCardProperty retreives a property value from the smart card.
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetCardProperty )( CK_SLOT_ID ulSlotID, CK_BYTE a_ucProperty, CK_BYTE a_ucFlags, CK_BYTE_PTR a_pValue, CK_ULONG_PTR a_pValueLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetCardProperty" );
+        Log::in( "C_GetCardProperty" );
+        Log::log( "C_GetCardProperty - slotID <%#02x>", ulSlotID );
+        Log::log( "C_GetCardProperty - property <%#02x>", a_ucProperty );
+        Log::log( "C_GetCardProperty - flags <%#02x>", a_ucFlags );
+        if( *a_pValueLen ) {
+
+            Log::logCK_UTF8CHAR_PTR( "C_GetCardProperty - value", a_pValue, *a_pValueLen );
+            Log::log( "C_GetCardProperty - value len <%#02x>", *a_pValueLen );
+        }
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            /*} else if( !(*a_pValueLen) ) {
+
+                rv =  CKR_ARGUMENTS_BAD;
+                */
+            } else {
+
+                s = g_Application.getSlot( ulSlotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                    s->m_Device->beginTransaction( );
+
+                    s->getCardProperty( a_ucProperty, a_ucFlags, a_pValue, a_pValueLen );
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetCardProperty" );
+        Log::logCK_RV( "C_GetCardProperty", rv );
+        Log::out( "C_GetCardProperty" );
+        if( *a_pValueLen ) {
+
+            Log::logCK_UTF8CHAR_PTR( "C_GetCardProperty - value", a_pValue, *a_pValueLen );
+            Log::log( "C_GetCardProperty - value len <%#02x>", *a_pValueLen );
+        }
+        Log::end( "C_GetCardProperty" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_SetCardProperty sets a property value into the smart card.
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SetCardProperty )( CK_SLOT_ID ulSlotID, CK_BYTE a_ucProperty, CK_BYTE a_ucFlags, CK_BYTE_PTR a_pValue, CK_ULONG a_ulValueLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_SetCardProperty" );
+        Log::in( "C_SetCardProperty" );
+        Log::log( "C_SetCardProperty - slotID <%#02x>", ulSlotID );
+        Log::log( "C_SetCardProperty - property <%#02x>", a_ucProperty );
+        Log::log( "C_SetCardProperty - flags <%#02x>", a_ucFlags );
+        Log::logCK_UTF8CHAR_PTR( "C_SetCardProperty - value", a_pValue, a_ulValueLen );
+        Log::log( "C_SetCardProperty - value len <%#02x>", a_ulValueLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !a_pValue || !a_ulValueLen ) {
+
+                rv =  CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlot( ulSlotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                    s->m_Device->beginTransaction( );
+
+                    s->setCardProperty( a_ucProperty, a_ucFlags, a_pValue, a_ulValueLen );
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_SetCardProperty" );
+        Log::logCK_RV( "C_SetCardProperty", rv );
+        Log::end( "C_SetCardProperty" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Initialize initializes the Cryptoki library.
+    *
+    * @param pInitArgs
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Initialize )( CK_VOID_PTR a_pInitArgs ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Initialize" );
+        Log::in( "C_Initialize" );
+        Log::log( "C_Initialize - pInitArgs <%#02x>", a_pInitArgs );
+        Log::start( );
+
+        try {
+
+            // Already Initialized
+            if( g_isInitialized ) {
+
+                Log::error( "C_Initialize", "CKR_CRYPTOKI_ALREADY_INITIALIZED" );
+                rv = CKR_CRYPTOKI_ALREADY_INITIALIZED;
+
+            } else if( a_pInitArgs ) {
+
+                CK_C_INITIALIZE_ARGS initArgs = *(CK_C_INITIALIZE_ARGS_PTR)a_pInitArgs;
+
+                Log::logCK_C_INITIALIZE_ARGS_PTR( "C_Initialize", (CK_C_INITIALIZE_ARGS_PTR)a_pInitArgs );
+
+                if( initArgs.pReserved ) {
+
+                    Log::error( "C_Initialize", "CKR_ARGUMENTS_BAD" );
+                    rv = CKR_ARGUMENTS_BAD;
+
+                } else if( initArgs.flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS ) {
+
+                    Log::error( "C_Initialize", "CKR_NEED_TO_CREATE_THREADS" );
+                    rv = CKR_NEED_TO_CREATE_THREADS;
+
+                } else if( initArgs.flags & CKF_OS_LOCKING_OK ) {
+
+                    if( initArgs._CreateMutex || initArgs.DestroyMutex || initArgs.LockMutex || initArgs.UnlockMutex ) {
+
+                        Log::error( "C_Initialize", "CKR_CANT_LOCK" );
+                        rv = CKR_CANT_LOCK;
+                    }
+
+                } else if( initArgs._CreateMutex || initArgs.DestroyMutex || initArgs.LockMutex || initArgs.UnlockMutex ) {
+
+                    if( !initArgs._CreateMutex || !initArgs.DestroyMutex || !initArgs.LockMutex || !initArgs.UnlockMutex ) {
+
+                        Log::error( "C_Initialize", "CKR_ARGUMENTS_BAD" );
+                        rv = CKR_ARGUMENTS_BAD;
+
+                    } else if( !( initArgs.flags & CKF_OS_LOCKING_OK ) ) {
+
+                        Log::error( "C_Initialize", "CKR_CANT_LOCK" );
+                        rv = CKR_CANT_LOCK;
+                    }
+                }
+            }
+
+            if ( CKR_OK == rv ) {
+
+                g_isInitialized = TRUE;
+
+                g_Application.initialize( );
+            }
+
+            Log::log( "C_Initialize - isInitialized <%#02x>", g_isInitialized );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        Log::stop( "C_Initialize" );
+        Log::logCK_RV( "C_Initialize", rv );
+        Log::end( "C_Initialize" );
+        return rv;
+    }
+
+
+    /**
+    * C_Finalize indicates that an application is done with the
+    * Cryptoki library.
+    *
+    * @param pReserved reserved.Should be NULL_PTR
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Finalize )( CK_VOID_PTR a_pReserved ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Finalize" );
+        Log::in( "C_Finalize" );
+        Log::log( "C_Finalize - pReserved <%#02x>", a_pReserved );
+        Log::start( );
+
+        try {
+
+            // Not Initialized
+            if( !g_isInitialized ) {
+
+                Log::error( "C_Finalize", "CKR_CRYPTOKI_NOT_INITIALIZED" );
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( a_pReserved ) {
+
+                Log::error( "C_Finalize", "CKR_ARGUMENTS_BAD" );
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                g_WaitForSlotEventCondition.notify_all( );
+
+                g_isInitialized = FALSE;
+
+                g_Application.finalize( );
+            }
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        Log::stop( "C_Finalize" );
+        Log::logCK_RV( "C_Finalize", rv );
+        Log::end( "C_Finalize" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetInfo returns general information about Cryptoki.
+    *
+    * @param pInfo location that receives information
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetInfo )( CK_INFO_PTR pInfo ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+        Log::begin( "C_GetInfo" );
+        Log::in( "C_GetInfo" );
+        Log::logCK_INFO( "C_GetInfo", pInfo );
+        Log::start( );
+
+        if( !g_isInitialized ) {
+
+            rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+        } else if( !pInfo ) {
+
+            rv = CKR_ARGUMENTS_BAD;
+
+        } else {
+
+            pInfo->cryptokiVersion.major = CRYPTOKIVERSION_INTERFACE_MAJOR;
+            pInfo->cryptokiVersion.minor = CRYPTOKIVERSION_INTERFACE_MINOR;
+            pInfo->flags = 0;
+            memset( pInfo->libraryDescription, ' ', sizeof( pInfo->libraryDescription ) );
+            memcpy( pInfo->libraryDescription, g_stLibraryDescription, sizeof( g_stLibraryDescription ) - 1 );
+            memset( pInfo->manufacturerID, ' ', sizeof( pInfo->manufacturerID ) );
+            memcpy( pInfo->manufacturerID, g_stManufacturedId, sizeof( g_stManufacturedId ) - 1 );
+            pInfo->libraryVersion.major  = CRYPTOKIVERSION_LIBRARY_MAJOR;
+            pInfo->libraryVersion.minor  = CRYPTOKIVERSION_LIBRARY_MINOR;
+        }
+
+        Log::stop( "C_GetInfo" );
+        Log::logCK_RV( "C_GetInfo", rv );
+        Log::out( "C_GetInfo" );
+        Log::logCK_INFO( "C_GetInfo", pInfo );
+        Log::end( "C_GetInfo" );
+        return rv;
+    }
+
+
+    /**
+    * C_GetFunctionList returns the function list.
+    *
+    * @param ppFunctionList receives pointer to function list
+    */
+    CK_DEFINE_FUNCTION( CK_RV,C_GetFunctionList )( CK_FUNCTION_LIST_PTR_PTR ppFunctionList ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+        Log::begin( "C_GetFunctionList" );
+        Log::in( "C_GetFunctionList" );
+        Log::log( "C_GetFunctionList - CK_FUNCTION_LIST_PTR_PTR <%#02x>", ppFunctionList );
+        Log::start( );
+
+        if( !ppFunctionList ) {
+
+            rv = CKR_ARGUMENTS_BAD;
+
+        } else {
+
+            // this is the only function which an application can call before calling C_Initialize
+            *ppFunctionList = (CK_FUNCTION_LIST_PTR)&FunctionList;
+        }
+
+        Log::stop( "C_GetFunctionList" );
+        Log::logCK_RV( "C_GetFunctionList", rv );
+        Log::out( "C_GetFunctionList" );
+        Log::log( "C_GetFunctionList - CK_FUNCTION_LIST_PTR_PTR <%#02x>", ppFunctionList );
+        Log::end( "C_GetFunctionList" );
+        return rv;
+    }
+
+
+    /**
+    * C_GetSlotList obtains a list of slots in the system.
+    *
+    * @param tokenPresent only slots with tokens
+    * @param pSlotList    receives array of slot IDs
+    * @param pulCount     receives number of slots
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetSlotList )( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetSlotList" );
+        Log::in( "C_GetSlotList" );
+        Log::log( "C_GetSlotList - tokenPresent <%d>", tokenPresent );
+        Log::logCK_SLOT_ID_PTR( "C_GetSlotList", pSlotList, pulCount );
+        Log::start( );
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( pulCount ) {
+
+                g_Application.getSlotList( tokenPresent, pSlotList, pulCount );
+
+            } else {
+
+                rv = CKR_ARGUMENTS_BAD;
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+        }
+
+        Log::stop( "C_GetSlotList" );
+        Log::logCK_RV( "C_GetSlotList", rv );
+        Log::out( "C_GetSlotList" );
+        Log::logCK_SLOT_ID_PTR( "C_GetSlotList", pSlotList, pulCount );
+        Log::end( "C_GetSlotList" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetSlotInfo obtains information about a particular slot in
+    * the system.
+    *
+    * @param slotId the ID of the slot
+    * @param pInfo  received the slot information
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetSlotInfo )( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo )
+    {
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetSlotInfo" );
+        Log::in( "C_GetSlotInfo" );
+        Log::log( "C_GetSlotInfo - slotID <%ld>", slotID );
+        Log::logCK_SLOT_INFO_PTR( "C_GetSlotInfo", pInfo );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pInfo ) {
+
+                rv =  CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                    s->m_Device->beginTransaction( );
+               
+                    s->getInfo( pInfo );
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+
+            rv = x.getError( );
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetSlotInfo" );
+        Log::logCK_RV( "C_GetSlotInfo", rv );
+        Log::out( "C_GetSlotInfo" );
+        Log::logCK_SLOT_INFO_PTR( "C_GetSlotInfo", pInfo );
+        Log::end( "C_GetSlotInfo" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetTokenInfo obtains information about a particular token
+    * in the system.
+    *
+    * @param slotID ID of the token's slot
+    * @param pInfo  receives the token information
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetTokenInfo )( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetTokenInfo" );
+        Log::in( "C_GetTokenInfo" );
+        Log::log( "C_GetTokenInfo - slotID <%ld>", slotID );
+        Log::logCK_TOKEN_INFO_PTR( "C_GetTokenInfo", pInfo );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pInfo ) {
+
+                rv =  CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                    //if( ! s->getToken( ).get( ) ) {
+                    if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+
+                        s->m_Device->beginTransaction( );
+                
+                        s->getTokenInfo( pInfo );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetTokenInfo" );
+        Log::logCK_RV( "C_GetTokenInfo", rv );
+        Log::out( "C_GetTokenInfo" );
+        Log::logCK_TOKEN_INFO_PTR( "C_GetTokenInfo", pInfo );
+        Log::end( "C_GetTokenInfo" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetMechanismList obtains a list of mechanism types
+    * supported by a token.
+    *
+    * @param slotID ID of token's slot
+    * @param pMechanismList gets mech. array
+    * @param pulCount get number of mechs
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetMechanismList )( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetMechanismList" );
+        Log::in( "C_GetMechanismList" );
+        Log::log( "C_GetMechanismList - slotID <%#02x>", slotID );
+        Log::logCK_MECHANISM_TYPE( "C_GetMechanismList", pMechanismList, pulCount );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s; 
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pulCount ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+               
+                        s->getMechanismList( pMechanismList, pulCount );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetMechanismList" );
+        Log::logCK_RV( "C_GetMechanismList", rv );
+        Log::out( "C_GetMechanismList" );
+        Log::logCK_MECHANISM_TYPE( "C_GetMechanismList", pMechanismList, pulCount );
+        Log::end( "C_GetMechanismList" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetMechanismInfo obtains information about a particular
+    * mechanism possibly supported by a token.
+    *
+    * @param slotID ID of the token's slot
+    * @param type  type of mechanism
+    * @param pInfo receives mechanism info
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetMechanismInfo )( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetMechanismInfo" );
+        Log::in( "C_GetMechanismInfo" );
+        Log::log( "C_GetMechanismInfo - slotID <%#02x>", slotID );
+        Log::logCK_MECHANISM_TYPE( "C_GetMechanismInfo", type );
+        Log::logCK_MECHANISM_INFO_PTR( "C_GetMechanismInfo", pInfo );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pInfo ) {
+
+                rv =  CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->getMechanismInfo( type, pInfo );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetMechanismInfo" );
+        Log::logCK_RV( "C_GetMechanismInfo", rv );
+        Log::out( "C_GetMechanismInfo" );
+        Log::logCK_MECHANISM_INFO_PTR( "C_GetMechanismInfo", pInfo );
+        Log::end( "C_GetMechanismInfo" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_InitToken initializes a token.
+    *
+    * @param slotID ID of the token's slot
+    * @param pPin   the SO's initial PIN
+    * @param ulPinLen length in bytes of the PIN
+    * @param pLabel 32-byte token label (blank padded) pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_InitToken )( CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_InitToken" );
+        Log::in( "C_InitToken" );
+        Log::log( "C_InitToken - slotID <%#02x>", slotID );
+        Log::logCK_UTF8CHAR_PTR( "C_InitToken - pPin", pPin, ulPinLen );
+        Log::logCK_UTF8CHAR_PTR( "C_InitToken - pLabel", pLabel, 32 );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pPin ||  !ulPinLen || !pLabel ) {
+
+                rv =  CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->initToken( pPin, ulPinLen, pLabel );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_InitToken" );
+        Log::logCK_RV( "C_InitToken", rv );
+        Log::end( "C_InitToken" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_InitPIN initializes the normal user's PIN.
+    *
+    * @param hSession the session's handle
+    * @param pPin the noraml user's PIN
+    * @param ulPinLen length in bytes of the PIN
+    */
+    CK_DEFINE_FUNCTION( CK_RV,C_InitPIN )( CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_InitPIN" );
+        Log::in( "C_InitPIN" );
+        Log::log( "C_InitPIN - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_InitPIN - pPin", pPin, ulPinLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pPin ||  !ulPinLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+
+                        s->m_Device->beginTransaction( );
+                
+                        s->initPIN( hSession, pPin, ulPinLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_InitPIN" );
+        Log::logCK_RV( "C_InitPIN", rv );
+        Log::end( "C_InitPIN" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_SetPIN modifies the PIN of the user who is logged in.
+    *
+    * @param hSession   the session's handle
+    * @param pOldPin     the old PIN
+    * @param ulOldPin    length of the old PIN
+    * @param pNewPin     the new PIN
+    * @param ulNewLen    length of the new PIN
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SetPIN )( CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_SetPIN" );
+        Log::in( "C_SetPIN" );
+        Log::log( "C_SetPIN - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_SetPIN - pOldPin", pOldPin, ulOldLen );
+        Log::logCK_UTF8CHAR_PTR( "C_SetPIN - pNewPin", pNewPin, ulNewLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pOldPin || !ulOldLen || !pNewPin || !ulNewLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+               
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+               
+                        s->setPIN( hSession, pOldPin, ulOldLen, pNewPin, ulNewLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_SetPIN" );
+        Log::logCK_RV( "C_SetPIN", rv );
+        Log::end( "C_SetPIN" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_OpenSession opens a session between an application and a
+    * token.
+    *
+    * @param slotID       the slot's ID
+    * @param flags        from CK_SESSION_INFO
+    * @param pApplication passed to callback
+    * @param Notify       callback function
+    * @param phSession    gets session handle
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_OpenSession )( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_OpenSession" );
+        Log::in( "C_OpenSession" );
+        Log::log( "C_OpenSession - slotID <%#02x>", slotID );
+        Log::logSessionFlags( "C_OpenSession", flags );
+        Log::log( "C_OpenSession - pApplication <%#02x>", pApplication );
+        Log::log( "C_OpenSession - Notify <%#02x>", Notify );
+        Log::log( "C_OpenSession - phSession <%#02x> (%#02x)", phSession, ( ( NULL_PTR != phSession ) ? *phSession : 0 ) );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !phSession ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+            }
+
+            if ( ( flags & CKF_SERIAL_SESSION ) != CKF_SERIAL_SESSION ) {
+
+                rv = CKR_SESSION_PARALLEL_NOT_SUPPORTED;
+            }
+
+            if( CKR_OK == rv ) {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                    if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+              
+                        s->openSession( flags, pApplication, Notify, phSession );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_OpenSession" );
+        Log::logCK_RV( "C_OpenSession", rv );
+        Log::out( "C_OpenSession" );
+        Log::log( "C_OpenSession - phSession <%#02x> (%ld)", phSession, ( ( NULL_PTR != phSession ) ? *phSession : 0 ) );
+        Log::end( "C_OpenSession" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_CloseSession closes a session between an application and a
+    * token.
+    *
+    * @param hSession the session's handle
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_CloseSession )( CK_SESSION_HANDLE hSession ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_CloseSession" );
+        Log::in( "C_CloseSession" );
+        Log::log( "C_CloseSession - hSession <%#02x>", hSession );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !hSession ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->closeSession( hSession );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_CloseSession" );
+        Log::logCK_RV( "C_CloseSession", rv );
+        Log::end( "C_CloseSession" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_CloseAllSessions closes all sessions with a token.
+    *
+    * @param slotID the token's slot
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_CloseAllSessions )( CK_SLOT_ID slotID ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_CloseAllSessions" );
+        Log::in( "C_CloseAllSessions" );
+        Log::log( "C_CloseAllSessions - slotID <%#02x>", slotID );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else {
+
+                s = g_Application.getSlot( slotID );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                    ////===== TEST
+                    // if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    //
+                    //    rv = CKR_TOKEN_NOT_PRESENT;
+                    //
+                    //} else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->closeAllSessions( );
+                    //}
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_CloseAllSessions" );
+        Log::logCK_RV( "C_CloseAllSessions", rv );
+        Log::end( "C_CloseAllSessions" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetSessionInfo obtains information about the session.
+    *
+    * @param hSession the session's handle
+    * @param receives session info
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetSessionInfo )( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetSessionInfo" );
+        Log::in( "C_GetSessionInfo" );
+        Log::log( "C_GetSessionInfo - hSession <%#02x>", hSession );
+        Log::logCK_SESSION_INFO_PTR( "C_GetSessionInfo", pInfo );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pInfo ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->getSessionInfo( hSession, pInfo );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetSessionInfo" );
+        Log::logCK_RV( "C_GetSessionInfo", rv );
+        Log::out( "C_GetSessionInfo" );
+        Log::logCK_SESSION_INFO_PTR( "C_GetSessionInfo", pInfo );
+        Log::end( "C_GetSessionInfo" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Login logs a user into a token.
+    *
+    * @param hSession the session's handle
+    * @param userType the user type
+    * @param pPin the user's PIN
+    * @param ulPinLen the length of the PIN
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Login )( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Login" );
+        Log::in( "C_Login" );
+        Log::log( "C_Login - hSession <%#02x>", hSession );
+        Log::logCK_USER_TYPE( "C_Login", userType );
+        Log::logCK_UTF8CHAR_PTR( "C_Login - pPin", pPin, ulPinLen );
+        Log::log( "C_Login - ulPinLen <%ld>", ulPinLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pPin && ulPinLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+               
+                        s->login( hSession, userType, pPin, ulPinLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Login" );
+        Log::logCK_RV( "C_Login", rv );
+        Log::end( "C_Login" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Logout logs a user out from a token.
+    *
+    * @param hSession the session's handle
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Logout )( CK_SESSION_HANDLE hSession ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Logout" );
+        Log::in( "C_Logout" );
+        Log::log( "C_Logout - hSession <%#02x>", hSession );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+              
+                        s->logout( hSession );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Logout" );
+        Log::logCK_RV( "C_Logout", rv );
+        Log::end( "C_Logout" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_CreateObject creates a new object.
+    *
+    * @param hSession  the session's handle
+    * @param pTemplate the object's template
+    * @param ulCount   attributes in template
+    * @param phObject  gets new object's handle.
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_CreateObject )( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_CreateObject" );
+        Log::in( "C_CreateObject" );
+        Log::log( "C_CreateObject - hSession <%#02x>", hSession );
+        Log::logCK_ATTRIBUTE_PTR( "C_CreateObject", pTemplate, ulCount );
+        Log::log( "C_CreateObject - phObject <%#02x>", phObject );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pTemplate || !ulCount || !phObject ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->createObject( hSession, pTemplate, ulCount, phObject );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_CreateObject" );
+        Log::logCK_RV( "C_CreateObject", rv );
+        Log::out( "C_CreateObject" );
+        Log::log( "C_CreateObject - phObject <%#02x> (%#02x)", phObject, ( ( NULL_PTR != phObject ) ? *phObject : 0 ) );
+        Log::end( "C_CreateObject" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_DestroyObject destroys an object.
+    *
+    * @param hSession the session's handle
+    * @param hObject the object's handle
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DestroyObject )( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_DestroyObject" );
+        Log::in( "C_DestroyObject" );
+        Log::log( "C_DestroyObject - hSession <%#02x>", hSession );
+        Log::log( "C_DestroyObject - hObject <%#02x>", hObject );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->destroyObject( hSession, hObject );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_DestroyObject" );
+        Log::logCK_RV( "C_DestroyObject", rv );
+        Log::end( "C_DestroyObject" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GetAttributeValue obtains the value of one or more object
+    * attributes.
+    *
+    * @param hSession    the session's handle
+    * @param hObject     the object's handle
+    * @param pTemplate   specifies attrs; gets vals
+    * @param ulCount     attributes in template
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetAttributeValue )( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GetAttributeValue" );
+        Log::in( "C_GetAttributeValue" );
+        Log::log( "C_GetAttributeValue - hSession <%#02x>", hSession );
+        Log::logCK_ATTRIBUTE_PTR( "C_GetAttributeValue", pTemplate, ulCount );
+        Log::log( "C_GetAttributeValue - hObject <%#02x>", hObject );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pTemplate || !ulCount ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->getAttributeValue( hSession, hObject, pTemplate, ulCount );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GetAttributeValue" );
+        Log::logCK_RV( "C_GetAttributeValue", rv );
+        Log::out( "C_GetAttributeValue" );
+        Log::logCK_ATTRIBUTE_PTR( "C_GetAttributeValue", pTemplate, ulCount );
+        Log::end( "C_GetAttributeValue" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_SetAttributeValue modifies the value of one or more object
+    * attributes
+    *
+    * @param   hSession    the session's handle
+    * @param   hObject     the object's handle
+    * @param   pTemplate   specifies attrs and values
+    * @param   ulCount     attributes in template
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SetAttributeValue )( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_SetAttributeValue" );
+        Log::in( "C_SetAttributeValue" );
+        Log::log( "C_SetAttributeValue - hSession <%#02x>", hSession );
+        Log::logCK_ATTRIBUTE_PTR( "C_SetAttributeValue", pTemplate, ulCount );
+        Log::log( "C_SetAttributeValue - hObject <%#02x>", hObject );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pTemplate || !ulCount ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+               
+                        s->setAttributeValue( hSession, hObject, pTemplate, ulCount );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+        }
+        catch( ... )
+        {
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_SetAttributeValue" );
+        Log::logCK_RV( "C_SetAttributeValue", rv );
+        Log::end( "C_SetAttributeValue" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_FindObjectsInit initializes a search for token and session
+    * objects that match a template.
+    *
+    * @param hSession the session's handle
+    * @param pTemplate attribute values to match
+    * @param ulCount atrs in search template
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_FindObjectsInit )( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_FindObjectsInit" );
+        Log::in( "C_FindObjectsInit" );
+        Log::log( "C_FindObjectsInit - hSession <%#02x>", hSession );
+        Log::logCK_ATTRIBUTE_PTR( "C_FindObjectsInit", pTemplate, ulCount );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pTemplate && ulCount ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->findObjectsInit( hSession, pTemplate, ulCount );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_FindObjectsInit" );
+        Log::logCK_RV( "C_FindObjectsInit", rv );
+        Log::end( "C_FindObjectsInit" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_FindObjects continues a search for token and session
+    * objects that match a template, obtaining additional object
+    * handles.
+    *
+    * @param hSession                session's handle
+    * @param phObject                gets obj. handles
+    * @param ulMaxObjectCount        max handles to get
+    * @param pulObjectCount          actual # returned
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_FindObjects )(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_FindObjects" );
+        Log::in( "C_FindObjects" );
+        Log::log( "C_FindObjects - hSession <%#02x>", hSession );
+        Log::log( "C_FindObjects - phObject <%#02x> (%#02x)", phObject, ( ( NULL_PTR != phObject ) ? *phObject : 0 ) );
+        Log::log( "C_FindObjects - ulMaxObjectCount <%#02x>", ulMaxObjectCount );
+        Log::log( "C_FindObjects - pulObjectCount <%#02x> (%#02x)", pulObjectCount, ( ( NULL_PTR != pulObjectCount ) ? *pulObjectCount : 0 ) );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !phObject || !pulObjectCount ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->findObjects( hSession, phObject, ulMaxObjectCount, pulObjectCount );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_FindObjects" );
+        Log::logCK_RV( "C_FindObjects", rv );
+        Log::out( "C_FindObjects" );
+        Log::log( "C_FindObjects - phObject <%#02x> (%#02x)", phObject, ( ( NULL_PTR != phObject ) ? *phObject : 0 ) );
+        Log::log( "C_FindObjects - pulObjectCount <%#02x> (%#02x)", pulObjectCount, ( ( NULL_PTR != pulObjectCount ) ? *pulObjectCount : 0 ) );
+        Log::end( "C_FindObjects" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_FindObjectsFinal finishes a search for token and session objects
+    *
+    * @param hSession the session's handle
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_FindObjectsFinal )( CK_SESSION_HANDLE hSession ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_FindObjectsFinal" );
+        Log::in( "C_FindObjectsFinal" );
+        Log::log( "C_FindObjectsFinal - hSession <%#02x>", hSession );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->findObjectsFinal( hSession );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_FindObjectsFinal" );
+        Log::logCK_RV( "C_FindObjectsFinal", rv );
+        Log::end( "C_FindObjectsFinal" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_EncryptInit initializes an encryption operation.
+    *
+    * @param hSession          the session's handle
+    * @param pMechanism        the encryption mechanism
+    * @param hKey              handle of encryption key
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_EncryptInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_EncryptInit" );
+        Log::in( "C_EncryptInit" );
+        Log::log( "C_EncryptInit - hSession <%#02x>", hSession );
+        Log::logCK_MECHANISM_PTR( "C_EncryptInit", pMechanism );
+        Log::log( "C_EncryptInit - hKey <%#02x>", hKey );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( pMechanism ) {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->encryptInit( hSession, pMechanism, hKey );
+                    }
+                }
+
+            } else {
+
+                rv = CKR_ARGUMENTS_BAD;
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_EncryptInit" );
+        Log::logCK_RV( "C_EncryptInit", rv );
+        Log::end( "C_EncryptInit" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Encrypt encrypts single-part data.
+    *
+    * @param hSession               session's handle
+    * @param pData                  the plaintext data
+    * @param ulDataLen              bytes of plaintext
+    * @param pEncryptedData         gets ciphertext
+    * @param pulEncryptedData Len   gets c-text size
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Encrypt )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Encrypt" );
+        Log::in( "C_Encrypt" );
+        Log::log( "C_Encrypt - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_Encrypt - pData", pData, ulDataLen );
+        Log::logCK_UTF8CHAR_PTR( "C_Encrypt - pEncryptedData", pEncryptedData, (NULL_PTR == pulEncryptedDataLen) ? 0 : *pulEncryptedDataLen );
+        Log::start( );      
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pData || !ulDataLen || !pulEncryptedDataLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->encrypt( hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen );
+                    }
+                 }
+           }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Encrypt" );
+        Log::logCK_RV( "C_Encrypt", rv );
+        Log::out( "C_Encrypt" );
+        Log::logCK_UTF8CHAR_PTR( "C_Encrypt - pEncryptedData", pEncryptedData, (NULL_PTR == pulEncryptedDataLen) ? 0 : *pulEncryptedDataLen );
+        Log::end( "C_Encrypt" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_DecryptInit initializes a decryption operation.
+    *
+    * @param hSession the session's handle
+    * @param pMechanism the decryption mechanism
+    * @param hKey handle of decrypting key
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DecryptInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_DecryptInit" );
+        Log::in( "C_DecryptInit" );
+        Log::log( "C_DecryptInit - hSession <%#02x>", hSession );
+        Log::logCK_MECHANISM_PTR( "C_DecryptInit", pMechanism );
+        Log::log( "C_DecryptInit - hKey <%#02x>", hKey );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( pMechanism ) {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->decryptInit( hSession, pMechanism, hKey );
+                    }
+                }
+
+            } else {
+
+                rv = CKR_ARGUMENTS_BAD;
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_DecryptInit" );
+        Log::logCK_RV( "C_DecryptInit", rv );
+        Log::end( "C_DecryptInit" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Decrypt decrypts encrypted data in a single part.
+    *
+    * @param hSession                   session's handle
+    * @param pEncryptedData             ciphertext
+    * @param ulEncryptedDataLen         ciphertext length
+    * @param pData                      gets plaintext
+    * @param pulDataLen                 gets p-text size
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Decrypt )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Decrypt" );
+        Log::in( "C_Decrypt" );
+        Log::log( "C_Decrypt - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_Decrypt - pEncryptedData", pEncryptedData, ulEncryptedDataLen );
+        Log::logCK_UTF8CHAR_PTR( "C_Decrypt - pData", pData, (NULL_PTR == pulDataLen) ? 0 : *pulDataLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pEncryptedData || !ulEncryptedDataLen || !pulDataLen ) {
+
+                rv  = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->decrypt( hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Decrypt" );
+        Log::logCK_RV( "C_Decrypt", rv );
+        Log::out( "C_Decrypt" );
+        Log::logCK_UTF8CHAR_PTR( "C_Decrypt - pData", pData, (NULL_PTR == pulDataLen) ? 0 : *pulDataLen );
+        Log::end( "C_Decrypt" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_DigestInit initializes a message-digesting operation.
+    *
+    * @param hSession the session's handle
+    * @param pMechanism the digesting mechanism
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DigestInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_DigestInit" );
+        Log::in( "C_DigestInit" );
+        Log::log( "C_DigestInit - hSession <%#02x>", hSession );
+        Log::logCK_MECHANISM_PTR( "C_DigestInit", pMechanism );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pMechanism ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->digestInit( hSession, pMechanism );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_DigestInit" );
+        Log::logCK_RV( "C_DigestInit", rv );
+        Log::end( "C_DigestInit" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Digest digests data in a single part.
+    *
+    * @param hSession      the session's handle
+    * @param pData         data to be digested
+    * @param ulDataLen     bytes of data to digest
+    * @param pDigest       gets the message digest
+    * @param pulDigestLen  gets digest length
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Digest )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Digest" );
+        Log::in( "C_Digest" );
+        Log::log( "C_Digest - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_Digest - pData", pData, ulDataLen );
+        Log::logCK_UTF8CHAR_PTR( "C_Digest - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pData ||  !ulDataLen ||  !pulDigestLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+                
+                        s->digest( hSession, pData, ulDataLen, pDigest, pulDigestLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Digest" );
+        Log::logCK_RV( "C_Digest", rv );
+        Log::out( "C_Digest" );
+        Log::logCK_UTF8CHAR_PTR( "C_Digest - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
+        Log::end( "C_Digest" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_DigestUpdate continues a multiple-part message-digesting
+    * operation.
+    *
+    * @param hSession       the session's handle
+    * @param pPart          data to be digested
+    * @param ulPartLen      bytes of data to be digested
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DigestUpdate )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_DigestUpdate" );
+        Log::in( "C_DigestUpdate" );
+        Log::log( "C_DigestUpdate - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_DigestUpdate - pPart", pPart, ulPartLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pPart || !ulPartLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->digestUpdate( hSession, pPart, ulPartLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_DigestUpdate" );
+        Log::logCK_RV( "C_DigestUpdate", rv );
+        Log::end( "C_DigestUpdate" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_DigestFinal finishes a multiple-part message-digesting
+    * operation.
+    *
+    * @param hSession       the session's handle
+    * @param pDigest        gets the message digest
+    * @param pulDigestLen   gets byte count of digest
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DigestFinal )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_DigestFinal" );
+        Log::in( "C_DigestFinal" );
+        Log::log( "C_DigestFinal - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_DigestFinal - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pulDigestLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->digestFinal( hSession, pDigest, pulDigestLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_DigestFinal" );
+        Log::logCK_RV( "C_DigestFinal", rv );
+        Log::out( "C_DigestFinal" );
+        Log::logCK_UTF8CHAR_PTR( "C_DigestFinal - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
+        Log::end( "C_DigestFinal" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_SignInit initializes a signature (private key encryption)
+    * operation, where the signature is (will be) an appendix to
+    * the data, and plaintext cannot be recovered from the
+    * signature.
+    *
+    * @param hSession           the session's handle
+    * @param pMechanism         the signature mechanism
+    * @param hKey               handle of signature key
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SignInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_SignInit" );
+        Log::in( "C_SignInit" );
+        Log::log( "C_SignInit - hSession <%#02x>", hSession );
+        Log::logCK_MECHANISM_PTR( "C_SignInit", pMechanism );
+        Log::log( "C_SignInit - hKey <%#02x>", hKey );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pMechanism ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->signInit( hSession, pMechanism, hKey );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_SignInit" );
+        Log::logCK_RV( "C_SignInit", rv );
+        Log::end( "C_SignInit" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Sign signs (encrypts with private key) data in a single
+    * part, where the signature is (will be) an appendix to the
+    * data, and plaintext cannot be recovered from the signature.
+    *
+    * @param hSession          the session's handle
+    * @param pData             the data to sign
+    * @param ulDataLen         count of bytes to sign
+    * @param pSignature        gets the signature
+    * @param pulSignatureLen   gets signature length
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Sign )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Sign" );
+        Log::in( "C_Sign" );
+        Log::log( "C_Sign - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_Sign - pData", pData, ulDataLen );
+        Log::logCK_UTF8CHAR_PTR( "C_Sign - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pData || !ulDataLen || !pulSignatureLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->sign( hSession, pData, ulDataLen, pSignature, pulSignatureLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Sign" );
+        Log::logCK_RV( "C_Sign", rv );
+        Log::out( "C_Sign" );
+        Log::logCK_UTF8CHAR_PTR( "C_Sign - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
+        Log::end( "C_Sign" );
+        return rv;
+    }
+
+
+    /**
+    * C_SignUpdate continues a multiple-part signature operation,
+    * where the signature is (will be) an appendix to the data,
+    * and plaintext cannot be recovered from the signature.
+    *
+    * @param hSession       the session's handle
+    * @param pPart          the data to sign
+    * @param ulPartLen      count of bytes to sign
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SignUpdate )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_SignUpdate" );
+        Log::in( "C_SignUpdate" );
+        Log::log( "C_SignUpdate - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_SignUpdate - pPart", pPart, ulPartLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pPart || !ulPartLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->signUpdate( hSession, pPart, ulPartLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_SignUpdate" );
+        Log::logCK_RV( "C_SignUpdate", rv );
+        Log::end( "C_SignUpdate" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_SignFinal finishes a multiple-part signature operation,
+    * returning the signature.
+    *
+    * @param hSession           the session's handle
+    * @param pSignature         gets the signature
+    * @param pulSignatureLen    gets signature length
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SignFinal )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_SignFinal" );
+        Log::in( "C_SignFinal" );
+        Log::log( "C_SignFinal - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_SignFinal - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pulSignatureLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->signFinal( hSession, pSignature, pulSignatureLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_SignFinal" );
+        Log::logCK_RV( "C_SignFinal", rv );
+        Log::out( "C_SignFinal" );
+        Log::logCK_UTF8CHAR_PTR( "C_SignFinal - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
+        Log::end( "C_SignFinal" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_VerifyInit initializes a verification operation, where the
+    * signature is an appendix to the data, and plaintext cannot
+    * cannot be recovered from the signature (e.g. DSA).
+    *
+    * @param hSession      the session's handle
+    * @param pMechanism    the verification mechanism
+    * @param hKey          verification key
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_VerifyInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_VerifyInit" );
+        Log::in( "C_VerifyInit" );
+        Log::log( "C_VerifyInit - hSession <%#02x>", hSession );
+        Log::logCK_MECHANISM_PTR( "C_VerifyInit", pMechanism );
+        Log::log( "C_VerifyInit - hKey <%#02x>", hKey );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pMechanism ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->verifyInit( hSession, pMechanism, hKey );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_VerifyInit" );
+        Log::logCK_RV( "C_VerifyInit", rv );
+        Log::end( "C_VerifyInit" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_Verify verifies a signature in a single-part operation,
+    * where the signature is an appendix to the data, and plaintext
+    * cannot be recovered from the signature.
+    *
+    * @param hSession           the session's handle
+    * @param pData              signed data
+    * @param ulDataLen          length of signed data
+    * @param pSignature         signature
+    * @param ulSignatureLen     signature length
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_Verify )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_Verify" );
+        Log::in( "C_Verify" );
+        Log::log( "C_Verify - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_Verify - pData", pData, ulDataLen );
+        Log::logCK_UTF8CHAR_PTR( "C_Verify - pSignature", pSignature, ulSignatureLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pData || !ulDataLen || !pSignature || !ulSignatureLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->verify( hSession, pData, ulDataLen, pSignature, ulSignatureLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_Verify" );
+        Log::logCK_RV( "C_Verify", rv );
+        Log::out( "C_Verify" );
+        Log::logCK_UTF8CHAR_PTR( "C_Verify - pSignature", pSignature, ulSignatureLen );
+        Log::end( "C_Verify" );
+
+        return rv;
+    }
+
+
+    /* C_VerifyUpdate continues a multiple-part verification
+    * operation, where the signature is an appendix to the data,
+    * and plaintext cannot be recovered from the signature. */
+    CK_DEFINE_FUNCTION( CK_RV, C_VerifyUpdate )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_VerifyUpdate" );
+        Log::in( "C_VerifyUpdate" );
+        Log::log( "C_VerifyUpdate - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_VerifyUpdate - pPart", pPart, ulPartLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pPart || !ulPartLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->verifyUpdate( hSession, pPart, ulPartLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_VerifyUpdate" );
+        Log::logCK_RV( "C_VerifyUpdate", rv );
+        Log::end( "C_VerifyUpdate" );
+
+        return rv;
+    }
+
+
+    /* C_VerifyFinal finishes a multiple-part verification
+    * operation, checking the signature. */
+    CK_DEFINE_FUNCTION( CK_RV, C_VerifyFinal )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_VerifyFinal" );
+        Log::in( "C_VerifyFinal" );
+        Log::log( "C_VerifyFinal - hSession <%#02x>", hSession );
+        Log::logCK_UTF8CHAR_PTR( "C_VerifyFinal - pSignature", pSignature, ulSignatureLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pSignature ||  !ulSignatureLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->verifyFinal( hSession, pSignature, ulSignatureLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_VerifyFinal" );
+        Log::logCK_RV( "C_VerifyFinal", rv );
+        Log::end( "C_VerifyFinal" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GenerateKeyPair generates a public-key/private-key pair, creating new key objects
+    *
+    * @param hSession,                    session handle
+    * @param pMechanism,                  key-gen mech.
+    * @param pPublicKeyTemplate,          template for pub. key
+    * @param ulPublicKeyAttributeCount,   # pub. attrs.
+    * @param pPrivateKeyTemplate,         template for priv. key
+    * @param ulPrivateKeyAttributeCount,  # priv. attrs.
+    * @param phPublicKey,                 gets pub. key handle
+    * @param phPrivateKey                 gets priv key handle
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GenerateKeyPair )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GenerateKeyPair" );
+        Log::in( "C_GenerateKeyPair" );
+        Log::log( "C_GenerateKeyPair - hSession <%#02x>", hSession );
+        Log::logCK_MECHANISM_PTR( "C_GenerateKeyPair", pMechanism );
+        Log::logCK_ATTRIBUTE_PTR( "C_GenerateKeyPair", pPublicKeyTemplate, ulPublicKeyAttributeCount );
+        Log::logCK_ATTRIBUTE_PTR( "C_GenerateKeyPair", pPrivateKeyTemplate, ulPrivateKeyAttributeCount );
+        Log::log( "C_GenerateKeyPair - phPublicKey <%#02x>", (phPublicKey == NULL_PTR) ? 0 : *phPublicKey );
+        Log::log( "C_GenerateKeyPair - phPrivateKey <%#02x>", (phPrivateKey == NULL_PTR) ? 0 : *phPrivateKey );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try {
+
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pMechanism || !pPublicKeyTemplate || !ulPublicKeyAttributeCount || !phPublicKey || !phPrivateKey ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else if( pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN ) {
+
+                rv = CKR_MECHANISM_INVALID;
+            }
+
+            if( CKR_OK == rv ) {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->generateKeyPair( hSession, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GenerateKeyPair" );
+        Log::logCK_RV( "C_GenerateKeyPair", rv );
+        Log::out( "C_GenerateKeyPair" );
+        Log::log( "C_GenerateKeyPair - phPublicKey <%#02x>", (phPublicKey == NULL_PTR) ? 0 : *phPublicKey );
+        Log::log( "C_GenerateKeyPair - phPrivateKey <%#02x>", (phPrivateKey == NULL_PTR) ? 0 : *phPrivateKey );
+        Log::end( "C_GenerateKeyPair" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_GenerateRandom generates random data.
+    *
+    * @param hSession       the session's handle
+    * @param RandomData     receives the random data
+    * @param ulRandomLen    # of bytes to generate
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GenerateRandom )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen ) {
+
+        boost::mutex::scoped_lock lock( io_mutex );
+
+        CK_RV rv = CKR_OK;
+
+        Log::begin( "C_GenerateRandom" );
+        Log::in( "C_GenerateRandom" );
+        Log::logCK_UTF8CHAR_PTR( "C_GenerateRandom", pRandomData, ulRandomLen );
+        Log::start( );
+
+        boost::shared_ptr< Slot > s;
+
+        try
+        {
+            if( !g_isInitialized ) {
+
+                rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+
+            } else if( !pRandomData || !ulRandomLen ) {
+
+                rv = CKR_ARGUMENTS_BAD;
+
+            } else {
+
+                s = g_Application.getSlotFromSession( hSession );
+
+                if( s.get( ) && s->m_Device.get( ) ) {
+
+                     if( !s->getToken( ).get( ) && !s->isTokenInserted( ) ) { //->getToken( ).get( ) ) {
+                    
+                        rv = CKR_TOKEN_NOT_PRESENT;
+                    
+                    } else {
+                        
+                        s->m_Device->beginTransaction( );
+
+                        s->generateRandom( hSession, pRandomData, ulRandomLen );
+                    }
+                }
+            }
+
+        } catch( PKCS11Exception& x ) {
+
+            rv = x.getError( );
+
+        } catch( ... ) {
+
+            rv = CKR_GENERAL_ERROR;
+        }
+
+        if( s.get( ) && s->m_Device.get( ) ) {
+
+            s->m_Device->endTransaction( );
+        }
+
+        Log::stop( "C_GenerateRandom" );
+        Log::logCK_RV( "C_GenerateRandom", rv );
+        Log::out( "C_GenerateRandom" );
+        Log::logCK_UTF8CHAR_PTR( "C_GenerateRandom", pRandomData, ulRandomLen );
+        Log::end( "C_GenerateRandom" );
+
+        return rv;
+    }
+
+
+    /**
+    * C_WaitForSlotEvent waits for a slot event (token insertion, removal, etc.) to occur.
+    *
+    * @param flags      blocking/nonblocking flag
+    * @param pSlot      location that receives the slot ID
+    * @param pReserved  reserved.  Should be NULL_PTR
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_WaitForSlotEvent )( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved ) {
+        
+        CK_RV rv = CKR_NO_EVENT;
+
+        Log::begin( "C_WaitForSlotEvent" );
+        Log::in( "C_WaitForSlotEvent" );
+        Log::log( "C_WaitForSlotEvent - flags <%ld> (1:CKF_DONT_BLOCK)", flags );
+        Log::log( "C_WaitForSlotEvent - pSlot <%ld>", *pSlot );
+        Log::log( "C_WaitForSlotEvent - pReserved <%#02x>", pReserved );
+
+        // Not Initialized
+        if( !g_isInitialized ) {
+
+            rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        
+        } else if( pReserved || !pSlot  ) {
+
+            rv = CKR_ARGUMENTS_BAD;
+        
+        } else {
+
+            // Block all other incoming calls to C_WaitForSlotEvent
+            {
+                boost::mutex::scoped_lock lock( io_mutex );
+
+                // Search for a state change into the known slots
+                Application::ARRAY_SLOTS sl = g_Application.getSlotList( );
+            
+                BOOST_FOREACH( const boost::shared_ptr< Slot >& s, sl ) {
+
+                    if( s.get( ) && s->getEvent( ) ) {
+
+                        *pSlot = s->getEventSlotId( );
+
+                        s->setEvent( false, 0xFF );
+
+                        Log::log( "C_WaitForSlotEvent -     slot <%ld>", *pSlot );
+                    
+                        rv = CKR_OK;
+                        
+                        break;
+                    }
+                }
+            }
+
+            if( ( CKR_OK != rv ) && ( CKF_DONT_BLOCK != ( flags & CKF_DONT_BLOCK ) ) ) {
+
+                Log::log( "C_WaitForSlotEvent -     Block until new smart card or reader event..." );
+
+                // Initialize the mutex to block the thread until a slot event arrives
+                boost::unique_lock<boost::mutex> lock( g_WaitForSlotEventMutex );
+
+                // Block and wait
+                g_WaitForSlotEventCondition.wait( lock );
+                Log::log( "WaitForSlotEvent -   Unblocked" );
+
+                if( g_bWaitForSlotEvent ) {
+
+                    // ??? TODO ??? lock this code section to modify the varaible in thread-safe mode
+                    g_bWaitForSlotEvent = false;
+
+                    Log::log( "WaitForSlotEvent -   Received a new event..." );
+
+                    // Block all other incoming calls to C_WaitForSlotEvent
+                    {
+                        boost::mutex::scoped_lock lock2( io_mutex );
+
+                        // Search for a state change into the known slots
+                        Application::ARRAY_SLOTS as = g_Application.getSlotList( );
+
+                        *pSlot = CK_UNAVAILABLE_INFORMATION;
+
+                        BOOST_FOREACH( const boost::shared_ptr< Slot >& s, as ) {
+
+                            if( s.get( ) && s->getEvent( ) ) {
+
+                                *pSlot = s->getEventSlotId( );
+
+                                s->setEvent( false, 0xFF );
+
+                                break;
+                            }
+                        }
+
+                        Log::log( "C_WaitForSlotEvent -     slot (Mode blocked) <%ld>", *pSlot );
+                                 
+                        rv = CKR_OK;
+                    }
+                }
+            }
+        }
+
+        Log::logCK_RV( "C_WaitForSlotEvent", rv );
+        Log::out( "C_WaitForSlotEvent" );
+        Log::log( "C_WaitForSlotEvent - flags <%ld> (1:CKF_DONT_BLOCK)", flags );
+        Log::log( "C_WaitForSlotEvent - pSlot <%ld>", *pSlot );
+        Log::log( "C_WaitForSlotEvent - pReserved <%#02x>", pReserved );
+        Log::end( "C_WaitForSlotEvent" );
+
+        return rv;
+    }
+
+
+    //// FUNCTION NOT SUPPORTED ////
+
+
+    /**
+    * C_GetFunctionStatus is a legacy function; it obtains an
+    * updated status of a function running in parallel with an
+    * application.
+    *
+    * @param hSession the session's handle
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetFunctionStatus )( CK_SESSION_HANDLE ) {
+
+        Log::begin( "C_GetFunctionStatus" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_GetFunctionStatus", rv );
+        Log::end( "C_GetFunctionStatus" );
+        return rv;
+    }
+
+
+    /**
+    * C_CancelFunction is a legacy function; it cancels a function
+    * running in parallel.
+    *
+    * @param hSession the session's handle
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_CancelFunction )( CK_SESSION_HANDLE ) {
+
+        Log::begin( "C_CancelFunction" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_CancelFunction", rv );
+        Log::end( "C_CancelFunction" );
+        return rv;
+    }
+
+
+    /**
+    * C_GetOperationState obtains the state of the cryptographic operation
+    * in a session.
+    *
+    * @param hSession session's handle
+    * @param pOperationState gets State
+    * @param pulOperationStateLen gets state length
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetOperationState )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_GetOperationState" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+        Log::logCK_RV( "C_GetOperationState", rv );
+        Log::end( "C_GetOperationState" );
+        return rv;
+    }
+
+
+    /**
+    * C_SetOperationState restores the state of the cryptographic
+    * operation in a session.
+    *
+    * @param hSession session's handle
+    * @param pOperationState hold state
+    * @param ulOperationStateLen holds state length
+    * @param hEncryptionKey en/decryption key
+    * @param hAuthenticationKey sig/verify key
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_SetOperationState )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE ) {
+
+        Log::begin( "C_SetOperationState" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+        Log::logCK_RV( "C_SetOperationState", rv );
+        Log::end( "C_SetOperationState" );
+        return rv;
+    }
+
+
+    /**
+    * C_WrapKey wraps (i.e., encrypts) a key.
+    *
+    * @param hSession              the session's handle
+    * @param pMechanism            the wrapping mechanism
+    * @param hWrappingKey          wrapping key
+    * @param hKey                  key to be wrapped
+    * @param pWrapperKey           gets wrapped key
+    * @param pulWrappedKeyLen      gets wrapped key size
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_WrapKey )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_WrapKey" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_WrapKey", rv );
+        Log::end( "C_WrapKey" );
+        return rv;
+    }
+
+
+    /**
+    * C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+    * key object.
+    *
+    * @param   hSession           session's handle
+    * @param   pMechanism         unwrapping mech.
+    * @param   hUnwrappingKey     unwrapping key
+    * @param   pWrappedKey        the wrapped key
+    * @param   ulWrappedKeyLen    wrapped key len
+    * @param   pTemplate          new key template
+    * @param   ulAttributeCount   template length
+    * @param   phKey              gets new handle
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV,C_UnwrapKey )(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ) {
+        Log::begin( "C_UnwrapKey" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_UnwrapKey", rv );
+        Log::end( "C_UnwrapKey" );
+        return rv;
+    }
+
+
+    /**
+    * C_DeriveKey derives a key from a base key, creating a new key
+    * object.
+    *
+    * @param hSession              session's handle
+    * @param pMechanism            key deriv. mech.
+    * @param hBaseKey              base key
+    * @param pTemplate             new key template
+    * @param ulAttributeCount      template length
+    * @param phKey                 gets new handle
+    *
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DeriveKey )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ) {
+
+        Log::begin( "C_DeriveKey" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DeriveKey", rv );
+        Log::end( "C_DeriveKey" );
+        return rv;
+    }
+
+
+    /**
+    * C_SeedRandom mixes additional seed material into the token's
+    * random number generator.
+    *
+    * @param hSession   the session's handle
+    * @param pSeed      the seed material
+    * @param ulSeedLen  length of seed material
+    */
+    CK_DEFINE_FUNCTION( CK_RV,C_SeedRandom )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG ) {
+
+        Log::begin( "C_SeedRandom" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_RANDOM_SEED_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_SeedRandom", rv );
+        Log::end( "C_SeedRandom" );
+        return rv;
+    }
+
+
+    /* C_VerifyRecoverInit initializes a signature verification operation, where the data is recovered from the signature. */
+    CK_DEFINE_FUNCTION( CK_RV, C_VerifyRecoverInit )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ) {
+
+        Log::begin( "C_VerifyRecoverInit" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_VerifyRecoverInit", rv );
+        Log::end( "C_VerifyRecoverInit" );
+        return rv;
+    }
+
+
+    /* C_VerifyRecover verifies a signature in a single-part
+    * operation, where the data is recovered from the signature. */
+    CK_DEFINE_FUNCTION( CK_RV, C_VerifyRecover )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_VerifyRecover" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_VerifyRecover", rv );
+        Log::end( "C_VerifyRecover" );
+        return rv;
+    }
+
+
+    /* C_DigestEncryptUpdate continues a multiple-part digesting and encryption operation. */
+    CK_DEFINE_FUNCTION( CK_RV, C_DigestEncryptUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_DigestEncryptUpdate" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DigestEncryptUpdate", rv );
+        Log::end( "C_DigestEncryptUpdate" );
+        return rv;
+    }
+
+
+    /* C_DecryptDigestUpdate continues a multiple-part decryption and digesting operation. */
+    CK_DEFINE_FUNCTION( CK_RV, C_DecryptDigestUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_DecryptDigestUpdate" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DecryptDigestUpdate", rv );
+        Log::end( "C_DecryptDigestUpdate" );
+        return rv;
+    }
+
+
+    /* C_SignEncryptUpdate continues a multiple-part signing and encryption operation. */
+    CK_DEFINE_FUNCTION( CK_RV, C_SignEncryptUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_SignEncryptUpdate" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_SignEncryptUpdate", rv );
+        Log::end( "C_SignEncryptUpdate" );
+        return rv;
+    }
+
+
+    /**
+    * C_DecryptVerifyUpdate continues a multiple-part decryption and verify operation. */
+    CK_DEFINE_FUNCTION( CK_RV, C_DecryptVerifyUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR , CK_ULONG_PTR ) {
+
+        Log::begin( "C_DecryptVerifyUpdate" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DecryptVerifyUpdate", rv );
+        Log::end( "C_DecryptVerifyUpdate" );
+        return rv;
+    }
+
+
+    /**
+    * C_GenerateKey generates a secret key, creating a new key object.
+    *
+    * @param    hSession,    the session's handle
+    * @param    pMechanism   key generation mech.
+    * @param    pTemplate    template for new key
+    * @param    ulCount      # of attrs in template
+    * @param    phKey        gets handle of new key
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_GenerateKey )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ) {
+
+        Log::begin( "C_GenerateKey" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_GenerateKey", rv );
+        Log::end( "C_GenerateKey" );
+        return rv;
+    }
+
+    /* C_SignRecoverInit initializes a signature operation, where the data can be recovered from the signature. */
+    CK_DEFINE_FUNCTION( CK_RV, C_SignRecoverInit )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE ) {
+
+        Log::begin( "C_SignRecoverInit" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_SignRecoverInit", rv );
+        Log::end( "C_SignRecoverInit" );
+        return rv;
+    }
+
+
+    /* C_SignRecover signs data in a single operation, where the data can be recovered from the signature. */
+    CK_DEFINE_FUNCTION( CK_RV, C_SignRecover )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_SignRecover" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_SignRecover", rv );
+        Log::end( "C_SignRecover" );
+        return rv;
+    }
+
+
+    /* C_CopyObject copies an object, creating a new object for the copy. */
+    CK_DEFINE_FUNCTION(CK_RV, C_CopyObject )( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR ) {
+
+        Log::begin( "C_CopyObject" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_CopyObject", rv );
+        Log::end( "C_CopyObject" );
+        return rv;
+    }
+
+
+    /* C_GetObjectSize gets the size of an object in bytes */
+    CK_DEFINE_FUNCTION( CK_RV, C_GetObjectSize )( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR ) {
+
+        Log::begin( "C_GetObjectSize" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_GetObjectSize", rv );
+        Log::end( "C_GetObjectSize" );
+        return rv;
+    }
+
+
+    /**
+    * C_EncryptUpdate continues a multiple-part encryption
+    * operation.
+    *
+    * @param hSession                  session's handle
+    * @param pPart                     the plaintext data
+    * @param ulPartLen                 plaintext data len
+    * @param pEncryptedPart            gets ciphertext
+    * @param pulEncryptedPartLen       gets c-text size
+    *
+    */
+    CK_DEFINE_FUNCTION(CK_RV,C_EncryptUpdate)( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_EncryptUpdate" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_EncryptUpdate", rv );
+        Log::end( "C_EncryptUpdate" );
+        return rv;
+    }
+
+
+    /**
+    * C_EncryptFinal finishes a multiple-part encryption
+    * operation.
+    *
+    * @param hSession                   session handle
+    * @param pLastEncryptedPart         last c-text
+    * @param pulLastEncryptedPartLen    gets last size
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_EncryptFinal )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_EncryptFinal" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_EncryptFinal", rv );
+        Log::end( "C_EncryptFinal" );
+        return rv;
+    }
+
+
+    /**
+    * C_DecryptUpdate continues a multiple-part decryption
+    * operation.
+    *
+    * @param hSession           session's handle
+    * @param pEncryptedPart     encrypted data
+    * @param ulEncryptedPart    input length
+    * @param pPart              gets plaintext
+    * @param pulPartLen         p-text size
+    */
+    CK_DEFINE_FUNCTION(CK_RV,C_DecryptUpdate)( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_DecryptUpdate" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DecryptUpdate", rv );
+        Log::end( "C_DecryptUpdate" );
+        return rv;
+    }
+
+
+    /**
+    * C_DecryptFinal finishes a multiple-part decryption
+    * operation.
+    *
+    * @param hSession           the session's handle
+    * @param pLastPart          gets plaintext
+    * @param pulLastPartLen     p-text size
+    */
+    CK_DEFINE_FUNCTION( CK_RV, C_DecryptFinal )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR ) {
+
+        Log::begin( "C_DecryptFinal" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DecryptFinal", rv );
+        Log::end( "C_DecryptFinal" );
+        return rv;
+    }
+
+
+    /* C_DigestKey continues a multi-part message-digesting operation, by digesting the value of a secret key as part of
+    * the data already digested. */
+    CK_DEFINE_FUNCTION( CK_RV, C_DigestKey )( CK_SESSION_HANDLE, CK_OBJECT_HANDLE ) {
+
+        Log::begin( "C_DigestKey" );
+
+        CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
+        if( g_isInitialized ) {
+
+            rv = CKR_FUNCTION_NOT_SUPPORTED;
+        }
+
+        Log::logCK_RV( "C_DigestKey", rv );
+        Log::end( "C_DigestKey" );
+        return rv;
+    }
+
+} // extern "C"

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Exception.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Exception.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Exception.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,50 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifndef __GEMALTO_PKCS11_EXCEPTION__
+#define __GEMALTO_PKCS11_EXCEPTION__
+
+
+#include <string>
+#include <stdexcept>
+
+
+/*
+*/
+class PKCS11Exception : public std::runtime_error {
+
+public:
+    
+	inline PKCS11Exception( ) : std::runtime_error( "" ), m_ulError( 0 ) { }
+    
+	inline PKCS11Exception( unsigned long a_ulError ) : std::runtime_error( "" ), m_ulError( a_ulError ) { }
+    
+	inline PKCS11Exception( const std::string& a_stMessage, unsigned long a_ulError = 0 ) : std::runtime_error( a_stMessage ), m_ulError( a_ulError ) { }
+
+    inline unsigned long getError( void ) const { return m_ulError; }
+
+private:
+
+    unsigned long m_ulError;
+
+};
+
+#endif // __GEMALTO_PKCS11_EXCEPTION__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,272 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectCertificate.hpp"
+#include "PKCS11Exception.hpp"
+
+
+CertificateObject::CertificateObject( ) : StorageObject( ) {
+
+    m_Class = CKO_CERTIFICATE;
+
+    _trusted   = CK_FALSE;
+
+    m_ucContainerIndex = 0xFF;
+
+    m_ucKeySpec  = 0xFF;
+
+    _certCategory = 0; // unspecified (default value)
+
+    _checkValue = 0;
+}
+
+
+bool CertificateObject::isEqual( StorageObject * that) const
+{
+    if( m_Class != that->getClass( ) ) {
+
+        return false;
+    }
+
+    const CertificateObject* thatCert = static_cast< const CertificateObject* >( that );
+
+    return ( ( m_ucContainerIndex == thatCert->m_ucContainerIndex ) && ( m_ucKeySpec == thatCert->m_ucKeySpec ) );
+}
+
+
+/*
+*/
+bool CertificateObject::compare( const CK_ATTRIBUTE& attribute ) {
+
+    switch( attribute.type ) {
+
+    case CKA_CERTIFICATE_TYPE:
+        return ( _certType == *(CK_ULONG*)attribute.pValue );
+
+    case CKA_CERTIFICATE_CATEGORY:
+        return (_certCategory == *(CK_ULONG*)attribute.pValue);
+
+    case CKA_TRUSTED:
+        return (_trusted == *(CK_BBOOL*)attribute.pValue);
+
+    case CKA_CHECK_VALUE:
+        return Util::compareU1Arrays( m_pCheckSum.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_START_DATE:
+        return Util::compareU1Arrays( m_pStartDate.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_END_DATE:
+        return Util::compareU1Arrays( m_pEndDate.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    default:
+        return StorageObject::compare( attribute );
+    }
+}
+
+
+/*
+*/
+void CertificateObject::setAttribute( const CK_ATTRIBUTE& a_Attribute, const bool& a_objCreation )
+{
+
+    //if( 0 == a_Attribute.ulValueLen ) {
+
+    //    return;
+    //}
+
+    if( !a_objCreation ) {
+
+        switch( a_Attribute.type ) {
+
+        case CKA_CERTIFICATE_TYPE:
+        case CKA_CERTIFICATE_CATEGORY:
+            throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+        }
+    }
+
+    switch( a_Attribute.type ) {
+
+    case CKA_CERTIFICATE_TYPE:
+        _certType = StorageObject::readULongFromAttribute( a_Attribute );
+        break;
+
+    case CKA_CERTIFICATE_CATEGORY:
+        _certCategory = StorageObject::readULongFromAttribute( a_Attribute );
+        break;
+
+    case CKA_TRUSTED:
+        _trusted = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_CHECK_VALUE:
+        m_pCheckSum.reset( StorageObject::readU1ArrayFromAttribute( a_Attribute ));
+        break;
+
+    case CKA_START_DATE:
+        m_pStartDate.reset( StorageObject::readDateFromAttribute( a_Attribute ));
+        break;
+
+    case CKA_END_DATE:
+        m_pEndDate.reset( StorageObject::readDateFromAttribute( a_Attribute ));
+        break;
+
+    default:
+        StorageObject::setAttribute( a_Attribute, a_objCreation );
+    }
+}
+
+
+void CertificateObject::getAttribute(CK_ATTRIBUTE_PTR attribute)
+{
+    switch(attribute->type){
+
+    case CKA_CERTIFICATE_TYPE:
+        StorageObject::putULongInAttribute(_certType,attribute);
+        break;
+
+    case CKA_CERTIFICATE_CATEGORY:
+        StorageObject::putULongInAttribute(_certCategory,attribute);
+        break;
+
+    case CKA_TRUSTED:
+        StorageObject::putBBoolInAttribute(_trusted,attribute);
+        break;
+
+    case CKA_CHECK_VALUE:
+        StorageObject::putU1ArrayInAttribute(m_pCheckSum.get( ),attribute);
+        break;
+
+    case CKA_START_DATE:
+        StorageObject::putU1ArrayInAttribute(m_pStartDate.get( ),attribute);
+        break;
+
+    case CKA_END_DATE:
+        StorageObject::putU1ArrayInAttribute(m_pEndDate.get( ),attribute);
+        break;
+
+    default:
+        StorageObject::getAttribute(attribute);
+        break;
+    }
+}
+
+
+void CertificateObject::serialize(std::vector<u1> *to)
+{
+    StorageObject::serialize(to);
+
+    Util::PushULongInVector(to,_certType);
+
+    Util::PushULongInVector(to,_certCategory);
+
+    Util::PushBBoolInVector(to,_trusted);
+
+    Util::PushByteArrayInVector(to,m_pStartDate.get( ));
+
+    Util::PushByteArrayInVector(to,m_pEndDate.get( ));
+
+    Util::PushByteArrayInVector(to,m_pCheckSum.get( ));
+
+    // serialize the extra fields
+    
+    Util::PushULongLongInVector( to,_checkValue );
+
+    Util::PushBBoolInVector(to,m_ucContainerIndex);
+
+    Util::PushBBoolInVector(to,m_ucKeySpec);
+}
+
+
+void CertificateObject::deserialize(std::vector<u1>& from, CK_ULONG_PTR idx)
+{
+    StorageObject::deserialize(from,idx);
+
+    _certType = Util::ReadULongFromVector(from,idx);
+
+    _certCategory = Util::ReadULongFromVector(from,idx);
+
+    _trusted = Util::ReadBBoolFromVector(from,idx);
+
+    m_pStartDate.reset( Util::ReadByteArrayFromVector(from,idx));
+
+    m_pEndDate.reset( Util::ReadByteArrayFromVector(from,idx));
+
+    m_pCheckSum.reset( Util::ReadByteArrayFromVector(from,idx));
+
+    // serialize the extra fields
+ 
+	// Read old checkvalue field
+    Util::ReadULongLongFromVector(from,idx);
+
+    m_ucContainerIndex = Util::ReadBBoolFromVector(from,idx);
+
+    m_ucKeySpec = Util::ReadBBoolFromVector(from,idx);
+}
+
+
+/*
+*/
+void CertificateObject::print( void ) {
+
+    StorageObject::print( );
+
+    Log::log( "CKA_CERTIFICATE_TYPE <%ld>", _certType );
+
+    Log::log( "CKA_TRUSTED <%ld>", _trusted );
+
+    Log::log( "CKA_CERTIFICATE_CATEGORY <%ld>", _certCategory );
+
+    if( m_pCheckSum ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_CHECK_VALUE", m_pCheckSum->GetBuffer( ), m_pCheckSum->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_CHECK_VALUE <null>" );
+    }
+
+    if( m_pStartDate ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_START_DATE", m_pStartDate->GetBuffer( ), m_pStartDate->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_START_DATE <null>" );
+    }
+
+    if( m_pEndDate ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_END_DATE", m_pEndDate->GetBuffer( ), m_pEndDate->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_END_DATE <null>" );
+    }
+
+
+    Log::log( "[Certificate Name <%s>]", m_stCertificateName.c_str( ) );
+
+    Log::log( "[Container Index <%d>]", m_ucContainerIndex );
+
+    Log::log( "[KeySpec <%d>]", m_ucKeySpec );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificate.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,74 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_OBJECT_CERTIFICATE__
+#define __GEMALTO_OBJECT_CERTIFICATE__
+
+
+#include <boost/shared_ptr.hpp>
+#include "Pkcs11ObjectStorage.hpp"
+
+
+class CertificateObject : public StorageObject {
+
+public:
+
+	CK_ULONG _certType;
+
+	CK_BBOOL _trusted;
+	
+    CK_ULONG _certCategory;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pCheckSum;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pStartDate;
+	
+   boost::shared_ptr< Marshaller::u1Array > m_pEndDate;
+
+	std::string m_stCertificateName;
+
+    unsigned char m_ucContainerIndex;
+	
+    unsigned char m_ucKeySpec;
+
+    u8 _checkValue;
+
+	CertificateObject( );
+
+    virtual ~CertificateObject( ) { }
+
+	virtual bool isEqual( StorageObject* ) const;
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+#endif //__GEMALTO_OBJECT_CERTIFICATE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,317 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectCertificateX509PublicKey.hpp"
+#include "PKCS11Exception.hpp"
+
+
+/*
+*/
+X509PubKeyCertObject::X509PubKeyCertObject( ) {
+
+	_certType = CKC_X_509;
+
+    _certCategory = 1; // Set as "token user"
+	
+    _trusted = CK_TRUE;
+    
+	m_bIsSmartCardLogon = false;
+
+    m_bIsRoot = false;
+}
+
+
+/*
+*/
+bool X509PubKeyCertObject::compare( const CK_ATTRIBUTE& a_Attribute ) {
+
+	switch( a_Attribute.type ) {
+
+	case CKA_SUBJECT:
+		return Util::compareU1Arrays( m_pSubject.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	case CKA_ID:
+        {
+            Log::logCK_UTF8CHAR_PTR( "X509PubKeyCertObject::compare - Attribute", (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+            if( m_pID.get( ) ) {
+            
+                Log::logCK_UTF8CHAR_PTR( "X509PubKeyCertObject::compare - CKA_ID", m_pID->GetBuffer( ), m_pID->GetLength( ) );
+            
+            } else {
+            
+                Log::log( "X509PubKeyCertObject::compare - CKA_ID <null>" );
+            }
+		
+            return Util::compareU1Arrays( m_pID.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+        }
+
+	case CKA_ISSUER:
+		return Util::compareU1Arrays( m_pIssuer.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	case CKA_SERIAL_NUMBER:
+		return Util::compareU1Arrays( m_pSerialNumber.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	case CKA_VALUE:
+		return Util::compareU1Arrays( m_pValue.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	case CKA_URL:
+		return Util::compareU1Arrays( m_pURL.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
+		return Util::compareU1Arrays( m_pHashOfSubjectPubKey.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
+		return Util::compareU1Arrays( m_pHashOfIssuerPubKey.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+	default:
+		return CertificateObject::compare( a_Attribute );
+	}
+}
+
+
+/*
+*/
+void X509PubKeyCertObject::setAttribute( const CK_ATTRIBUTE& attribute, const bool& objCreation ) {
+
+	//if( !attribute.ulValueLen ) {
+
+	//	return;
+	//}
+
+	if( !objCreation && ( ( CKA_SUBJECT == attribute.type ) || ( CKA_VALUE == attribute.type ) ) ) {
+
+			throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+	}
+
+	switch( attribute.type ) {
+
+	case CKA_SUBJECT:
+		m_pSubject.reset( StorageObject::readU1ArrayFromAttribute(attribute) );
+		break;
+
+	case CKA_ID:
+        m_pID.reset( StorageObject::readU1ArrayFromAttribute(attribute) );
+        break;
+
+	case CKA_ISSUER:
+		m_pIssuer.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+		break;
+
+	case CKA_SERIAL_NUMBER:
+		m_pSerialNumber.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+		break;
+
+	case CKA_VALUE:
+		m_pValue.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+		break;
+
+	case CKA_URL:
+		m_pURL.reset( StorageObject::/*readStringFromAttribute*/readU1ArrayFromAttribute( attribute ) );
+		break;
+
+	case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
+		m_pHashOfSubjectPubKey.reset( StorageObject::readU1ArrayFromAttribute(attribute) );
+		break;
+
+	case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
+		m_pHashOfIssuerPubKey.reset( StorageObject::readU1ArrayFromAttribute(attribute) );
+		break;
+
+	default:
+		CertificateObject::setAttribute( attribute, objCreation );
+	}
+}
+
+
+/*
+*/
+void X509PubKeyCertObject::getAttribute( CK_ATTRIBUTE_PTR attribute ) {
+
+	switch( attribute->type ) {
+
+	case CKA_SUBJECT:
+		StorageObject::putU1ArrayInAttribute( m_pSubject.get( ), attribute );
+        break;
+
+	case CKA_ID:
+		StorageObject::putU1ArrayInAttribute( m_pID.get( ),attribute);
+        break;
+
+	case CKA_ISSUER:
+		StorageObject::putU1ArrayInAttribute(m_pIssuer.get( ),attribute);
+        break;
+
+    case CKA_SERIAL_NUMBER:
+		StorageObject::putU1ArrayInAttribute(m_pSerialNumber.get( ),attribute);
+        break;
+
+	case CKA_VALUE:
+		StorageObject::putU1ArrayInAttribute(m_pValue.get( ),attribute);
+        break;
+
+	case CKA_URL:
+		StorageObject::putU1ArrayInAttribute(m_pURL.get( ),attribute);
+        break;
+
+	case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
+		StorageObject::putU1ArrayInAttribute(m_pHashOfSubjectPubKey.get( ),attribute);
+        break;
+
+	case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
+		StorageObject::putU1ArrayInAttribute(m_pHashOfIssuerPubKey.get( ),attribute);
+        break;
+
+	default:
+		CertificateObject::getAttribute(attribute);
+        break;
+	}
+}
+
+
+/*
+*/
+void X509PubKeyCertObject::serialize(std::vector<u1> *to)
+{
+	CertificateObject::serialize(to);
+
+	Util::PushByteArrayInVector( to, m_pSubject.get( ) );
+
+	Util::PushByteArrayInVector(to, m_pID.get( ) );
+
+	Util::PushByteArrayInVector(to,m_pIssuer.get( ) );
+
+	Util::PushByteArrayInVector(to,m_pSerialNumber.get( ) );
+
+	Util::PushByteArrayInVector(to,m_pURL.get( ) );
+
+	Util::PushByteArrayInVector(to,m_pHashOfSubjectPubKey.get( ) );
+
+	Util::PushByteArrayInVector(to,m_pHashOfIssuerPubKey.get( ) );
+}
+
+ 
+/*
+*/
+void X509PubKeyCertObject::deserialize(std::vector<u1>& from, CK_ULONG_PTR idx)
+{
+	CertificateObject::deserialize(from,idx);
+
+	m_pSubject.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+	m_pID.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+	m_pIssuer.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+	m_pSerialNumber.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+	m_pURL.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+	m_pHashOfSubjectPubKey.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+	m_pHashOfIssuerPubKey.reset( Util::ReadByteArrayFromVector( from, idx ) );
+}
+
+
+/*
+*/
+void X509PubKeyCertObject::print( void ) {
+
+    CertificateObject::print( );
+
+    if( m_pSubject.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_SUBJECT", m_pSubject->GetBuffer( ), m_pSubject->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_SUBJECT <null>" );
+    }
+
+    if( m_pID.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_ID", m_pID->GetBuffer( ), m_pID->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_ID <null>" );
+    }
+
+    if( m_pIssuer.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_ISSUER", m_pIssuer->GetBuffer( ), m_pIssuer->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_ISSUER <null>" );
+    }
+
+    if( m_pSerialNumber.get( ) ) {
+    
+        Log::logCK_UTF8CHAR_PTR( "CKA_SERIAL_NUMBER", m_pSerialNumber->GetBuffer( ), m_pSerialNumber->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_SERIAL_NUMBER <null>" );
+    }
+
+    if( m_pValue.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_VALUE", m_pValue->GetBuffer( ), m_pValue->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_VALUE <null>" );
+    }
+
+    if( m_pURL.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_URL", m_pURL->GetBuffer( ), m_pURL->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_URL <null>" );
+    }
+
+    if( m_pHashOfSubjectPubKey.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_HASH_OF_SUBJECT_PUBLIC_KEY", m_pHashOfSubjectPubKey->GetBuffer( ), m_pHashOfSubjectPubKey->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_HASH_OF_SUBJECT_PUBLIC_KEY <null>" );
+    }
+
+    if( m_pHashOfIssuerPubKey.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_HASH_OF_ISSUER_PUBLIC_KEY", m_pHashOfIssuerPubKey->GetBuffer( ), m_pHashOfIssuerPubKey->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_HASH_OF_ISSUER_PUBLIC_KEY <null>" );
+    }
+
+    Log::log( "[IsSmartCardLogon <%d>]", m_bIsSmartCardLogon );
+
+    Log::log( "[IsRoot <%d>]", m_bIsRoot );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectCertificateX509PublicKey.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,75 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_OBJECT_CERTIFICATE_X509_PUBLIC_KEY__
+#define __GEMALTO_OBJECT_CERTIFICATE_X509_PUBLIC_KEY__
+
+
+#include <boost/shared_ptr.hpp>
+#include "Pkcs11ObjectCertificate.hpp"
+
+
+class X509PubKeyCertObject : public CertificateObject {
+
+public:
+
+    boost::shared_ptr< Marshaller::u1Array > m_pSubject;
+
+    boost::shared_ptr< Marshaller::u1Array > m_pID;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pIssuer;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pSerialNumber;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pValue;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pURL;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pHashOfSubjectPubKey;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pHashOfIssuerPubKey;
+
+    bool m_bIsSmartCardLogon;
+
+    bool m_bIsRoot;
+
+	boost::shared_ptr< Marshaller::u1Array > m_pModulus;
+
+
+	X509PubKeyCertObject( );
+
+    virtual ~X509PubKeyCertObject( ) { }
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+#endif //__GEMALTO_OBJECT_CERTIFICATE_X509_PUBLIC_KEY__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,158 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectData.hpp"
+
+
+DataObject::DataObject( ) : StorageObject( ) {
+
+   m_Class = CKO_DATA;
+}
+
+
+bool DataObject::compare( const CK_ATTRIBUTE& attribute ) {
+
+   bool bRet = false;
+
+   switch(attribute.type)
+   {
+   case CKA_APPLICATION:
+       bRet = Util::compareU1Arrays( m_pApplicationName.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+      break;
+
+   case CKA_OBJECT_ID:
+      bRet = Util::compareU1Arrays( m_pID.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+      break;
+
+   case CKA_VALUE:
+      bRet = Util::compareU1Arrays( m_pValue.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+      break;
+
+   default:
+      bRet = StorageObject::compare( attribute );
+      break;
+   }
+
+   return bRet;
+}
+
+void DataObject::setAttribute( const CK_ATTRIBUTE& attribute, const bool& objCreation)
+{
+   if( !attribute.ulValueLen )
+   {
+      return;
+   }
+
+   switch(attribute.type){
+
+        case CKA_APPLICATION:
+            m_pApplicationName.reset( StorageObject::/*readStringFromAttribute*/readU1ArrayFromAttribute(attribute ) );
+           break;
+
+        case CKA_OBJECT_ID:
+           m_pID.reset( StorageObject::readU1ArrayFromAttribute(attribute) );
+           break;
+
+        case CKA_VALUE:
+           m_pValue.reset( StorageObject::readU1ArrayFromAttribute(attribute) );
+           break;
+
+        default:
+           StorageObject::setAttribute(attribute,objCreation);
+   }
+}
+
+
+void DataObject::getAttribute(CK_ATTRIBUTE_PTR attribute)
+{
+   switch(attribute->type)
+   {
+   case CKA_APPLICATION:
+      StorageObject::putU1ArrayInAttribute( m_pApplicationName.get( ), attribute);
+      break;
+
+   case CKA_OBJECT_ID:
+      StorageObject::putU1ArrayInAttribute( m_pID.get( ), attribute);
+      break;
+
+   case CKA_VALUE:
+      StorageObject::putU1ArrayInAttribute( m_pValue.get( ), attribute);
+      break;
+
+   default:
+      StorageObject::getAttribute(attribute);
+      break;
+   }
+}
+
+
+void DataObject::serialize(std::vector<u1>* to)
+{
+   // first go ahead and serialize the fields in base class
+   StorageObject::serialize(to);
+
+   // serialize label attribute
+   Util::PushByteArrayInVector(to, m_pApplicationName.get( ) );
+
+   // serialize label attribute
+   Util::PushByteArrayInVector(to,m_pID.get( ) );
+
+   // serialize label attribute
+   Util::PushByteArrayInVector(to, m_pValue.get( ) );
+}
+
+
+void DataObject::deserialize(std::vector<u1>& from,CK_ULONG_PTR idx)
+{
+   // first go ahead and de-serialize the fields in base class
+   StorageObject::deserialize(from,idx);
+
+   m_pApplicationName.reset( Util::ReadByteArrayFromVector(from,idx) );
+
+   m_pID.reset( Util::ReadByteArrayFromVector(from,idx) );
+
+   m_pValue.reset( Util::ReadByteArrayFromVector(from,idx) );
+}
+
+
+/*
+*/
+void DataObject::print( void ) {
+
+    StorageObject::print( );
+
+    if( m_pApplicationName ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_APPLICATION", m_pApplicationName->GetBuffer( ), m_pApplicationName->GetLength( ) );
+    }
+
+    if( m_pID ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_OBJECT_ID", m_pID->GetBuffer( ), m_pID->GetLength( ) );
+    }
+
+    if( m_pValue ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_VALUE", m_pValue->GetBuffer( ), m_pValue->GetLength( ) );
+    }
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectData.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,59 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_OBJECT_DATA__
+#define __GEMALTO_OBJECT_DATA__
+
+
+#include <boost/shared_ptr.hpp>
+#include "Pkcs11ObjectStorage.hpp"
+
+
+class DataObject : public StorageObject {
+
+public:
+
+	boost::shared_ptr< Marshaller::u1Array > m_pApplicationName;
+
+	boost::shared_ptr< Marshaller::u1Array > m_pID;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pValue;
+
+	DataObject( );
+
+    virtual ~DataObject( ) { }
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+
+#endif

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,360 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectKey.hpp"
+#include "PKCS11Exception.hpp"
+
+
+/*
+*/
+KeyObject::KeyObject( ) : StorageObject( ) {
+
+    _keyType = 0;
+
+    _derive = CK_FALSE;
+
+    _local = CK_FALSE;
+
+    _mechanismType = CK_UNAVAILABLE_INFORMATION;
+
+    m_ucContainerIndex = 0xFF;
+
+    m_ucKeySpec = 0;
+}
+
+
+KeyObject::KeyObject( const KeyObject* p ) : StorageObject( *p ) {
+
+    if( p ) {
+
+        _keyType = p->_keyType;
+
+        _local = p->_local;
+
+        _mechanismType = p->_mechanismType;
+
+        m_ucContainerIndex = p->m_ucContainerIndex;
+
+        m_ucKeySpec = p->m_ucKeySpec;
+
+        _derive = p->_derive;
+
+        if( p->m_pID.get( ) ) {
+
+            Marshaller::u1Array* a = new Marshaller::u1Array( *( p->m_pID.get( ) ) );
+
+            m_pID.reset( a );
+
+        } else {
+
+            m_pID.reset( );
+        }
+
+        if( p->m_pStartDate.get( ) ) {
+
+            Marshaller::u1Array* a = new Marshaller::u1Array( *( p->m_pStartDate.get( ) ) );
+
+            m_pStartDate.reset( a );
+
+        } else {
+
+            m_pStartDate.reset( );
+        }
+
+        if( p->m_pEndDate.get( ) ) {
+
+            Marshaller::u1Array* a = new Marshaller::u1Array( *( p->m_pEndDate.get( ) ) );
+
+            m_pEndDate.reset( a );
+
+        } else {
+
+            m_pEndDate.reset( );
+        }
+
+        if( p->m_pAllowedMechanism.get( ) ) {
+
+            Marshaller::u4Array* a = new Marshaller::u4Array( *( p->m_pAllowedMechanism.get( ) ) );
+
+            m_pAllowedMechanism.reset( a );
+
+        } else {
+
+            m_pAllowedMechanism.reset( );
+        }
+
+    } else {
+
+    _keyType = 0;
+
+    _local = CK_FALSE;
+
+    _mechanismType = CK_UNAVAILABLE_INFORMATION;
+
+    m_ucContainerIndex = 0xFF;
+
+    m_ucKeySpec = 0;
+        _derive = CK_FALSE;
+
+        m_pID.reset( );
+        m_pStartDate.reset( );
+        m_pEndDate.reset( );
+        m_pAllowedMechanism.reset( );
+    }
+}
+
+
+/*
+*/
+bool KeyObject::compare( const CK_ATTRIBUTE& a_Attribute ) {
+
+    switch( a_Attribute.type ) {
+
+    case CKA_KEY_TYPE:
+        return (_keyType == *(CK_ULONG*)a_Attribute.pValue);
+
+    case CKA_ID:
+        return Util::compareU1Arrays( m_pID.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+    case CKA_START_DATE:
+        return Util::compareU1Arrays( m_pStartDate.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+    case CKA_END_DATE:
+        return Util::compareU1Arrays( m_pEndDate.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+    case CKA_LOCAL:
+        return (_local == *(CK_BBOOL*)a_Attribute.pValue);
+
+    case CKA_DERIVE:
+        return (_derive == *(CK_BBOOL*)a_Attribute.pValue);
+
+    case CKA_MECHANISM_TYPE:
+        return (_mechanismType == *(CK_ULONG*)a_Attribute.pValue);
+
+    case CKA_ALLOWED_MECHANISMS:
+        return Util::compareU4Arrays(m_pAllowedMechanism.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+    default:
+        return StorageObject::compare( a_Attribute );
+
+    }
+}
+
+void KeyObject::setAttribute( const CK_ATTRIBUTE& a_Attribute, const bool& objCreation ) {
+
+    if( !a_Attribute.ulValueLen )
+    {
+        return;
+    }
+
+    if( !objCreation ){
+
+        switch(a_Attribute.type){
+
+        case CKA_KEY_TYPE:
+        case CKA_LOCAL:
+        case CKA_MECHANISM_TYPE:
+            throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+        }
+    }
+
+    switch(a_Attribute.type){
+
+    case CKA_KEY_TYPE:
+        _keyType = StorageObject::readULongFromAttribute( a_Attribute );
+        break;
+
+    case CKA_ID:
+        m_pID.reset( StorageObject::readU1ArrayFromAttribute( a_Attribute ) );
+        break;
+
+    case CKA_START_DATE:
+        m_pStartDate.reset( StorageObject::readDateFromAttribute( a_Attribute ) );
+        break;
+
+    case CKA_END_DATE:
+        m_pEndDate.reset( StorageObject::readDateFromAttribute( a_Attribute ) );
+        break;
+
+    case CKA_LOCAL:
+        _local = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_DERIVE:
+        _derive = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_MECHANISM_TYPE:
+        _mechanismType = StorageObject::readULongFromAttribute( a_Attribute );
+        break;
+
+    case CKA_ALLOWED_MECHANISMS:
+        m_pAllowedMechanism.reset( new Marshaller::u4Array( a_Attribute.ulValueLen / 4 ) );
+        memcpy( (unsigned char*)m_pAllowedMechanism->GetBuffer( ), (CK_BYTE_PTR)a_Attribute.pValue, a_Attribute.ulValueLen );
+        break;
+
+    default:
+        StorageObject::setAttribute( a_Attribute, objCreation );
+
+    }
+}
+
+
+/*
+*/
+void KeyObject::getAttribute( CK_ATTRIBUTE_PTR a_Attribute ) {
+
+    switch( a_Attribute->type ) {
+
+    case CKA_KEY_TYPE:
+        StorageObject::putULongInAttribute( _keyType, a_Attribute );
+        break;
+
+    case CKA_ID:
+        StorageObject::putU1ArrayInAttribute( m_pID.get( ), a_Attribute );
+        break;
+
+    case CKA_START_DATE:
+        StorageObject::putU1ArrayInAttribute( m_pStartDate.get( ), a_Attribute );
+        break;
+
+    case CKA_END_DATE:
+        StorageObject::putU1ArrayInAttribute( m_pEndDate.get( ), a_Attribute );
+        break;
+
+    case CKA_LOCAL:
+        return StorageObject::putBBoolInAttribute(_local,a_Attribute);
+        break;
+
+    case CKA_DERIVE:
+        StorageObject::putBBoolInAttribute( _derive, a_Attribute );
+        break;
+
+    case CKA_MECHANISM_TYPE:
+        StorageObject::putULongInAttribute( _mechanismType, a_Attribute );
+        break;
+
+    case CKA_ALLOWED_MECHANISMS:
+        StorageObject::putU4ArrayInAttribute( m_pAllowedMechanism.get( ), a_Attribute );
+        break;
+
+    default:
+        StorageObject::getAttribute( a_Attribute );
+        break;
+    }
+}
+
+
+/*
+*/
+void KeyObject::serialize( std::vector<u1> *to ) {
+
+    StorageObject::serialize( to );
+
+    Util::PushULongInVector( to, _keyType );
+
+    Util::PushByteArrayInVector( to, m_pID.get( ) );
+
+    Util::PushByteArrayInVector( to, m_pStartDate.get( ) );
+
+    Util::PushByteArrayInVector( to, m_pEndDate.get( ) );
+
+    Util::PushBBoolInVector( to,_local );
+
+    Util::PushBBoolInVector( to,_derive );
+
+    Util::PushULongInVector( to, _mechanismType );
+
+    Util::PushIntArrayInVector(to, m_pAllowedMechanism.get( ) );
+}
+
+
+/*
+*/
+void KeyObject::deserialize( std::vector<u1>& from, CK_ULONG_PTR idx ) {
+
+    StorageObject::deserialize(from,idx);
+
+    _keyType = Util::ReadULongFromVector(from,idx);
+
+    m_pID.reset( Util::ReadByteArrayFromVector(from,idx) );
+
+    m_pStartDate.reset( Util::ReadByteArrayFromVector(from,idx) );
+
+    m_pEndDate.reset( Util::ReadByteArrayFromVector(from,idx) );
+
+    _local = Util::ReadBBoolFromVector(from,idx);
+
+    _derive = Util::ReadBBoolFromVector(from,idx);
+
+    _mechanismType = Util::ReadULongFromVector(from,idx);
+
+    m_pAllowedMechanism.reset( Util::ReadIntArrayFromVector(from,idx) );
+}
+
+
+/*
+*/
+void KeyObject::print( void ) {
+
+    StorageObject::print( );
+
+    Log::log( "CKA_KEY_TYPE <%ld>", _keyType );
+
+    Log::log( "CKA_DERIVE <%ld>", _derive );
+
+    Log::log( "CKA_LOCAL <%ld>", _local );
+
+    Log::log( "CKA_KEY_GEN_MECHANISM <%ld>", _mechanismType );
+
+    if( m_pID.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_ID", m_pID->GetBuffer( ), m_pID->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_ID <null>" );
+    }
+
+    if( m_pStartDate.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_START_DATE", m_pStartDate->GetBuffer( ), m_pStartDate->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_START_DATE <null>" );
+    }
+
+    if( m_pEndDate.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_END_DATE", m_pEndDate->GetBuffer( ), m_pEndDate->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_END_DATE <null>" );
+    }
+
+    Log::log( "[Container Index <%d>]", m_ucContainerIndex );
+
+    Log::log( "[KeySpec <%d>]", m_ucKeySpec );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKey.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,75 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMLATO_OBJECT_KEY__
+#define __GEMLATO_OBJECT_KEY__
+
+
+#include <boost/shared_ptr.hpp>
+#include "Pkcs11ObjectStorage.hpp"
+
+
+class KeyObject : public StorageObject {
+
+public:
+
+	CK_ULONG _keyType;
+
+	boost::shared_ptr< Marshaller::u1Array > m_pID;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pStartDate;
+	
+    boost::shared_ptr< Marshaller::u1Array > m_pEndDate;
+	
+    CK_BBOOL _derive;
+	
+    CK_BBOOL _local;
+	
+    CK_ULONG _mechanismType;
+	
+    boost::shared_ptr< Marshaller::u4Array > m_pAllowedMechanism;
+
+   	unsigned char m_ucContainerIndex;
+	
+	unsigned char m_ucKeySpec;
+
+
+	KeyObject( );
+
+	KeyObject( const KeyObject * );
+
+    virtual ~KeyObject( ) { }
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+#endif //__GEMLATO_OBJECT_KEY__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,417 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectKeyPrivate.hpp"
+#include "PKCS11Exception.hpp"
+
+
+PrivateKeyObject :: PrivateKeyObject( ) : KeyObject( ) {
+
+    m_Class = CKO_PRIVATE_KEY;
+    _sensitive = CK_TRUE;
+    _decrypt = CK_TRUE;
+    _sign = CK_TRUE;
+    _signRecover = CK_TRUE;
+    _unwrap = CK_FALSE;
+    _extractable = CK_FALSE;
+    _alwaysSensitive = CK_TRUE;
+    _neverExtractable = CK_TRUE;
+    _wrapWithTrusted = CK_FALSE;
+    _alwaysAuthenticate = CK_FALSE;
+    _keyType = CK_UNAVAILABLE_INFORMATION;
+    _checkValue = 0;
+}
+
+
+PrivateKeyObject :: PrivateKeyObject( const PrivateKeyObject* p ) : KeyObject( p ) {
+
+    if( p ) {
+
+        m_Class = p->m_Class;
+        _sensitive = p->_sensitive;
+        _decrypt = p->_decrypt;
+        _sign = p->_sign;
+        _signRecover = p->_signRecover;
+        _unwrap = p->_unwrap;
+        _extractable = p->_extractable;
+        _alwaysSensitive = p->_alwaysSensitive;
+        _neverExtractable = p->_neverExtractable;
+        _wrapWithTrusted = p->_wrapWithTrusted;
+        _alwaysAuthenticate = p->_alwaysAuthenticate;
+        _keyType  = p->_keyType;
+        _checkValue = p->_checkValue;
+
+    } else {
+
+        m_Class = CKO_PRIVATE_KEY;
+        _sensitive = CK_TRUE;
+        _decrypt = CK_TRUE;
+        _sign = CK_TRUE;
+        _signRecover = CK_TRUE;
+        _unwrap = CK_FALSE;
+        _extractable = CK_FALSE;
+        _alwaysSensitive = CK_TRUE;
+        _neverExtractable = CK_TRUE;
+        _wrapWithTrusted = CK_FALSE;
+        _alwaysAuthenticate = CK_FALSE;
+        _keyType = CK_UNAVAILABLE_INFORMATION;
+        _checkValue = 0;
+    }
+}
+
+
+
+bool PrivateKeyObject::isEqual( StorageObject * that) const
+{
+    if( m_Class != that->getClass( ) ) {
+
+        return false;
+    }
+
+    const PrivateKeyObject * thatCert = static_cast< const PrivateKeyObject* >( that );
+
+    return ( (m_ucContainerIndex == thatCert->m_ucContainerIndex) && (m_ucKeySpec == thatCert->m_ucKeySpec) );
+}
+
+bool PrivateKeyObject::compare( const CK_ATTRIBUTE& attribute)
+{
+    switch(attribute.type){
+
+        case CKA_SENSITIVE:
+            return (_sensitive == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_DECRYPT:
+            return (_decrypt == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_SIGN:
+            return (_sign == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_SIGN_RECOVER:
+            return (_signRecover == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_UNWRAP:
+            return (_unwrap == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_EXTRACTABLE:
+            return (_extractable == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_ALWAYS_SENSITIVE:
+            return (_alwaysSensitive == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_NEVER_EXTRACTABLE:
+            return (_neverExtractable == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_WRAP_WITH_TRUSTED:
+            return (_wrapWithTrusted == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_ALWAYS_AUTHENTICATE:
+            return (_alwaysAuthenticate == *(CK_BBOOL*)attribute.pValue);
+
+        case CKA_SUBJECT:
+            return Util::compareU1Arrays( m_pSubject.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+        default:
+            return KeyObject::compare(attribute);
+
+    }
+}
+
+void PrivateKeyObject::getAttribute( CK_ATTRIBUTE_PTR attribute )
+{
+    switch(attribute->type){
+
+        case CKA_SENSITIVE:
+            StorageObject::putBBoolInAttribute(_sensitive,attribute);
+        break;
+
+        case CKA_DECRYPT:
+            StorageObject::putBBoolInAttribute(_decrypt,attribute);
+        break;
+
+        case CKA_SIGN:
+            StorageObject::putBBoolInAttribute(_sign,attribute);
+        break;
+
+        case CKA_SIGN_RECOVER:
+            StorageObject::putBBoolInAttribute(_signRecover,attribute);
+        break;
+
+        case CKA_UNWRAP:
+            StorageObject::putBBoolInAttribute(_unwrap,attribute);
+        break;
+
+        case CKA_EXTRACTABLE:
+            StorageObject::putBBoolInAttribute(_extractable,attribute);
+        break;
+
+        case CKA_ALWAYS_SENSITIVE:
+            StorageObject::putBBoolInAttribute(_alwaysSensitive,attribute);
+        break;
+
+        case CKA_NEVER_EXTRACTABLE:
+            StorageObject::putBBoolInAttribute(_neverExtractable,attribute);
+        break;
+
+        case CKA_WRAP_WITH_TRUSTED:
+            StorageObject::putBBoolInAttribute(_wrapWithTrusted,attribute);
+        break;
+
+        case CKA_ALWAYS_AUTHENTICATE:
+            StorageObject::putBBoolInAttribute(_alwaysAuthenticate,attribute);
+        break;
+
+        case CKA_SUBJECT:
+            StorageObject::putU1ArrayInAttribute( m_pSubject.get( ), attribute );
+        break;
+
+        default:
+            KeyObject::getAttribute(attribute);
+        break;
+    }
+}
+
+
+/*
+*/
+void PrivateKeyObject::setAttribute( const CK_ATTRIBUTE& a_Attribute, const bool& objCreation ) {
+
+   if( !a_Attribute.ulValueLen )
+   {
+      return;
+   }
+
+    if( !objCreation )
+    {
+        switch( a_Attribute.type )
+        {
+            case CKA_ALWAYS_AUTHENTICATE:
+            case CKA_ALWAYS_SENSITIVE:
+            case CKA_NEVER_EXTRACTABLE:
+                throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+
+            case CKA_DECRYPT:
+            case CKA_EXTRACTABLE:
+            case CKA_SENSITIVE:
+            case CKA_SIGN:
+            case CKA_SIGN_RECOVER:
+            case CKA_UNWRAP:
+            case CKA_WRAP_WITH_TRUSTED:
+                if( *(CK_BBOOL*)a_Attribute.pValue ) {
+
+                    throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+                }
+                break;
+        }
+    }
+
+    switch(a_Attribute.type){
+
+        case CKA_SENSITIVE:
+            {
+                CK_BBOOL btemp = StorageObject::readBBoolFromAttribute( a_Attribute );
+
+                    if( !objCreation && _sensitive && !btemp ) {
+
+                        throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+                    
+					}else{
+
+                        _sensitive = btemp;
+
+                        if( !btemp ){
+
+                            _alwaysSensitive = CK_FALSE;
+                        }
+                    }
+            }
+            break;
+
+        case CKA_DECRYPT:
+            _decrypt = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_SIGN:
+            _sign = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_SIGN_RECOVER:
+            _signRecover = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_UNWRAP:
+            _unwrap = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_EXTRACTABLE:
+            {
+                CK_BBOOL btemp = StorageObject::readBBoolFromAttribute( a_Attribute );
+
+                    if( !objCreation && !_extractable && btemp ) {
+
+                        throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+
+                    } else {
+
+                        _extractable = btemp;
+
+                        if( btemp ) {
+
+                            _neverExtractable = CK_FALSE;
+                        }
+                    }
+            }
+            break;
+
+        case CKA_ALWAYS_SENSITIVE:
+            _alwaysSensitive = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+
+        case CKA_NEVER_EXTRACTABLE:
+            _neverExtractable = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_WRAP_WITH_TRUSTED:
+            _wrapWithTrusted = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_ALWAYS_AUTHENTICATE:
+            _alwaysAuthenticate = StorageObject::readBBoolFromAttribute( a_Attribute );
+            break;
+
+        case CKA_SUBJECT:
+            m_pSubject.reset( StorageObject::readU1ArrayFromAttribute( a_Attribute ) );
+
+            break;
+
+        default:
+            KeyObject::setAttribute( a_Attribute, objCreation );
+    }
+}
+
+void PrivateKeyObject::serialize(std::vector<u1> *to)
+{
+    KeyObject::serialize(to);
+
+    Util::PushBBoolInVector(to,_sensitive);
+
+    Util::PushBBoolInVector(to,_decrypt);
+
+    Util::PushBBoolInVector(to,_sign);
+
+    Util::PushBBoolInVector(to,_signRecover);
+
+    Util::PushBBoolInVector(to,_unwrap);
+
+    Util::PushBBoolInVector(to,_extractable);
+
+    Util::PushBBoolInVector(to,_alwaysSensitive);
+
+    Util::PushBBoolInVector(to,_neverExtractable);
+
+    Util::PushBBoolInVector(to,_wrapWithTrusted);
+
+    Util::PushBBoolInVector(to,_alwaysAuthenticate);
+
+    Util::PushByteArrayInVector( to, m_pSubject.get( ) );
+
+    // serialize the extra fields
+
+    Util::PushULongLongInVector(to,_checkValue);
+
+    Util::PushBBoolInVector(to,m_ucContainerIndex);
+
+    Util::PushBBoolInVector(to,m_ucKeySpec);
+}
+
+void PrivateKeyObject::deserialize(std::vector<u1>& from, CK_ULONG_PTR idx)
+{
+    KeyObject::deserialize(from,idx);
+
+    _sensitive = Util::ReadBBoolFromVector(from,idx);
+
+    _decrypt = Util::ReadBBoolFromVector(from,idx);
+
+    _sign = Util::ReadBBoolFromVector(from,idx);
+
+    _signRecover = Util::ReadBBoolFromVector(from,idx);
+
+    _unwrap = Util::ReadBBoolFromVector(from,idx);
+
+    _extractable = Util::ReadBBoolFromVector(from,idx);
+
+    _alwaysSensitive = Util::ReadBBoolFromVector(from,idx);
+
+    _neverExtractable = Util::ReadBBoolFromVector(from,idx);
+
+    _wrapWithTrusted = Util::ReadBBoolFromVector(from,idx);
+
+    _alwaysAuthenticate = Util::ReadBBoolFromVector(from,idx);
+
+    m_pSubject.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+    // deserialize extra fields
+
+	/*u8 _checkValue = */Util::ReadULongLongFromVector(from,idx);
+
+    m_ucContainerIndex = Util::ReadBBoolFromVector(from,idx);
+
+    m_ucKeySpec = Util::ReadBBoolFromVector(from,idx);
+}
+
+
+/*
+*/
+void PrivateKeyObject::print( void ) {
+
+    KeyObject::print( );
+
+    if( m_pSubject.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_SUBJECT", m_pSubject->GetBuffer( ), m_pSubject->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_SUBJECT <null>" );
+    }
+
+    Log::log( "CKA_SENSITIVE <%ld>", _sensitive );
+        
+    Log::log( "CKA_DECRYPT <%ld>", _decrypt );
+
+    Log::log( "CKA_SIGN <%ld>", _sign );
+
+    Log::log( "CKA_SIGN_RECOVER <%ld>", _signRecover );
+
+    Log::log( "CKA_UNWRAP <%ld>", _unwrap );
+
+    Log::log( "CKA_EXTRACTABLE <%ld>", _extractable );
+
+    Log::log( "CKA_ALWAYS_SENSITIVE <%ld>", _alwaysSensitive );
+
+    Log::log( "CKA_NEVER_EXTRACTABLE <%ld>", _neverExtractable );
+
+    Log::log( "CKA_WRAP_WITH_TRUSTED <%ld>", _wrapWithTrusted );
+
+    Log::log( "CKA_ALWAYS_AUTHENTICATE <%ld>", _alwaysAuthenticate );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivate.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,79 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_OBJECT_KEY_PRIVATE__
+#define __GEMALTO_OBJECT_KEY_PRIVATE__
+
+
+#include "Pkcs11ObjectKey.hpp"
+
+
+class PrivateKeyObject : public KeyObject {
+
+public:
+
+	boost::shared_ptr< Marshaller::u1Array > m_pSubject;
+
+    CK_BBOOL     _sensitive;
+	
+    CK_BBOOL     _decrypt;
+	
+    CK_BBOOL     _sign;
+	
+    CK_BBOOL     _signRecover;
+	
+    CK_BBOOL     _unwrap;
+	
+    CK_BBOOL     _extractable;
+	
+    CK_BBOOL     _alwaysSensitive;
+	
+    CK_BBOOL     _neverExtractable;
+	
+    CK_BBOOL     _wrapWithTrusted;
+	
+    CK_BBOOL     _alwaysAuthenticate;
+
+    u8 _checkValue; 
+
+	PrivateKeyObject( );
+
+    PrivateKeyObject( const PrivateKeyObject* );
+
+    virtual ~PrivateKeyObject( ) { }
+
+	virtual bool isEqual( StorageObject * that) const;
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+#endif //__GEMALTO_OBJECT_KEY_PRIVATE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,424 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectKeyPrivateRSA.hpp"
+#include "PKCS11Exception.hpp"
+
+
+/*
+*/
+RSAPrivateKeyObject :: RSAPrivateKeyObject( ) : PrivateKeyObject( ) {
+
+    _keyType = CKK_RSA;
+
+    _mechanismType = CKM_RSA_PKCS_KEY_PAIR_GEN;
+}
+
+
+RSAPrivateKeyObject::RSAPrivateKeyObject( const RSAPrivateKeyObject* p ) : PrivateKeyObject( p ) {
+
+    if( p ) {
+
+        _keyType = p->_keyType;
+
+        _mechanismType = p->_mechanismType;
+
+        if( p->m_pPublicExponent.get( ) ) {
+
+            Marshaller::u1Array* e = new Marshaller::u1Array( *(p->m_pPublicExponent.get( )) );
+
+            m_pPublicExponent.reset( e );
+
+        } else {
+
+            m_pPublicExponent.reset( );
+        }
+
+        if( p->m_pModulus.get( ) ) {
+
+            Marshaller::u1Array* m = new Marshaller::u1Array( *(p->m_pModulus.get( )) );
+
+            m_pModulus.reset( m );
+
+        } else {
+
+            m_pModulus.reset( );
+        }
+
+        if( p->m_pPrivateExponent.get( ) ) {
+
+            Marshaller::u1Array* e = new Marshaller::u1Array( *(p->m_pPrivateExponent.get( )) );
+
+            m_pPrivateExponent.reset( e );
+
+        } else {
+
+            m_pPrivateExponent.reset( );
+        }
+
+        if( p->m_pPrime1.get( ) ) {
+
+            Marshaller::u1Array* m = new Marshaller::u1Array( *(p->m_pPrime1.get( )) );
+
+            m_pPrime1.reset( m );
+
+        } else {
+
+            m_pPrime1.reset( );
+        }
+
+        if( p->m_pPrime2.get( ) ) {
+
+            Marshaller::u1Array* m = new Marshaller::u1Array( *(p->m_pPrime2.get( )) );
+
+            m_pPrime2.reset( m );
+
+        } else {
+
+            m_pPrime2.reset( );
+        }
+
+        if( p->m_pExponent1.get( ) ) {
+
+            Marshaller::u1Array* e = new Marshaller::u1Array( *(p->m_pExponent1.get( )) );
+
+            m_pExponent1.reset( e );
+
+        } else {
+
+            m_pExponent1.reset( );
+        }
+
+        if( p->m_pExponent2.get( ) ) {
+
+            Marshaller::u1Array* e = new Marshaller::u1Array( *(p->m_pExponent2.get( )) );
+
+            m_pExponent2.reset( e );
+
+        } else {
+
+            m_pExponent2.reset( );
+        }
+
+        if( p->m_pCoefficient.get( ) ) {
+
+            Marshaller::u1Array* e = new Marshaller::u1Array( *(p->m_pCoefficient.get( )) );
+
+            m_pCoefficient.reset( e );
+
+        } else {
+
+            m_pCoefficient.reset( );
+        }
+
+    } else {
+
+    _keyType = CKK_RSA;
+
+    _mechanismType = CKM_RSA_PKCS_KEY_PAIR_GEN;
+        m_pPublicExponent.reset( );
+        m_pModulus.reset( );
+        m_pPrivateExponent.reset( );
+        m_pPrime1.reset( );
+        m_pPrime2.reset( );
+        m_pExponent1.reset( );
+        m_pExponent2.reset( );
+        m_pCoefficient.reset( );
+    }
+}
+
+
+/*
+*/
+bool RSAPrivateKeyObject::compare( const CK_ATTRIBUTE& attribute ) {
+
+    switch( attribute.type ) {
+
+    case CKA_MODULUS:
+        return Util::compareU1Arrays(m_pModulus.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_PUBLIC_EXPONENT:
+        return Util::compareU1Arrays(m_pPublicExponent.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_PRIVATE_EXPONENT:
+        return Util::compareU1Arrays(m_pPrivateExponent.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_PRIME_1:
+        return Util::compareU1Arrays(m_pPrime1.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_PRIME_2:
+        return Util::compareU1Arrays(m_pPrime2.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_EXPONENT_1:
+        return Util::compareU1Arrays(m_pExponent1.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_EXPONENT_2:
+        return Util::compareU1Arrays(m_pExponent2.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    case CKA_COEFFICIENT:
+        return Util::compareU1Arrays(m_pCoefficient.get( ), (unsigned char*)attribute.pValue, attribute.ulValueLen );
+
+    default:
+        return PrivateKeyObject::compare( attribute );
+    }
+}
+
+
+/*
+*/
+void RSAPrivateKeyObject::setAttribute( const CK_ATTRIBUTE& attribute, const bool& objCreation ) {
+
+    if( !attribute.ulValueLen ) {
+
+        return;
+    }
+
+    if( !objCreation ) {
+
+        switch( attribute.type ) {
+
+        case CKA_PUBLIC_EXPONENT:
+        case CKA_MODULUS:
+        case CKA_PRIVATE_EXPONENT:
+        case CKA_PRIME_1:
+        case CKA_PRIME_2:
+        case CKA_EXPONENT_1:
+        case CKA_EXPONENT_2:
+        case CKA_COEFFICIENT:
+            throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+        }
+    }
+
+    switch( attribute.type ) {
+
+    case CKA_MODULUS:
+        m_pModulus.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_PUBLIC_EXPONENT:
+        m_pPublicExponent.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_PRIVATE_EXPONENT:
+        m_pPrivateExponent.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_EXPONENT_1:
+        m_pExponent1.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_EXPONENT_2:
+        m_pExponent2.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_PRIME_1:
+        m_pPrime1.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_PRIME_2:
+        m_pPrime2.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    case CKA_COEFFICIENT:
+        m_pCoefficient.reset( StorageObject::readU1ArrayFromAttribute( attribute ) );
+        break;
+
+    default:
+        PrivateKeyObject::setAttribute( attribute, objCreation );
+        break;
+    }
+}
+
+
+void RSAPrivateKeyObject::getAttribute(CK_ATTRIBUTE_PTR attribute)
+{
+    switch(attribute->type){
+
+    case CKA_MODULUS:
+        StorageObject::putU1ArrayInAttribute( m_pModulus.get( ), attribute );
+        break;
+
+    case CKA_PUBLIC_EXPONENT:
+        StorageObject::putU1ArrayInAttribute( m_pPublicExponent.get( ), attribute );
+        break;
+
+    case CKA_PRIVATE_EXPONENT:
+        if(_sensitive || !_extractable){
+            attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
+            throw PKCS11Exception( CKR_ATTRIBUTE_SENSITIVE );
+        }
+        StorageObject::putU1ArrayInAttribute(m_pPrivateExponent.get( ),attribute);
+        break;
+
+    case CKA_PRIME_1:
+        if(_sensitive || !_extractable ){
+            attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
+            throw PKCS11Exception( CKR_ATTRIBUTE_SENSITIVE );
+        }
+        StorageObject::putU1ArrayInAttribute(m_pPrime1.get( ),attribute);
+        break;
+
+    case CKA_PRIME_2:
+        if(_sensitive || !_extractable ){
+            attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
+            throw PKCS11Exception( CKR_ATTRIBUTE_SENSITIVE );
+        }
+        StorageObject::putU1ArrayInAttribute(m_pPrime2.get( ),attribute);
+        break;
+
+    case CKA_EXPONENT_1:
+        if(_sensitive || !_extractable ){
+            attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
+            throw PKCS11Exception( CKR_ATTRIBUTE_SENSITIVE );
+        }
+        StorageObject::putU1ArrayInAttribute(m_pExponent1.get( ),attribute);
+        break;
+
+    case CKA_EXPONENT_2:
+        if(_sensitive || !_extractable ){
+            attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
+            throw PKCS11Exception( CKR_ATTRIBUTE_SENSITIVE );
+        }
+        StorageObject::putU1ArrayInAttribute(m_pExponent2.get( ),attribute);
+        break;
+
+    case CKA_COEFFICIENT:
+        if(_sensitive || !_extractable ){
+            attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
+            throw PKCS11Exception( CKR_ATTRIBUTE_SENSITIVE );
+        }
+        StorageObject::putU1ArrayInAttribute(m_pCoefficient.get( ),attribute);
+        break;
+
+    default:
+        PrivateKeyObject::getAttribute(attribute);
+        break;
+    }
+}
+
+
+/*
+*/
+void RSAPrivateKeyObject::serialize(std::vector<u1> *to)
+{
+    PrivateKeyObject::serialize(to);
+
+    // since keys will reside in the key container we are not going
+    // to marshal the key values except modulus and public exponent
+
+    Util::PushByteArrayInVector( to,m_pModulus.get( ) );
+
+    Util::PushByteArrayInVector( to, m_pPublicExponent.get( ) );
+}
+
+
+/*
+*/
+void RSAPrivateKeyObject::deserialize(std::vector<u1>& from, CK_ULONG_PTR idx)
+{
+    PrivateKeyObject::deserialize(from,idx);
+
+    m_pModulus.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+    m_pPublicExponent.reset( Util::ReadByteArrayFromVector( from, idx ) );
+}
+
+
+/*
+*/
+void RSAPrivateKeyObject::print( void ) {
+
+    PrivateKeyObject::print( );
+
+    if( m_pPublicExponent.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_PUBLIC_EXPONENT", m_pPublicExponent->GetBuffer( ), m_pPublicExponent->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_PUBLIC_EXPONENT <null>" );
+    }
+
+    if( m_pModulus.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_MODULUS", m_pModulus->GetBuffer( ), m_pModulus->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_MODULUS <null>" );
+    }
+
+    if( m_pPrivateExponent.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_PRIVATE_EXPONENT", m_pPrivateExponent->GetBuffer( ), m_pPrivateExponent->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_PRIVATE_EXPONENT <null>" );
+    }
+
+    if( m_pPrime1.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_PRIME_1", m_pPrime1->GetBuffer( ), m_pPrime1->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_PRIME_1 <null>" );
+    }
+
+    if( m_pPrime2.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_PRIME_2", m_pPrime2->GetBuffer( ), m_pPrime2->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_PRIME_2 <null>" );
+    }
+
+    if( m_pExponent1.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_EXPONENT_1", m_pExponent1->GetBuffer( ), m_pExponent1->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_EXPONENT_1 <null>" );
+    }
+
+    if( m_pExponent2.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_EXPONENT_2", m_pExponent2->GetBuffer( ), m_pExponent2->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_EXPONENT_2 <null>" );
+    }
+
+    if( m_pCoefficient.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_COEFFICIENT", m_pCoefficient->GetBuffer( ), m_pCoefficient->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_COEFFICIENT <null>" );
+    }
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPrivateRSA.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,78 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_OBJECT_KEY_PRIVATE_RSA__
+#define __GEMALTO_OBJECT_KEY_PRIVATE_RSA__
+
+
+#include <boost/shared_ptr.hpp>
+#include "Pkcs11ObjectKeyPrivate.hpp"
+
+
+class RSAPrivateKeyObject : public PrivateKeyObject {
+
+public:
+
+    // Attribute CKA_PUBLIC_EXPONENT (CRT public exponent e)
+	boost::shared_ptr< Marshaller::u1Array > m_pPublicExponent;
+	
+    // Attribute CKA_MODULUS (CRT modulus n)
+    boost::shared_ptr< Marshaller::u1Array > m_pModulus;
+    
+	// Attribute CKA_PRIVATE_EXPONENT (CRT private exponent d)
+    boost::shared_ptr< Marshaller::u1Array > m_pPrivateExponent;
+	
+    // Attribute CKA_PRIME_1 (CRT prime p)
+    boost::shared_ptr< Marshaller::u1Array > m_pPrime1;
+	
+    // Attribute CKA_PRIME_2 (CRT prime q)
+    boost::shared_ptr< Marshaller::u1Array > m_pPrime2;
+	
+    // Attribute CKA_EXPONENT_1 (CRT private exponent d modulo p-1)
+    boost::shared_ptr< Marshaller::u1Array > m_pExponent1;
+	
+    // Attribute CKA_EXPONENT_2 (CRT private exponent d modulo q-1)
+    boost::shared_ptr< Marshaller::u1Array > m_pExponent2;
+	
+    // Attribute CKA_COEFFICIENT (CRT coefficient q-1)
+    boost::shared_ptr< Marshaller::u1Array > m_pCoefficient;
+
+	RSAPrivateKeyObject( );
+
+	RSAPrivateKeyObject( const RSAPrivateKeyObject* );
+
+    virtual ~RSAPrivateKeyObject( ) { }
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+#endif // __GEMALTO_OBJECT_KEY_PRIVATE_RSA__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,252 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectKeyPublic.hpp"
+#include "PKCS11Exception.hpp"
+
+
+Pkcs11ObjectKeyPublic::Pkcs11ObjectKeyPublic( ) : KeyObject( ) {
+
+    m_Class         = CKO_PUBLIC_KEY;
+
+    _encrypt       = CK_TRUE;
+    _verify        = CK_TRUE;
+    _verifyRecover = CK_TRUE;
+    _wrap          = CK_FALSE;
+    _trusted = CK_TRUE;
+    _keyType  = CK_UNAVAILABLE_INFORMATION;
+}
+
+
+Pkcs11ObjectKeyPublic::Pkcs11ObjectKeyPublic( const Pkcs11ObjectKeyPublic* p ) : KeyObject( p ) {
+
+    m_Class = CKO_PUBLIC_KEY;
+
+    if( p ) {
+
+        _encrypt       = p->_encrypt;
+        _verify        = p->_verify;
+        _verifyRecover = p->_verifyRecover;
+        _wrap          = p->_wrap;
+        _keyType  = p->_keyType;
+        _trusted = p->_trusted;
+
+        if( p->m_pSubject.get( ) ) {
+
+            Marshaller::u1Array* pLabel = new Marshaller::u1Array( *(p->m_pSubject.get( )) );
+
+            m_pSubject.reset( pLabel );
+
+        } else {
+
+            m_pSubject.reset( );
+        }
+
+    } else {
+
+        _encrypt       = CK_TRUE;
+        _verify        = CK_TRUE;
+        _verifyRecover = CK_TRUE;
+        _wrap          = CK_FALSE;
+
+        _keyType  = CK_UNAVAILABLE_INFORMATION;
+
+        _trusted = CK_TRUE;
+
+        m_pSubject.reset( );
+    }
+}
+
+
+bool Pkcs11ObjectKeyPublic::compare( const CK_ATTRIBUTE& a_Attribute)
+{
+    switch(a_Attribute.type){
+
+    case CKA_ENCRYPT:
+        return (_encrypt == *(CK_BBOOL*)a_Attribute.pValue);
+
+    case CKA_VERIFY:
+        return (_verify == *(CK_BBOOL*)a_Attribute.pValue);
+
+    case CKA_VERIFY_RECOVER:
+        return (_verifyRecover == *(CK_BBOOL*)a_Attribute.pValue);
+
+    case CKA_WRAP:
+        return (_wrap == *(CK_BBOOL*)a_Attribute.pValue);
+
+    case CKA_SUBJECT:
+        return Util::compareU1Arrays( m_pSubject.get( ), (unsigned char*)a_Attribute.pValue, a_Attribute.ulValueLen );
+
+    default:
+        return KeyObject::compare(a_Attribute);
+    }
+}
+
+
+void Pkcs11ObjectKeyPublic::getAttribute(CK_ATTRIBUTE_PTR a_Attribute)
+{
+    switch(a_Attribute->type){
+
+    case CKA_ENCRYPT:
+        StorageObject::putBBoolInAttribute(_encrypt,a_Attribute);
+        break;
+
+    case CKA_VERIFY:
+        StorageObject::putBBoolInAttribute(_verify,a_Attribute);
+        break;
+
+    case CKA_VERIFY_RECOVER:
+        StorageObject::putBBoolInAttribute(_verifyRecover,a_Attribute);
+        break;
+
+    case CKA_WRAP:
+        StorageObject::putBBoolInAttribute(_wrap,a_Attribute);
+        break;
+
+    case CKA_SUBJECT:
+        StorageObject::putU1ArrayInAttribute( m_pSubject.get( ), a_Attribute );
+        break;
+
+    default:
+        KeyObject::getAttribute(a_Attribute);
+        break;
+
+    }
+}
+
+
+void Pkcs11ObjectKeyPublic::setAttribute( const CK_ATTRIBUTE& a_Attribute, const bool& objCreation)
+{
+    //if( 0 == a_Attribute.ulValueLen )
+    //{
+    //    return;
+    //}
+
+    if(objCreation == CK_FALSE){
+        switch(a_Attribute.type){
+        case CKA_ENCRYPT:
+        case CKA_TRUSTED:
+        case CKA_VERIFY:
+        case CKA_VERIFY_RECOVER:
+        case CKA_WRAP:
+            if(*(CK_BBOOL*)a_Attribute.pValue == CK_TRUE){
+                throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+            }
+            break;
+        }
+    }
+
+    switch(a_Attribute.type){
+
+    case CKA_ENCRYPT:
+        _encrypt = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_VERIFY:
+        _verify = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_VERIFY_RECOVER:
+        _verifyRecover = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_WRAP:
+        _wrap = StorageObject::readBBoolFromAttribute( a_Attribute );
+        break;
+
+    case CKA_SUBJECT:
+        m_pSubject.reset( StorageObject::readU1ArrayFromAttribute( a_Attribute ) );
+        break;
+
+    default:
+        KeyObject::setAttribute(a_Attribute,objCreation);
+    }
+}
+
+
+void Pkcs11ObjectKeyPublic::serialize(std::vector<u1> *to)
+{
+    KeyObject::serialize(to);
+
+    Util::PushBBoolInVector(to,_encrypt);
+
+    Util::PushBBoolInVector(to,_verify);
+
+    Util::PushBBoolInVector(to,_verifyRecover);
+
+    Util::PushBBoolInVector(to,_wrap);
+
+    Util::PushByteArrayInVector(to, m_pSubject.get( ) );
+
+    // serialize the extra fields
+    Util::PushBBoolInVector(to,m_ucContainerIndex);
+
+    Util::PushBBoolInVector(to,m_ucKeySpec);
+}
+
+void Pkcs11ObjectKeyPublic::deserialize(std::vector<u1>& from, CK_ULONG_PTR idx)
+{
+    KeyObject::deserialize(from,idx);
+
+    _encrypt = Util::ReadBBoolFromVector(from,idx);
+
+    _verify = Util::ReadBBoolFromVector(from,idx);
+
+    _verifyRecover = Util::ReadBBoolFromVector(from,idx);
+
+    _wrap = Util::ReadBBoolFromVector(from,idx);
+
+    m_pSubject.reset( Util::ReadByteArrayFromVector(from,idx) );
+
+    // deserialize extra fields
+    m_ucContainerIndex = Util::ReadBBoolFromVector(from,idx);
+
+    m_ucKeySpec = Util::ReadBBoolFromVector(from,idx);
+}
+
+
+/*
+*/
+void Pkcs11ObjectKeyPublic::print( void ) {
+
+    KeyObject::print( );
+
+    if( m_pSubject.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_SUBJECT", m_pSubject->GetBuffer( ), m_pSubject->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_SUBJECT <null>" );
+    }
+
+    Log::log( "CKA_ENCRYPT <%ld>", _encrypt );
+
+    Log::log( "CKA_VERIFY <%ld>", _verify );
+
+    Log::log( "CKA_VERIFY_RECOVER <%ld>", _verifyRecover );
+
+    Log::log( "CKA_WRAP <%ld>", _wrap );
+
+    Log::log( "CKA_TRUSTED <%ld>", _trusted );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublic.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,65 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_OBJECT_KEY_PUBLIC__
+#define __GEMALTO_OBJECT_KEY_PUBLIC__
+
+
+#include "Pkcs11ObjectKey.hpp"
+
+
+class Pkcs11ObjectKeyPublic : public KeyObject {
+
+public:
+
+	boost::shared_ptr< Marshaller::u1Array > m_pSubject;
+	
+    CK_BBOOL     _encrypt;
+	
+    CK_BBOOL     _verify;
+	
+    CK_BBOOL     _verifyRecover;
+	
+    CK_BBOOL     _wrap;
+	
+    CK_BBOOL     _trusted;
+
+	Pkcs11ObjectKeyPublic( );
+
+	Pkcs11ObjectKeyPublic( 	const Pkcs11ObjectKeyPublic* );
+
+    virtual ~Pkcs11ObjectKeyPublic( ) { }
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+#endif // __GEMALTO_OBJECT_KEY_PUBLIC__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,215 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectKeyPublicRSA.hpp"
+#include "PKCS11Exception.hpp"
+
+
+Pkcs11ObjectKeyPublicRSA::Pkcs11ObjectKeyPublicRSA( ) : Pkcs11ObjectKeyPublic( ) {
+
+    m_ulModulusBits = 0;
+
+    _keyType = CKK_RSA;
+
+    _mechanismType = CKM_RSA_PKCS_KEY_PAIR_GEN;
+}
+
+
+Pkcs11ObjectKeyPublicRSA::Pkcs11ObjectKeyPublicRSA( const Pkcs11ObjectKeyPublicRSA* p ) : Pkcs11ObjectKeyPublic( p ) {
+
+
+    _keyType = CKK_RSA;
+
+    _mechanismType = CKM_RSA_PKCS_KEY_PAIR_GEN;
+
+    if( p ) {
+
+        m_ulModulusBits = p->m_ulModulusBits;
+
+        if( p->m_pModulus.get( ) ) {
+
+            Marshaller::u1Array* x = new Marshaller::u1Array( *(p->m_pModulus.get( )) );
+
+            m_pModulus.reset( x );
+
+        } else {
+
+            m_pModulus.reset( );
+        }
+
+        if( p->m_pPublicExponent.get( ) ) {
+
+            Marshaller::u1Array* x = new Marshaller::u1Array( *(p->m_pPublicExponent.get( )) );
+
+            m_pPublicExponent.reset( x );
+
+        } else {
+
+            m_pPublicExponent.reset( );
+        }
+    } else {
+
+        m_ulModulusBits = 0;
+
+        m_pModulus.reset( );
+        m_pPublicExponent.reset( );
+    }
+}
+
+
+bool Pkcs11ObjectKeyPublicRSA ::compare( const CK_ATTRIBUTE& attribute)
+{
+    switch(attribute.type){
+
+    case CKA_MODULUS:
+        return Util::compareU1Arrays(m_pModulus.get( ), (unsigned char*)attribute.pValue,attribute.ulValueLen);
+
+    case CKA_MODULUS_BITS:
+        return (m_ulModulusBits == *(CK_ULONG*)attribute.pValue);
+
+    case CKA_PUBLIC_EXPONENT:
+        return Util::compareU1Arrays(m_pModulus.get( ), (unsigned char*)attribute.pValue,attribute.ulValueLen);
+
+    default:
+        return Pkcs11ObjectKeyPublic::compare(attribute);
+    }
+}
+
+void Pkcs11ObjectKeyPublicRSA ::getAttribute(CK_ATTRIBUTE_PTR attribute)
+{
+    switch(attribute->type){
+
+    case CKA_MODULUS:
+        StorageObject::putU1ArrayInAttribute(m_pModulus.get( ),attribute);
+        break;
+
+    case CKA_MODULUS_BITS:
+        StorageObject::putULongInAttribute(m_ulModulusBits,attribute);
+        break;
+
+    case CKA_PUBLIC_EXPONENT:
+        StorageObject::putU1ArrayInAttribute(m_pPublicExponent.get( ),attribute);
+        break;
+
+    default:
+        Pkcs11ObjectKeyPublic::getAttribute(attribute);
+        break;
+    }
+}
+
+
+/*
+*/
+void Pkcs11ObjectKeyPublicRSA::setAttribute( const CK_ATTRIBUTE& a_Attribute, const bool& a_bObjCreation ) {
+
+    if( !a_Attribute.ulValueLen ) {
+
+        return;
+    }
+
+    if( !a_bObjCreation ) {
+
+        switch( a_Attribute.type ) {
+
+        case CKA_PUBLIC_EXPONENT:
+        case CKA_MODULUS:
+        case CKA_MODULUS_BITS:
+            throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+        }
+    }
+
+    switch( a_Attribute.type ) {
+
+    case CKA_MODULUS:
+        m_pModulus.reset( StorageObject::readU1ArrayFromAttribute( a_Attribute ) );
+        m_ulModulusBits = m_pModulus->GetLength()*8;
+        break;
+
+    case CKA_PUBLIC_EXPONENT:
+        m_pPublicExponent.reset( StorageObject::readU1ArrayFromAttribute( a_Attribute ) );
+        break;
+
+    case CKA_MODULUS_BITS:
+        m_ulModulusBits = StorageObject::readULongFromAttribute( a_Attribute );
+        break;
+
+    default:
+        Pkcs11ObjectKeyPublic::setAttribute( a_Attribute, a_bObjCreation );
+    }
+}
+
+
+/*
+*/
+void Pkcs11ObjectKeyPublicRSA::serialize( std::vector<u1> *to ) {
+
+    Pkcs11ObjectKeyPublic::serialize(to);
+
+    Util::PushByteArrayInVector(to,m_pModulus.get( ) );
+
+    Util::PushByteArrayInVector(to,m_pPublicExponent.get( ) );
+
+    Util::PushULongInVector(to,m_ulModulusBits);
+}
+
+
+/*
+*/
+void Pkcs11ObjectKeyPublicRSA::deserialize( std::vector<u1>& from, CK_ULONG_PTR idx ) {
+
+    Pkcs11ObjectKeyPublic::deserialize( from, idx );
+
+    m_pModulus.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+    m_pPublicExponent.reset( Util::ReadByteArrayFromVector( from, idx ) );
+
+    m_ulModulusBits = Util::ReadULongFromVector( from, idx );
+}
+
+
+/*
+*/
+void Pkcs11ObjectKeyPublicRSA::print( void ) {
+
+    Pkcs11ObjectKeyPublic::print( );
+
+    Log::log( "CKA_MODULUS_BITS <%ld>", m_ulModulusBits );
+
+    if( m_pModulus.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_MODULUS", m_pModulus->GetBuffer( ), m_pModulus->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_MODULUS <null>" );
+    }
+
+    if( m_pPublicExponent.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_PUBLIC_EXPONENT", m_pPublicExponent->GetBuffer( ), m_pPublicExponent->GetLength( ) );
+
+    } else {
+
+        Log::log( "CKA_PUBLIC_EXPONENT <null>" );
+    }
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectKeyPublicRSA.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,64 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO__OBJECT_KEY_PUBLICK_RSA__
+#define __GEMALTO__OBJECT_KEY_PUBLICK_RSA__
+
+
+#include <boost/shared_ptr.hpp>
+#include "Pkcs11ObjectKeyPublic.hpp"
+
+
+class Pkcs11ObjectKeyPublicRSA : public Pkcs11ObjectKeyPublic
+{
+
+public:
+
+	boost::shared_ptr< Marshaller::u1Array > m_pModulus;
+	
+	CK_ULONG m_ulModulusBits;
+
+	boost::shared_ptr< Marshaller::u1Array > m_pPublicExponent;
+
+
+	Pkcs11ObjectKeyPublicRSA( );
+    
+    Pkcs11ObjectKeyPublicRSA( const Pkcs11ObjectKeyPublicRSA* );
+
+    virtual ~Pkcs11ObjectKeyPublicRSA( ) { }
+
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize( std::vector< u1 >&, CK_ULONG_PTR );
+
+    virtual void print( void );
+
+};
+
+
+#endif // __GEMALTO__OBJECT_KEY_PUBLICK_RSA__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,447 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#include "Log.hpp"
+#include "util.h"
+#include "Pkcs11ObjectStorage.hpp"
+#include "PKCS11Exception.hpp"
+
+
+/*
+*/
+StorageObject::StorageObject( )
+{
+	m_Class = 0;
+
+    m_iVersion = OBJECT_SERIALIZATION_CURRENT_VERSION;
+    
+    m_Token = CK_FALSE;
+    
+	m_Private = CK_FALSE;
+
+    m_Modifiable = CK_TRUE;
+
+	m_stFileName = "";
+
+    m_bOffCardObject = false;
+        
+    _uniqueId = 0;
+}
+
+
+/*
+*/
+StorageObject::StorageObject( const StorageObject& a_Object ) {
+
+	m_iVersion = a_Object.m_iVersion;
+	
+	m_Class = a_Object.m_Class;
+
+	m_Token = a_Object.m_Token;
+
+	m_Private = a_Object.m_Private;
+
+	m_Modifiable = a_Object.m_Modifiable;
+
+    if( a_Object.m_pLabel.get( ) ) {
+    
+        Marshaller::u1Array* pLabel = new Marshaller::u1Array( *(a_Object.m_pLabel.get( )) );
+
+        m_pLabel.reset( pLabel );
+    
+    } else {
+    
+        m_pLabel.reset( );
+    }
+	
+	m_stFileName = a_Object.m_stFileName; 
+
+    m_bOffCardObject = a_Object.m_bOffCardObject;
+
+    _uniqueId = a_Object._uniqueId;
+}
+
+
+/*
+*/
+bool StorageObject::compare( const CK_ATTRIBUTE& a_attribute ) {
+
+    switch(a_attribute.type){
+        case CKA_CLASS:
+            return (m_Class == *(CK_ULONG*)a_attribute.pValue);
+
+        case CKA_PRIVATE:
+            return (m_Private == *(CK_BBOOL*)a_attribute.pValue);
+
+        case CKA_TOKEN:
+            return (m_Token == *(CK_BBOOL*)a_attribute.pValue);
+
+        case CKA_MODIFIABLE:
+            return (m_Modifiable == *(CK_BBOOL*)a_attribute.pValue);
+
+        case CKA_LABEL:
+			if( m_pLabel.get( ) && ( m_pLabel->GetLength( ) == a_attribute.ulValueLen ) ) {
+                return Util::compareByteArrays(m_pLabel->GetBuffer(),(CK_BYTE_PTR)a_attribute.pValue,a_attribute.ulValueLen);
+            }
+            return false;
+
+        default:
+            return false;
+
+    }
+}
+
+
+/*
+*/
+void StorageObject::setAttribute( const CK_ATTRIBUTE& a_attribute, const bool& a_objCreation) {
+
+   if( !a_attribute.ulValueLen ) {
+
+      return;
+   }
+
+    if( !a_objCreation ) {
+
+        switch( a_attribute.type ) {
+
+            case CKA_CLASS:
+            case CKA_PRIVATE:
+            case CKA_TOKEN:
+            case CKA_MODIFIABLE:
+                throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+        }
+    }
+
+    switch( a_attribute.type ) {
+
+        case CKA_CLASS:
+            break;
+
+        case CKA_PRIVATE:
+            m_Private = StorageObject::readBBoolFromAttribute( a_attribute );
+            break;
+
+        case CKA_TOKEN:
+            m_Token = StorageObject::readBBoolFromAttribute( a_attribute );
+            break;
+
+        case CKA_MODIFIABLE:
+            m_Modifiable = StorageObject::readBBoolFromAttribute( a_attribute );
+            break;
+
+        case CKA_LABEL:
+				m_pLabel.reset( StorageObject::readU1ArrayFromAttribute( a_attribute ) );
+            break;
+
+        default:
+            throw PKCS11Exception( CKR_ATTRIBUTE_TYPE_INVALID );
+    }
+}
+
+
+/*
+*/
+void StorageObject::getAttribute( CK_ATTRIBUTE_PTR attribute ) {
+
+    switch( attribute->type )
+    {
+        case CKA_CLASS:
+            StorageObject::putULongInAttribute(m_Class,attribute);
+            break;
+
+        case CKA_PRIVATE:
+            StorageObject::putBBoolInAttribute(m_Private,attribute);
+            break;
+
+        case CKA_TOKEN:
+            StorageObject::putBBoolInAttribute(m_Token,attribute);
+            break;
+
+        case CKA_MODIFIABLE:
+            StorageObject::putBBoolInAttribute(m_Modifiable,attribute);
+            break;
+
+        case CKA_LABEL:
+			StorageObject::putU1ArrayInAttribute(m_pLabel.get( ),attribute);
+            break;
+
+        default:
+           attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION;
+
+           throw PKCS11Exception( CKR_ATTRIBUTE_TYPE_INVALID );
+    }
+}
+
+
+/*
+*/
+void StorageObject::serialize( std::vector<u1>* to ) {
+
+    // serialize format version
+    Util::PushBBoolInVector( to, (CK_BBOOL)m_iVersion );
+
+    // serialize unique id for compatibility with old version of the P11 library
+    Util::PushULongLongInVector( to, _uniqueId );
+
+    // serialize class attribute
+    Util::PushULongInVector( to, m_Class );
+
+    // serialize private attribute
+    Util::PushBBoolInVector( to, m_Private );
+
+    // serialize token attribute
+    Util::PushBBoolInVector( to, m_Token );
+
+    // serialize modifiable attribute
+    Util::PushBBoolInVector( to, m_Modifiable );
+
+    // serialize label attribute
+    Util::PushByteArrayInVector( to, m_pLabel.get( ) );
+}
+
+
+/*
+*/
+void StorageObject::deserialize( const std::vector<u1>& from, CK_ULONG_PTR idx )
+{
+    m_iVersion = Util::ReadBBoolFromVector( from, idx );
+
+    // Unused value. Read to support old mapping.
+    /*u8 ulUniqueId =*/ Util::ReadULongLongFromVector( from, idx );
+
+    m_Class = Util::ReadULongFromVector( from, idx );
+
+    m_Private = Util::ReadBBoolFromVector( from, idx );
+
+    m_Token = Util::ReadBBoolFromVector( from, idx );
+
+    m_Modifiable = Util::ReadBBoolFromVector( from, idx );
+
+	m_pLabel.reset( Util::ReadByteArrayFromVector( from, idx ) );
+}
+
+
+/*
+*/
+void StorageObject::putU1ArrayInAttribute( Marshaller::u1Array* value, CK_ATTRIBUTE_PTR attribute ) {
+    
+    if( !attribute->pValue ) {
+
+        if( !value ) {
+
+            attribute->ulValueLen = 0; 
+        
+        } else {
+        
+            attribute->ulValueLen = value->GetLength();
+        }
+
+        return;
+    }
+
+    if( !value ) {
+
+        attribute->ulValueLen = 0;
+
+        return;
+    }
+
+    if( attribute->ulValueLen < value->GetLength( ) ) {
+
+        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION;
+        
+        throw PKCS11Exception(  CKR_BUFFER_TOO_SMALL );
+    }
+
+    attribute->ulValueLen = value->GetLength();
+    
+    memcpy((CK_BYTE_PTR)attribute->pValue,value->GetBuffer(),attribute->ulValueLen);
+}
+
+
+/*
+*/
+void StorageObject::putU4ArrayInAttribute( Marshaller::u4Array* value,CK_ATTRIBUTE_PTR attribute)
+{
+    if( !attribute->pValue ) {
+
+        if( !value ) {
+
+            attribute->ulValueLen = 0;
+        
+        } else {
+
+            attribute->ulValueLen = (value->GetLength() * 4);
+        }
+
+        return;
+    }
+
+    if( !value ) {
+
+        attribute->ulValueLen = 0;
+        
+        return;
+    }
+
+    if( attribute->ulValueLen < ( value->GetLength( ) * 4 ) ) {
+
+        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION;
+        
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+
+    attribute->ulValueLen = value->GetLength() * 4;
+    
+    memcpy((CK_BYTE_PTR)attribute->pValue,(u1*)value->GetBuffer(),attribute->ulValueLen);
+}
+
+
+/*
+*/
+void StorageObject::putBBoolInAttribute( const CK_BBOOL& value, CK_ATTRIBUTE_PTR attribute) {
+
+    if( !attribute->pValue ) {
+
+        attribute->ulValueLen = sizeof(CK_BBOOL);
+        
+        return;
+    }
+
+    if( attribute->ulValueLen < sizeof( CK_BBOOL ) ) {
+
+        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION;
+        
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+
+    attribute->ulValueLen = sizeof(CK_BBOOL);
+    
+    *(CK_BBOOL*)attribute->pValue = value;
+}
+
+
+/*
+*/
+void StorageObject::putULongInAttribute( const CK_ULONG& value, CK_ATTRIBUTE_PTR attribute ) {
+
+    if( !attribute->pValue ) {
+
+        attribute->ulValueLen = sizeof( CK_ULONG );
+
+        return;
+    }
+
+    if( attribute->ulValueLen < sizeof( CK_ULONG ) ) {
+
+        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION;
+        
+		throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+
+    attribute->ulValueLen = sizeof( CK_ULONG );
+
+    *(CK_ULONG*)attribute->pValue = value;
+}
+
+
+/*
+*/
+CK_ULONG StorageObject::readULongFromAttribute( const CK_ATTRIBUTE&  a_Attribute ) {
+
+    if( a_Attribute.ulValueLen != sizeof( CK_ULONG ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    return *(CK_ULONG*)a_Attribute.pValue;
+}
+
+
+/*
+*/
+CK_BBOOL StorageObject::readBBoolFromAttribute( const CK_ATTRIBUTE& a_Attribute ) {
+
+    if( a_Attribute.ulValueLen != sizeof( CK_BBOOL ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    CK_BBOOL val = *(CK_BBOOL*)a_Attribute.pValue;
+
+    if( ( val != 0x00 ) && ( val != 0x01 ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    return val;
+}
+
+
+/*
+*/
+Marshaller::u1Array* StorageObject::readU1ArrayFromAttribute( const CK_ATTRIBUTE& a_Attribute ) {
+
+    Marshaller::u1Array* val = new Marshaller::u1Array( a_Attribute.ulValueLen );
+
+    val->SetBuffer( (CK_BYTE_PTR) a_Attribute.pValue );
+
+    return val;
+}
+
+
+/*
+*/
+Marshaller::u1Array* StorageObject::readDateFromAttribute( const CK_ATTRIBUTE& a_Attribute ) {
+
+    if( a_Attribute.ulValueLen != 8 ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    return StorageObject::readU1ArrayFromAttribute( a_Attribute );
+}
+
+
+/*
+*/
+void StorageObject::print( void ) {
+
+	Log::log( "CKA_CLASS <%ld>", m_Class );
+
+    Log::log( "CKA_TOKEN <%ld>", m_Token );
+
+    Log::log( "CKA_PRIVATE <%ld>", m_Private );
+
+    Log::log( "CKA_MODIFIABLE <%ld>", m_Modifiable );
+
+     if( m_pLabel.get( ) ) {
+
+        Log::logCK_UTF8CHAR_PTR( "CKA_LABEL", m_pLabel->GetBuffer( ), m_pLabel->GetLength( ) );
+    
+    } else {
+    
+        Log::log( "CKA_LABEL <null>" );
+    }
+
+    Log::log( "[FileName <%s>]",m_stFileName.c_str( ) );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Pkcs11ObjectStorage.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,108 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_PKCS11_OBJECT_STORAGE__
+#define __GEMALTO_PKCS11_OBJECT_STORAGE__
+
+
+#include <string>
+#include <memory>
+#include "cryptoki.h"
+#include "Array.hpp"
+#include <boost/shared_ptr.hpp>
+
+
+const int OBJECT_SERIALIZATION_CURRENT_VERSION = 2;
+
+
+/*
+*/
+class StorageObject {
+
+public:
+
+	StorageObject( );
+
+	StorageObject( const StorageObject& a_Object );
+
+    virtual ~StorageObject( ) { }
+
+	inline bool isModifiable( void ) { return ( ( m_Modifiable == CK_TRUE ) ? true : false ); }
+
+	inline bool isToken( void ) { return ( ( m_Token == CK_TRUE ) ? true : false ); }
+
+	inline CK_OBJECT_CLASS getClass( void ) { return m_Class; } 
+
+	inline bool isPrivate( void ) { return ( ( m_Private == CK_TRUE ) ? true : false ); }
+
+	inline virtual bool isEqual( StorageObject * that) const { return ( m_Class == that->m_Class ); }
+
+	virtual bool compare( const CK_ATTRIBUTE& );
+
+	virtual void setAttribute( const CK_ATTRIBUTE&, const bool& );
+
+	virtual void getAttribute( CK_ATTRIBUTE_PTR );
+
+	virtual void serialize( std::vector< u1 >* );
+
+	virtual void deserialize(const std::vector< u1 >&, CK_ULONG_PTR );
+
+//protected:
+
+    virtual void print( void );
+
+	void putU1ArrayInAttribute( Marshaller::u1Array*, CK_ATTRIBUTE_PTR );
+
+	void putU4ArrayInAttribute( Marshaller::u4Array*, CK_ATTRIBUTE_PTR );
+
+	void putULongInAttribute( const CK_ULONG&, CK_ATTRIBUTE_PTR );
+
+	void putBBoolInAttribute( const CK_BBOOL&, CK_ATTRIBUTE_PTR );
+
+	CK_BBOOL readBBoolFromAttribute( const CK_ATTRIBUTE& );
+
+	CK_ULONG readULongFromAttribute( const CK_ATTRIBUTE& );
+
+	Marshaller::u1Array* readU1ArrayFromAttribute( const CK_ATTRIBUTE& );
+
+	Marshaller::u1Array* readDateFromAttribute( const CK_ATTRIBUTE& );
+
+	int m_iVersion;
+	
+	CK_ULONG m_Class;
+
+	CK_BBOOL m_Token;
+
+	CK_BBOOL m_Private;
+
+	CK_BBOOL m_Modifiable;
+
+	boost::shared_ptr< Marshaller::u1Array > m_pLabel;
+
+    u8 _uniqueId;
+
+	// name of the PKCS11 file in the card which contains this object attributes
+	std::string m_stFileName;
+
+    bool m_bOffCardObject;
+};
+
+#endif // __GEMALTO_PKCS11_OBJECT_STORAGE__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Session.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Session.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Session.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,339 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Template.hpp"
+#include "Session.hpp"
+#include "Slot.hpp"
+#include "PKCS11Exception.hpp"
+#include <boost/foreach.hpp>
+
+
+unsigned char Session::s_ucSessionObjectIndex = 0;
+
+
+/*
+*/
+Session::Session( Slot* a_pSlot, const CK_SESSION_HANDLE& a_hSession, const CK_BBOOL& a_bIsReadWrite ) {
+    
+	m_Slot = a_pSlot; 
+	
+	m_ulId = a_hSession;
+
+	m_bIsReadWrite = a_bIsReadWrite;
+	
+	m_bIsSearchActive = false;
+	
+	m_bIsDigestActive = false;
+	
+	m_bIsDigestActiveRSA = false;
+	
+	m_bIsDigestVerificationActiveRSA = false;
+
+	// The User or the SO has may be performed a login before to open this session
+	// In this case the state of the session must be updated
+    getState( );
+}
+
+
+/*
+*/
+CK_STATE Session::getState( void ) { 
+    
+    if( !m_Slot ) {
+    
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    CK_USER_TYPE ulRole = m_Slot->getUserType( );
+
+    updateState( ulRole );
+
+    return m_ulState; 
+}
+
+
+/*
+*/
+void Session::updateState( const CK_ULONG& a_ulRoleLogged ) {
+
+	if( m_bIsReadWrite ) {
+
+		switch( a_ulRoleLogged ) {
+
+		case CK_UNAVAILABLE_INFORMATION:
+			m_ulState = CKS_RW_PUBLIC_SESSION;
+			break;
+
+		case CKU_USER:
+			m_ulState = CKS_RW_USER_FUNCTIONS;
+			break;
+
+		case CKU_SO:
+			m_ulState = CKS_RW_SO_FUNCTIONS;
+			break;
+		}
+
+	} else {
+		
+		switch( a_ulRoleLogged ) {
+
+		case CK_UNAVAILABLE_INFORMATION:
+			m_ulState = CKS_RO_PUBLIC_SESSION;
+			break;
+
+		case CKU_USER:
+			m_ulState = CKS_RO_USER_FUNCTIONS;
+			break;
+
+		case CKU_SO:
+			throw PKCS11Exception( CKR_SESSION_READ_ONLY );
+		}
+	}
+}
+
+
+/*
+*/
+StorageObject* Session::getObject( const CK_OBJECT_HANDLE& a_hObject ) {
+
+	if( !a_hObject ) {
+
+		throw PKCS11Exception( CKR_OBJECT_HANDLE_INVALID );
+	}
+
+	// Find the targeted object
+	SESSION_OBJECTS::iterator i = m_Objects.find( a_hObject );
+
+     if( i == m_Objects.end( ) ) {
+	
+		 throw PKCS11Exception( CKR_OBJECT_HANDLE_INVALID );
+	 }
+
+	return i->second;
+}
+
+
+/*
+*/
+void Session::findObjects( CK_OBJECT_HANDLE_PTR a_phObject, const CK_ULONG& a_ulMaxObjectCount, CK_ULONG_PTR a_pulObjectCount ) {
+    
+    if( !m_Slot ) {
+    
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    bool bIsNotAllowedToAccessPrivateObjects = !m_Slot->isAuthenticated( );
+
+    Session::EXPLORED_HANDLES::iterator end = m_SessionObjectsReturnedInSearch.end( );
+
+    // For each P11 object
+    BOOST_FOREACH( const SESSION_OBJECTS::value_type& o, m_Objects ) {
+
+        // Check if the search has reached the allowed maximum of objects to search 
+        if( *a_pulObjectCount >= a_ulMaxObjectCount ) {
+
+            break;
+        }
+
+        // Check if this object has been already compared to the search template
+        if( end != m_SessionObjectsReturnedInSearch.find( o->first ) ) {
+
+            // This object has already been analysed by a previous call of findObjects for this template
+            continue;
+        }
+
+        // If the object is private and the user is not logged in
+        if( o->second->isPrivate( ) && bIsNotAllowedToAccessPrivateObjects )
+        {
+            // Then avoid this element. 
+            // Do not add it the list of already explored objects (may be a C_Login can occur)
+            continue;
+        }
+
+        // Add the object to the list of the objects compared to the search template
+        m_SessionObjectsReturnedInSearch.insert( o->first );
+
+        // If the template is NULL then return all objects
+        if( !_searchTempl ) {
+
+            a_phObject[ *a_pulObjectCount ] = o->first;
+
+            ++(*a_pulObjectCount);
+
+        } else {
+            // The template is not NULL.
+   
+            bool match = true;
+
+            // In this case the template attributes have to be compared to the objects ones.
+            BOOST_FOREACH( CK_ATTRIBUTE& t, _searchTempl->getAttributes( ) ) {
+
+                if( ! o->second->compare( t ) ) {
+
+                    match = false;
+
+                    break;
+                }
+            }
+
+            // The attributes match
+            if( match ) {
+
+                // Add the object handle to the outgoing list
+                a_phObject[ *a_pulObjectCount ] = o->first;
+
+                // Increment the number of found objects
+                ++(*a_pulObjectCount);
+            }
+        }
+    }
+}
+
+
+/*
+*/
+void Session::deleteObject( const CK_OBJECT_HANDLE& a_hObject ) {
+
+    if( !m_Slot ) {
+    
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+	// Find the targeted object
+	StorageObject* o = getObject( a_hObject );
+
+	// if this is a readonly session and user is not logged 
+	// then only public session objects can be created
+	if( !m_bIsReadWrite && o->isToken( ) ) {
+
+		throw PKCS11Exception( CKR_SESSION_READ_ONLY );
+	}
+
+	if( o->isPrivate( ) && !m_Slot->isAuthenticated( ) ) {
+        
+		throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+	}
+	
+	try {
+    
+        m_Objects.erase( a_hObject );
+    
+    } catch( ... ) {
+    
+        throw PKCS11Exception( CKR_OBJECT_HANDLE_INVALID );
+    }
+}
+
+
+/*
+*/
+void Session::getAttributeValue( const CK_OBJECT_HANDLE& a_hObject, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    if( !m_Slot ) {
+    
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Find the targeted object
+	StorageObject* o = getObject( a_hObject );
+
+	if( o->isPrivate( ) && !m_Slot->isAuthenticated( ) ) {
+        
+		for( u4 i = 0 ; i < a_ulCount ; ++i ) {
+
+			a_pTemplate[ i ].ulValueLen = (CK_ULONG)CK_UNAVAILABLE_INFORMATION;
+		}
+
+		throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+	}
+
+	for( CK_ULONG i = 0 ; i < a_ulCount ; ++i ) {
+		
+		o->getAttribute( &a_pTemplate[ i ] );
+	}
+}
+
+
+/*
+*/
+void Session::setAttributeValue( const CK_OBJECT_HANDLE& a_hObject, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    if( !m_Slot ) {
+    
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Find the targeted object
+	StorageObject* o = getObject( a_hObject );
+
+	if( o->isPrivate( ) && !m_Slot->isAuthenticated( ) ) {
+        
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+	}
+
+	for( CK_ULONG i = 0 ; i < a_ulCount ; ++i ) {
+
+		o->setAttribute( a_pTemplate[ i ], false );
+	}
+}
+
+
+/*
+*/
+CK_OBJECT_HANDLE Session::computeObjectHandle( const CK_OBJECT_CLASS& a_ulClass, const bool& a_bIsPrivate ) { 
+    
+    // Register the session object id (value from 0 to 255)
+    unsigned char ucByte1 = ++s_ucSessionObjectIndex;
+
+    // Register the object class and if the object is private:
+	// Private Data	        1000 [08] = set class to CKO_DATA (0x00) and Private to TRUE (0x08)
+	// Public Data	        0000 [00] = set class to CKO_DATA (0x00) and Private to FALSE (0x00)	
+	// Private Certificate	1001 [09] = set class to CKO_CERTIFICATE (0x01) and Private to TRUE (0x08)
+	// Public Certificate	0001 [01] = set class to CKO_CERTIFICATE (0x01) and Private to FALSE (0x00)		
+	// Private Public Key	1010 [10] = set class to CKO_PUBLIC_KEY (0x02) and Private to TRUE (0x08)
+	// Public Public Key	0010 [02] = set class to CKO_PUBLIC_KEY (0x02) and Private to FALSE (0x00)    
+    // Private Private Key	1011 [11] = set class to CKO_PRIVATE_KEY (0x03) and Private to TRUE (0x08)			
+	// Public Private Key	0011 [03] = set class to CKO_PRIVATE_KEY (0x03) and Private to FALSE (0x00)
+	unsigned char ucByte2 = (unsigned char)a_ulClass + ( a_bIsPrivate ? 0x08 : 0x00 );
+
+    // Register if the object is owned by the token (value 0) or the session (value corresponding to the session id from 1 to 255)
+    unsigned char ucByte3 = (unsigned char) ( 0x000000FF & m_ulId );
+
+    // Register the slot id
+    unsigned char ucByte4 = (unsigned char) ( 0x000000FF & m_Slot->getSlotId( ) );
+
+    // Compute the object handle: byte4 as Slot Id, byte3 as Token/Session, byte2 as attributes and byte1 as object Id					
+    CK_OBJECT_HANDLE h = ( ucByte4 << 24 ) + ( ucByte3 << 16 ) + ( ucByte2 << 8 )+ ucByte1;
+
+    return h; 
+}
+
+
+/*
+*/
+void Session::addObject( StorageObject* a_pObj, CK_OBJECT_HANDLE_PTR a_phObject ) { 
+    
+    *a_phObject = computeObjectHandle( a_pObj->getClass( ), a_pObj->isPrivate( ) ); 
+    
+    CK_OBJECT_HANDLE h = *a_phObject; 
+    
+    m_Objects.insert( h, a_pObj ); 
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Session.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Session.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Session.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,212 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_SESSION__
+#define __GEMALTO_SESSION__
+
+
+#include "Template.hpp"
+#include "digest.h"
+#include "Pkcs11ObjectStorage.hpp"
+#include <set>
+#include <vector>
+#include <boost/smart_ptr.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include "Array.hpp"
+#include "cryptoki.h"
+
+
+class Slot;
+
+
+/*
+*/
+class CryptoOperation {
+
+    CK_ULONG m_ulMechanism;
+
+    CK_OBJECT_HANDLE m_hObject;
+    //StorageObject* m_pObject;
+
+public:
+
+    //CryptoOperation( const CK_ULONG& a_ulMechanism, StorageObject* a_pObject ) : m_ulMechanism( a_ulMechanism ), m_pObject( a_pObject ) { }
+    CryptoOperation( const CK_ULONG& a_ulMechanism, const CK_OBJECT_HANDLE& a_hObject ) : m_ulMechanism( a_ulMechanism ), m_hObject( a_hObject ) { }
+
+    //virtual ~CryptoOperation( ) { };
+
+public:
+
+    inline const CK_ULONG& getMechanism( void ) { return m_ulMechanism; }
+
+    //inline StorageObject* getObject( void ) { return m_pObject; }
+    inline CK_OBJECT_HANDLE& getObject( void ) { return m_hObject; }
+
+};
+
+
+
+/*
+*/
+class Session {
+
+public:
+
+    typedef std::set< CK_OBJECT_HANDLE > EXPLORED_HANDLES;
+
+    typedef boost::ptr_map< CK_OBJECT_HANDLE, StorageObject > SESSION_OBJECTS;
+
+    Session( Slot*, const CK_SESSION_HANDLE&, const CK_BBOOL& );
+
+    //inline virtual ~Session( ) { }
+
+    inline CK_BBOOL isReadWrite( void ) { return m_bIsReadWrite; }
+
+    inline CK_FLAGS getFlags( void ) { return ( ( m_bIsReadWrite ? CKF_RW_SESSION : 0 ) | CKF_SERIAL_SESSION ); }
+
+    CK_STATE getState( void ); // { return m_ulState; }
+
+    CDigest* getDigest( void ) { return m_Digest.get( ); }
+
+    inline Marshaller::u1Array* getPinSO( void ) { return m_PinSO.get( ); }
+
+    inline void setSearchTemplate( Template* templ ) { _searchTempl.reset( templ ); m_bIsSearchActive = true; m_SessionObjectsReturnedInSearch.clear( ); }
+
+    inline void removeSearchTemplate( void ) {_searchTempl.reset( ); m_bIsSearchActive = false; }
+
+    inline bool isDecryptionActive( void ) { return (bool)_decryption; }
+
+    inline bool isSignatureActive( void ) { return (bool)m_Signature; }
+
+    void updateState( const CK_ULONG& );
+
+    inline bool isSearchActive( void ) { return m_bIsSearchActive; }
+
+    inline bool isDigestActive( void ) { return m_bIsDigestActive; }
+
+    inline bool isDigestActiveRSA( void ) { return m_bIsDigestActiveRSA; }
+
+    inline bool isDigestVerificationActiveRSA( void ) { return m_bIsDigestVerificationActiveRSA; }
+
+    void addObject( StorageObject*, CK_OBJECT_HANDLE_PTR );
+
+    void deleteObject( const CK_OBJECT_HANDLE& );
+
+    void findObjects( CK_OBJECT_HANDLE_PTR, const CK_ULONG&, CK_ULONG_PTR);
+
+    void getAttributeValue( const CK_OBJECT_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+    void setAttributeValue( const CK_OBJECT_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+    inline void setSlot( boost::shared_ptr< Slot > a_pSlot ) { m_Slot = a_pSlot.get( ); }
+
+    StorageObject* getObject( const CK_OBJECT_HANDLE& a_hObject );
+
+    inline boost::shared_ptr< CryptoOperation >& getSignature( void ) { return m_Signature; }
+
+    inline void setEncryptionOperation( CryptoOperation *encryption ) { _encryption.reset( encryption ); }
+
+    inline void removeEncryptionOperation( void ) { _encryption.reset( ); }
+
+    inline bool isEncryptionActive( void ) { return (_encryption.get( ) != NULL_PTR); }
+
+    inline void setVerificationOperation( CryptoOperation *verification ) { _verification.reset( verification ); }
+
+    inline void removeVerificationOperation( void ) { _verification.reset( ); }
+
+    inline bool isVerificationActive( void ) { return (_verification.get( ) != NULL_PTR); }
+
+    inline void setDecryptionOperation( CryptoOperation *decryption ) { _decryption.reset( decryption ); }
+
+    inline void removeDecryptionOperation( void ) { _decryption.reset( ); }
+
+    inline void setSignatureOperation( const boost::shared_ptr< CryptoOperation >& co ) { m_Signature = co; }
+
+    inline void removeSignatureOperation( void ) { m_Signature.reset( ); }
+
+    inline void setPinSO( Marshaller::u1Array& a ) { m_PinSO.reset( new Marshaller::u1Array( a.GetLength( ) ) ); m_PinSO->SetBuffer( a.GetBuffer( ) ); }
+
+    inline void setDigest(CDigest *digest) { m_Digest.reset( digest ); m_bIsDigestActive = true; }
+
+    inline void removeDigest( void ) { m_Digest.reset( ); m_bIsDigestActive = false; }
+
+    inline void setDigestRSA( CDigest *digest ) { _digestRSA.reset( digest ); m_bIsDigestActiveRSA = true; }
+
+    inline void removeDigestRSA( void ) { _digestRSA.reset( ); m_bIsDigestActiveRSA = false; }
+
+    inline void setDigestRSAVerification( CDigest *digest ) { _digestRSAVerification.reset( digest ); m_bIsDigestVerificationActiveRSA = true; }
+
+    inline void removeDigestRSAVerification( void ) { _digestRSAVerification.reset( ); m_bIsDigestVerificationActiveRSA = false; }
+
+    //private:
+    static unsigned char s_ucSessionObjectIndex;
+
+    CK_OBJECT_HANDLE computeObjectHandle( const CK_OBJECT_CLASS& a_ulClass, const bool& a_bIsPrivate ); 
+
+    CK_BBOOL m_bIsReadWrite;
+
+    CK_ULONG m_ulState;
+
+    SESSION_OBJECTS m_Objects;
+
+    boost::shared_ptr< Template > _searchTempl;
+
+    boost::shared_ptr< CDigest > m_Digest;
+
+    boost::shared_ptr< CDigest > _digestRSA;
+
+    boost::shared_ptr< CDigest > _digestRSAVerification;
+
+    EXPLORED_HANDLES m_SessionObjectsReturnedInSearch;
+
+    boost::shared_ptr< CryptoOperation > m_Signature;
+
+    boost::shared_ptr< CryptoOperation > _decryption;
+
+    boost::shared_ptr< CryptoOperation > _verification;
+
+    boost::shared_ptr< CryptoOperation > _encryption;
+
+    bool m_bIsSearchActive;
+
+    bool m_bIsDigestActive;
+
+    bool m_bIsDigestActiveRSA;
+
+    bool m_bIsDigestVerificationActiveRSA;
+
+    CK_ULONG m_ulId;
+
+    Slot* m_Slot;
+
+    boost::shared_ptr< Marshaller::u1Array > m_AccumulatedDataToSign;
+
+    boost::shared_ptr< Marshaller::u1Array > m_AccumulatedDataToVerify;
+
+    // The CardModule interface requires cryptogram as part of ChangeReferenceData method whereas
+    // PKCS#11 first log SO in and then call InitPIN. InitPIN does not have any information about 
+    // SO PIN so what we do here is to cache it momentarily. Basically during Login (as SO) we 
+    // cache it and destroy it during closing of session
+    boost::shared_ptr< Marshaller::u1Array > m_PinSO;
+
+};
+
+#endif // __GEMALTO_SESSION__

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.cpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,2889 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Slot.hpp"
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/array.hpp>
+#include "cryptoki.h"
+#include "Template.hpp"
+#include "digest.h"
+#include "sha1.h"
+#include "sha256.h"
+#include "md5.h"
+#include "Pkcs11ObjectData.hpp"
+#include "Pkcs11ObjectKeyPrivateRSA.hpp"
+#include "Pkcs11ObjectKeyPublicRSA.hpp"
+#include "Pkcs11ObjectCertificateX509PublicKey.hpp"
+#include "Log.hpp"
+
+
+CK_MECHANISM_TYPE g_mechanismList[ ] = {
+    CKM_RSA_PKCS_KEY_PAIR_GEN, // 0
+    CKM_RSA_PKCS,              // 1
+    CKM_RSA_X_509,             // 2
+    CKM_MD5_RSA_PKCS,          // 3
+    CKM_SHA1_RSA_PKCS,         // 4
+    CKM_SHA256_RSA_PKCS,       // 5
+    CKM_MD5,                   // 6
+    CKM_SHA_1,                 // 7
+    CKM_SHA256,                // 8
+};
+
+CK_MECHANISM_INFO g_mechanismInfo[] = {
+    {/* 0 */  MiniDriver::s_iMinLengthKeyRSA, MiniDriver::s_iMaxLengthKeyRSA, CKF_HW | CKF_GENERATE_KEY_PAIR },
+    {/* 1 */  MiniDriver::s_iMinLengthKeyRSA, MiniDriver::s_iMaxLengthKeyRSA, CKF_HW | CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT },
+    {/* 2 */  MiniDriver::s_iMinLengthKeyRSA, MiniDriver::s_iMaxLengthKeyRSA, CKF_HW | CKF_SIGN | CKF_VERIFY | CKF_ENCRYPT | CKF_DECRYPT },
+    {/* 3 */  MiniDriver::s_iMinLengthKeyRSA, MiniDriver::s_iMaxLengthKeyRSA, CKF_HW | CKF_SIGN | CKF_VERIFY },
+    {/* 4 */  MiniDriver::s_iMinLengthKeyRSA, MiniDriver::s_iMaxLengthKeyRSA, CKF_HW | CKF_SIGN | CKF_VERIFY },
+    {/* 5 */  MiniDriver::s_iMinLengthKeyRSA, MiniDriver::s_iMaxLengthKeyRSA, CKF_HW | CKF_SIGN | CKF_VERIFY },
+    {/* 6 */  0,0, CKF_DIGEST },
+    {/* 7 */  0,0, CKF_DIGEST },
+    {/* 8 */  0,0, CKF_DIGEST },
+};
+
+const int g_iLabelSize = 32;
+
+// Index used to compute the session handle. The first session handle must start from 1 because 0 is used for an unvalid handle
+unsigned char Slot::s_ucSessionIndex = 0;
+
+
+/*
+*/
+Slot::Slot( const boost::shared_ptr < Device >& a_pDevice ) {
+
+    Log::begin( "Slot::Slot" ); 
+
+    // LCA: used to remember card insertion
+    m_isTokenInserted = false;
+
+    //m_SessionState = CKS_RO_PUBLIC_SESSION;
+
+    m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+    m_stEmpty = "";
+
+    m_ucEventSlotId = 0xFF;
+
+    m_bEvent = false;
+
+    // Store a pointer to the device instance
+    m_Device = a_pDevice;
+
+    try {
+
+        // Create a token instance if a smart card is present into the reader
+        if( m_Device.get( ) && m_Device->isSmartCardPresent( ) ) {
+
+            Log::log( "Slot::Slot - Reader Name <%s> - SmartCard present <%d>", m_Device->getReaderName( ).c_str( ), m_Device->isSmartCardPresent( ) );
+
+            //m_Token.reset( new Token( this, m_Device.get( ) ) );
+
+            //// Analyse the current state of the smart card to consider the slot as connected or not
+            //if( m_Device->isNoPin( ) || ( m_Device->isSSO( ) && m_Device->isAuthenticated( ) ) ) {
+
+            //    Log::log( "Slot::Slot - No PIN or SSO activated" );
+
+            //    m_ulUserType = CKU_USER;
+            //}
+
+            tokenInserted( );
+        }
+
+    } catch( MiniDriverException& ) {
+
+        m_Token.reset( );
+
+        Log::error( "Slot::Slot", "MiniDriverException" );
+    }
+
+    // Initialize the slot info
+    memset( &m_SlotInfo, 0, sizeof( CK_SLOT_INFO ) );
+
+    m_SlotInfo.flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
+
+    memset( m_SlotInfo.slotDescription, ' ', sizeof( m_SlotInfo.slotDescription ) );
+
+    if( m_Device.get( ) ) {
+
+        memcpy( m_SlotInfo.slotDescription, m_Device->getReaderName( ).c_str( ), m_Device->getReaderName( ).length( ) );
+    }
+
+    memset( m_SlotInfo.manufacturerID, ' ', sizeof( m_SlotInfo.manufacturerID ) );
+
+    m_SlotInfo.manufacturerID[0] = 'U';
+    m_SlotInfo.manufacturerID[1] = 'n';
+    m_SlotInfo.manufacturerID[2] = 'k';
+    m_SlotInfo.manufacturerID[3] = 'n';
+    m_SlotInfo.manufacturerID[4] = 'o';
+    m_SlotInfo.manufacturerID[5] = 'w';
+    m_SlotInfo.manufacturerID[6] = 'n';
+
+    Log::end( "Slot::Slot" ); 
+}
+
+
+/*
+*/
+inline void Slot::tokenCreate( void ) { 
+        
+    m_ulUserType = CK_UNAVAILABLE_INFORMATION; 
+        
+    m_Token.reset( new Token( this, m_Device.get( ) ) ); 
+   
+    try { 
+
+        // Analyse the current state of the smart card to consider the slot as connected or not
+        if( m_Device->isNoPin( ) || ( m_Device->isSSO( ) && m_Device->isAuthenticated( ) ) ) {
+
+            Log::log( "Slot::Slot - No PIN or SSO activated" );
+
+            m_ulUserType = CKU_USER;
+        }
+                    
+        if( !Device::s_bEnableCache && m_Device.get( ) ) { 
+                
+            m_Device->forceGarbageCollection( ); 
+        } 
+            
+        updateAllSessionsState( ); 
+        
+    } catch( ... ) { } 
+}
+
+	
+/*
+*/
+void Slot::finalize( void ) {
+
+    Log::begin( "Slot::finalize" ); 
+
+    //m_SessionState = CKS_RO_PUBLIC_SESSION;
+
+    m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+    try {
+
+        closeAllSessions( );
+
+        if( m_Device.get( ) ) {
+
+            if( m_Device->isSmartCardPresent( ) ) {
+
+                m_Device->logOut( );
+
+                m_Device->administratorLogout( );
+
+                if( !Device::s_bEnableCache ) {
+
+                    m_Device->forceGarbageCollection( );
+                }
+            }
+
+            m_Device->saveCache( );
+        }
+
+    } catch( ... ) { }
+
+    Log::end( "Slot::finalize" ); 
+}
+
+
+/*
+*/
+void Slot::checkTokenInsertion( void ) {
+
+    if( m_isTokenInserted ) {
+
+        tokenCreate( );
+
+        m_isTokenInserted = false;
+
+        m_Device->saveCache( );
+    }
+}
+
+
+/*
+*/
+void Slot::getInfo( CK_SLOT_INFO_PTR p ) {
+
+    if( !p ) {
+
+        return;
+    }
+
+    memcpy( p->slotDescription, m_SlotInfo.slotDescription, sizeof( p->slotDescription ) );
+
+    memcpy( p->manufacturerID, m_SlotInfo.manufacturerID, sizeof( p->manufacturerID ) );
+
+    p->hardwareVersion.major = m_SlotInfo.hardwareVersion.major;
+
+    p->hardwareVersion.minor = m_SlotInfo.hardwareVersion.minor;
+
+    p->firmwareVersion.major = m_SlotInfo.firmwareVersion.major;
+
+    p->firmwareVersion.minor = m_SlotInfo.firmwareVersion.minor;
+
+    // No card in reader
+    m_SlotInfo.flags &= ~CKF_TOKEN_PRESENT;
+
+
+// LCA: Token inserted?
+    checkTokenInsertion( );
+
+    try {
+
+        if( getToken( ).get( ) ) { //m_Device.get( ) && m_Device->isSmartCardPresent( ) ) {
+
+            // we found a card in this reader
+            m_SlotInfo.flags |= CKF_TOKEN_PRESENT;
+        } 
+
+    } catch( ... ) { }
+
+    p->flags = m_SlotInfo.flags;
+}
+
+
+/*
+*/
+void Slot::getTokenInfo( CK_TOKEN_INFO_PTR p ) {
+
+    if( !p ) {
+
+        return;
+    }
+
+    // LCA: Token inserted?
+    checkTokenInsertion( );
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    //Log::begin( "Slot::GetTokenInfo" );
+
+    try {
+
+        p->firmwareVersion.major = m_Token->getTokenInfo( ).firmwareVersion.major;
+        p->firmwareVersion.minor = m_Token->getTokenInfo( ).firmwareVersion.minor;
+        p->hardwareVersion.major = m_Token->getTokenInfo( ).hardwareVersion.major;
+        p->hardwareVersion.minor = m_Token->getTokenInfo( ).hardwareVersion.minor;
+
+        memcpy( p->label, m_Token->getTokenInfo( ).label, sizeof( p->label ) );
+
+        memcpy( p->manufacturerID, m_Token->getTokenInfo( ).manufacturerID, sizeof( p->manufacturerID ) );
+
+        memcpy( p->model, m_Token->getTokenInfo( ).model, sizeof( p->model ) );
+
+        memcpy( p->serialNumber, m_Token->getTokenInfo( ).serialNumber, sizeof( p->serialNumber ) );
+
+        //Log::logCK_UTF8CHAR_PTR( "Slot::GetTokenInfo - m_TokenInfo.serialNumber", m_Token->getTokenInfo( ).serialNumber, sizeof( m_Token->getTokenInfo( ).serialNumber ) );
+
+        p->ulFreePrivateMemory  = m_Token->getTokenInfo( ).ulFreePrivateMemory;
+        p->ulFreePublicMemory   = m_Token->getTokenInfo( ).ulFreePublicMemory;
+        p->ulMaxPinLen          = m_Token->getTokenInfo( ).ulMaxPinLen;
+        p->ulMinPinLen          = m_Token->getTokenInfo( ).ulMinPinLen;
+        p->ulMaxRwSessionCount  = CK_EFFECTIVELY_INFINITE;
+        p->ulSessionCount       = 0;
+        p->ulMaxSessionCount    = CK_EFFECTIVELY_INFINITE;
+        p->ulRwSessionCount     = 0;
+        p->ulTotalPrivateMemory = m_Token->getTokenInfo( ).ulTotalPrivateMemory;
+        p->ulTotalPublicMemory  = m_Token->getTokenInfo( ).ulTotalPublicMemory;
+
+        BOOST_FOREACH( const MAP_SESSIONS::value_type& s, m_Sessions ) {
+
+            // Count the number of opened sessions
+            ++p->ulSessionCount;
+
+            if( s.second->isReadWrite( ) ) {
+
+                ++p->ulRwSessionCount;
+            }
+        }
+
+        memcpy( p->utcTime, m_Token->getTokenInfo( ).utcTime, sizeof( p->utcTime ) );
+
+        if( !m_Device.get( ) ) {
+
+            throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+        }
+
+        try {
+
+            //Log::log( "Slot::GetTokenInfo - isNoPinSupported <%d>", m_Device->isNoPin( ) );
+            //Log::log( "Slot::GetTokenInfo - IsSSO <%d>", m_Device->isSSO( ) );
+            //Log::log( "Slot::GetTokenInfo - IsAuthenticated <%d>", bIsAuthenticated );
+
+            // Check if the smart card is in SSO mode
+            if(  m_Device->isNoPin( ) || ( m_Device->isSSO( ) && isAuthenticated( ) ) ) {
+
+                m_Token->getTokenInfo( ).flags &= ~CKF_LOGIN_REQUIRED;
+                //Log::log( "Slot::GetTokenInfo - No login required" );
+
+            } else {
+
+                m_Token->getTokenInfo( ).flags |= CKF_LOGIN_REQUIRED;
+                //Log::log( "Slot::GetTokenInfo - Login required" );
+            }
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Slot::getTokenInfo", "MiniDriverException" );
+            throw PKCS11Exception( Token::checkException( x ) );
+        }
+
+        p->flags = m_Token->getTokenInfo( ).flags;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    //Log::end( "Slot::GetTokenInfo" );
+}
+
+
+/*
+*/
+void Slot::getMechanismList( CK_MECHANISM_TYPE_PTR a_pMechanismList, CK_ULONG_PTR a_pulCount ) {
+
+    size_t l = sizeof( g_mechanismList ) / sizeof( CK_ULONG );
+
+    if( *a_pulCount < l ) {
+
+        *a_pulCount = l;
+        
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+
+    if( a_pMechanismList ) {
+    
+        for( size_t i = 0 ; i < l ; ++i ) {
+
+            a_pMechanismList[ i ] = g_mechanismList[ i ];
+        }
+     }
+  
+    *a_pulCount = l;
+}
+
+
+/*
+*/
+void Slot::getMechanismInfo( const CK_MECHANISM_TYPE& t, CK_MECHANISM_INFO_PTR p ) {
+
+    //if( !p ) {
+
+    //    return;
+    //}
+
+    size_t i = 0;
+
+    bool found = false;
+
+    size_t l = sizeof( g_mechanismList ) / sizeof( CK_ULONG );
+
+    for( ; i < l ; ++i ) {
+
+        if( g_mechanismList[ i ] == t ) {
+
+            found = true;
+
+            break;
+        }
+    }
+
+    if( !found ) {
+
+        throw PKCS11Exception( CKR_MECHANISM_INVALID );
+    }
+
+    p->ulMinKeySize = g_mechanismInfo[ i ].ulMinKeySize;
+
+    p->ulMaxKeySize = g_mechanismInfo[ i ].ulMaxKeySize;
+
+    p->flags = g_mechanismInfo[ i ].flags;
+}
+
+
+/*
+*/
+void Slot::initToken( CK_UTF8CHAR_PTR pPin, const CK_ULONG& ulPinLen, CK_UTF8CHAR_PTR pLabel ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Check if we have an open session
+    if( m_Sessions.size( ) ) {
+
+        throw PKCS11Exception( CKR_SESSION_EXISTS );
+    }
+
+    Marshaller::u1Array p( ulPinLen );
+    p.SetBuffer( pPin );
+
+    Marshaller::u1Array l( g_iLabelSize );
+    l.SetBuffer( pLabel );
+
+    try {
+
+        m_Token->initToken( &p, &l );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::checkAccessException( const PKCS11Exception& a_Exception ) {
+
+    if( CKR_USER_NOT_LOGGED_IN == a_Exception.getError( ) ) {
+
+        Log::log( "Slot::checkAccessException - !! User desauthenticated !!" );
+
+        m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+        // Update the state of all sessions because write access is no more allowed
+        updateAllSessionsState( );
+    }
+}
+
+
+/*
+*/
+void Slot::openSession( const CK_FLAGS& flags, CK_VOID_PTR, CK_NOTIFY, CK_SESSION_HANDLE_PTR phSession ) {
+
+    bool bIsReadWrite = ( ( flags & CKF_RW_SESSION ) == CKF_RW_SESSION );
+
+
+// LCA: Token inserted?
+    checkTokenInsertion( );
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+
+    // if admin is logged we can not open R/O session because R/O session is not allowed for SO
+    if( administratorIsAuthenticated( ) && !bIsReadWrite ) {
+
+        throw PKCS11Exception( CKR_SESSION_READ_WRITE_SO_EXISTS );
+    }
+
+    // Create the session
+    *phSession = addSession( bIsReadWrite );
+}
+
+
+/*
+*/
+void Slot::closeAllSessions( void ) {
+
+    try {
+
+        // The user or SO must be desauthenticated
+        if( isAuthenticated( ) || administratorIsAuthenticated( ) ) {
+        
+            if( m_Device.get( ) && m_Device->isSmartCardPresent( ) ) {
+
+                if( m_Token.get( ) ) {
+
+                    m_Token->logout( );
+                }
+            }
+        }
+
+    } catch( ... ) { }
+
+    m_Sessions.clear( );
+
+    //m_SessionState = CKS_RO_PUBLIC_SESSION;
+    m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+}
+
+
+/*
+*/
+void Slot::closeSession( const CK_SESSION_HANDLE& a_hSession ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    getSession( a_hSession );
+
+    m_Sessions.erase( a_hSession );
+
+    try {
+
+        // Last session ? The user or SO must be desauthenticated
+        if( !m_Sessions.size( ) && ( isAuthenticated( ) || administratorIsAuthenticated( ) ) ) {
+
+            m_Token->logout( );
+
+            //m_SessionState = CKS_RO_PUBLIC_SESSION;
+
+            m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::closeSession", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& ) {
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::getSessionInfo( const CK_SESSION_HANDLE& a_hSession, CK_SESSION_INFO_PTR a_pInfo ) {
+
+    Session* s = getSession( a_hSession );
+
+    // Return the session information
+    unsigned char ucDeviceID = 0xFF;
+
+    if( !m_Device.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        ucDeviceID = m_Device->getDeviceID( );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::getSessionInfo", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    a_pInfo->slotID = ucDeviceID;
+
+    //// Lead Firefox to crash when it is called from the "Certificate Manager"
+    //// when the smart card was previously logged in by Firefox but is now logged 
+    //// out by another application than Firefox:
+    //// Check that the user is still logged in
+    if( m_ulUserType == CKU_USER ) {
+
+        if ( m_Device.get( ) && !m_Device->isAuthenticated( ) ) {
+        
+            m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+            // Update the state of all sessions because write access is no more allowed
+            updateAllSessionsState( );
+        }
+    }
+
+    a_pInfo->state = s->getState( );
+
+    a_pInfo->flags = s->getFlags( );
+
+    a_pInfo->ulDeviceError = CKR_OK;
+}
+
+
+/*
+*/
+void Slot::login( const CK_SESSION_HANDLE& a_hSession, const CK_USER_TYPE& a_UserType, CK_UTF8CHAR_PTR a_pPin, const CK_ULONG& a_ulPinLen ) {
+
+    if( !m_Token.get(  ) || !m_Device.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    try {
+
+        // The smart card is configured in "no pin" mode
+        if( m_Device->isNoPin( ) && !administratorIsAuthenticated( ) ) {
+
+            //m_SessionState = s->isReadWrite( ) ? ( ( CKU_USER == a_UserType ) ? CKS_RW_USER_FUNCTIONS : CKS_RW_SO_FUNCTIONS ) : ( ( CKU_USER == a_UserType ) ? CKS_RO_USER_FUNCTIONS : CKS_RW_SO_FUNCTIONS );
+
+            m_ulUserType = a_UserType;
+
+            updateAllSessionsState( );
+
+            return;
+        }
+
+        // The smart card is configured in "sso" mode and the end-user is already logged in
+        if( m_Device->isSSO( ) && isAuthenticated( ) ) {
+
+            m_ulUserType = a_UserType;
+
+            updateAllSessionsState( );
+
+            return;
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::login", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+    }
+
+    // The SO wants to log in but a session exists
+    if( ( CKU_SO == a_UserType ) && hasReadOnlySession( ) ) {
+
+        throw PKCS11Exception( CKR_SESSION_READ_ONLY_EXISTS );
+    }
+
+    CK_ULONG ulPinLen = a_ulPinLen;
+
+    if( !a_pPin ) {
+
+        ulPinLen = 0;
+    }
+
+    Marshaller::u1Array pPin( a_ulPinLen );
+
+    pPin.SetBuffer( a_pPin );
+
+    try {
+
+        m_Token->login( a_UserType, &pPin );
+
+    } catch( PKCS11Exception& ) {
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    if( CKU_SO == a_UserType ) {
+
+        // cache SO PIN for the duration of this session        
+        if( s ) {
+
+            s->setPinSO( pPin );
+        }
+    }
+
+    m_ulUserType = a_UserType;
+
+    // Update the state of all sessions because write access is now allowed
+    updateAllSessionsState( );
+}
+
+
+/*
+*/
+void Slot::logout( const CK_SESSION_HANDLE& a_hSession ) {
+
+    if( !m_Device.get( ) || !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    getSession( a_hSession );
+
+    try {
+
+        // Log out from the smart card
+        m_Token->logout( );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::closeSession", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& ) {
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+    // Analyse the current stae of the smart card to consider the slot as connected or not
+    if( m_Device->isNoPin( ) || ( m_Device->isSSO( ) && m_Device->isAuthenticated( ) ) ) {
+
+        m_ulUserType = CKU_USER;
+    }
+
+    // Update the state of all sessions because write access is no more allowed
+    updateAllSessionsState( );
+}
+
+
+/*
+*/
+void Slot::updateAllSessionsState( void ) {
+
+    //CK_ULONG ulRole = CK_UNAVAILABLE_INFORMATION;
+    //
+    //    if( isAuthenticated( ) ) {
+
+    //        ulRole = CKU_USER;
+
+    //    } else if( administratorIsAuthenticated( ) ) {
+
+    //        ulRole = CKU_SO;
+    //    }
+
+    BOOST_FOREACH( const MAP_SESSIONS::value_type& i, m_Sessions ) {
+
+        if( i.second ) {
+
+            i.second->updateState( m_ulUserType );
+        }
+    }
+}
+
+
+/*
+*/
+void Slot::initPIN( const CK_SESSION_HANDLE& a_hSession, CK_UTF8CHAR_PTR a_pPin, const CK_ULONG& a_ulPinLen ) {
+
+    Session* s = getSession( a_hSession );
+
+    if( CKS_RW_SO_FUNCTIONS != s->getState( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    Marshaller::u1Array p( a_ulPinLen );
+    p.SetBuffer( a_pPin );
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        m_Token->initPIN( s->getPinSO( ), &p );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::setPIN( const CK_SESSION_HANDLE& a_hSession, CK_UTF8CHAR_PTR a_pOldPin, const CK_ULONG& a_ulOldLen, CK_UTF8CHAR_PTR a_pNewPin, const CK_ULONG& a_ulNewLen ) {
+
+    Session* s = getSession( a_hSession );
+
+    CK_ULONG ulState = s->getState( );
+
+    if( ( CKS_RW_PUBLIC_SESSION != ulState ) && ( CKS_RW_SO_FUNCTIONS != ulState ) && ( CKS_RW_USER_FUNCTIONS != ulState ) ) {
+
+        throw PKCS11Exception( CKR_SESSION_READ_ONLY );
+    }
+
+    Marshaller::u1Array o( a_ulOldLen );
+    o.SetBuffer( a_pOldPin );
+
+    Marshaller::u1Array n( a_ulNewLen );
+    n.SetBuffer( a_pNewPin );
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        m_Token->setPIN( &o, &n );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::closeSession", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::findObjectsInit( const CK_SESSION_HANDLE& a_hSession, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    Session* s = getSession( a_hSession );
+
+    // check if search is active for this session or not
+    if( s->isSearchActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_ACTIVE );
+    }
+
+    Template* searchTmpl = NULL_PTR;
+
+    if( a_ulCount ) {
+
+        searchTmpl = new Template( a_pTemplate, a_ulCount );
+    }
+
+    s->removeSearchTemplate( );
+
+    s->setSearchTemplate( searchTmpl );
+
+    if( !m_Token ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        m_Token->findObjectsInit( );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::closeSession", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::findObjects( const CK_SESSION_HANDLE& a_hSession, CK_OBJECT_HANDLE_PTR a_phObject, const CK_ULONG& a_ulMaxObjectCount, CK_ULONG_PTR a_pulObjectCount ) {
+
+    Session* s = getSession( a_hSession );
+
+    // check if search is active for this session or not
+    if( !s->isSearchActive( )  ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    *a_pulObjectCount = 0;
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // Find the token objects matching the template
+        m_Token->findObjects( s, a_phObject, a_ulMaxObjectCount, a_pulObjectCount );
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Find the session objects matching the template
+    s->findObjects( a_phObject, a_ulMaxObjectCount, a_pulObjectCount );
+}
+
+
+/*
+*/
+void Slot::findObjectsFinal( const CK_SESSION_HANDLE& a_hSession ) {
+
+    Session* s = getSession( a_hSession );
+
+    // check if search is active for this session or not
+    if( !s->isSearchActive( )  ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    s->removeSearchTemplate( );
+}
+
+
+/*
+*/
+void Slot::createObject( const CK_SESSION_HANDLE& a_hSession, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount, CK_OBJECT_HANDLE_PTR a_phObject ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Check template consistency
+    Template t;
+    t.checkTemplate( a_pTemplate, a_ulCount, Template::MODE_CREATE );
+
+    bool bIsToken = t.isToken( a_pTemplate, a_ulCount );
+
+    // if this is a readonly session and user is not logged 
+    // then only public session objects can be created
+    Session* s = getSession( a_hSession );
+
+    if( !s->isReadWrite( ) && bIsToken ) {
+
+        throw PKCS11Exception( CKR_SESSION_READ_ONLY );
+    }
+
+    StorageObject* o = 0;
+
+    CK_ULONG ulClass = t.getClass( a_pTemplate, a_ulCount );
+
+    switch( ulClass ) {
+
+    case CKO_DATA:
+        o = new DataObject( );
+        break;
+
+    case CKO_PUBLIC_KEY:
+        o = new Pkcs11ObjectKeyPublicRSA( );
+        break;
+
+    case CKO_PRIVATE_KEY:
+        o = new RSAPrivateKeyObject( );
+        break;
+
+    case CKO_CERTIFICATE:
+        o = new X509PubKeyCertObject( );
+        break;
+
+    default:
+        throw PKCS11Exception( CKR_ATTRIBUTE_TYPE_INVALID );
+    }
+
+    for( CK_BYTE idx = 0; idx < a_ulCount; ++idx ) {
+
+        o->setAttribute( a_pTemplate[ idx ], true );
+    }
+
+    switch( ulClass ) {
+
+    case CKO_PUBLIC_KEY:
+        if(((Pkcs11ObjectKeyPublicRSA*)o)->_keyType != CKK_RSA) {
+
+            throw PKCS11Exception( CKR_KEY_TYPE_INCONSISTENT );
+        }
+        break;
+
+    case CKO_PRIVATE_KEY:
+        if(((RSAPrivateKeyObject*)o)->_keyType != CKK_RSA) {
+
+            throw PKCS11Exception( CKR_KEY_TYPE_INCONSISTENT );
+        }
+        break;
+    }
+
+    if( bIsToken ) {
+
+        switch( ulClass ) {
+
+        case CKO_PUBLIC_KEY:
+            m_Token->addObjectPublicKey( (Pkcs11ObjectKeyPublicRSA*)o, a_phObject );
+            break;
+
+        case CKO_PRIVATE_KEY:
+            m_Token->addObjectPrivateKey( (RSAPrivateKeyObject*)o, a_phObject );
+            break;
+
+        case CKO_CERTIFICATE:
+            m_Token->addObjectCertificate( (X509PubKeyCertObject*)o, a_phObject );
+            break;
+
+        default:
+            m_Token->addObject( o, a_phObject );
+            break;
+        }
+
+    } else {
+
+        s->addObject( o, a_phObject );
+    }
+}
+
+
+/*
+*/
+void Slot::destroyObject( const CK_SESSION_HANDLE& a_hSession, const CK_OBJECT_HANDLE& a_hObject ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    try {
+
+        // from object handle we can determine if it is a token object or session object
+        if( m_Token->isToken( a_hObject ) ) {
+
+            // if this is a readonly session and user is not logged then only public session objects can be created
+            if( !s->isReadWrite( ) ) {
+
+                throw PKCS11Exception( CKR_SESSION_READ_ONLY );
+            }
+
+            m_Token->deleteObject( a_hObject );
+
+        } else {
+
+            s->deleteObject( a_hObject );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::getAttributeValue( const CK_SESSION_HANDLE& a_hSession, const CK_OBJECT_HANDLE& a_hObject, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        if( m_Token->isToken( a_hObject ) ) {
+
+            m_Token->getAttributeValue( a_hObject, a_pTemplate, a_ulCount );
+
+        } else {
+
+            m_Sessions.at( a_hSession ).getAttributeValue( a_hObject, a_pTemplate, a_ulCount );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::setAttributeValue( const CK_SESSION_HANDLE& a_hSession, const CK_OBJECT_HANDLE& a_hObject, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    try {
+
+        if( m_Token->isToken( a_hObject ) ) {
+
+            if( !s->isReadWrite( ) ) {
+
+                throw PKCS11Exception( CKR_SESSION_READ_ONLY );
+            }
+
+            m_Token->setAttributeValue( a_hObject, a_pTemplate, a_ulCount );
+
+        } else {
+
+            s->setAttributeValue( a_hObject, a_pTemplate, a_ulCount );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::generateKeyPair( const CK_SESSION_HANDLE& a_hSession, CK_MECHANISM_PTR /*a_pMechanism*/, CK_ATTRIBUTE_PTR a_pPublicKeyTemplate, const CK_ULONG& a_ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR a_pPrivateKeyTemplate, const CK_ULONG& a_ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR a_phPublicKey,CK_OBJECT_HANDLE_PTR a_phPrivateKey ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    // Check Public Template Consitency
+    Template t;
+    t.checkTemplate( a_pPublicKeyTemplate, a_ulPublicKeyAttributeCount, Template::MODE_GENERATE_PUB );
+
+    // Check Private Template Consitency
+    t.checkTemplate( a_pPrivateKeyTemplate, a_ulPrivateKeyAttributeCount, Template::MODE_GENERATE_PRIV );
+
+    // Create the PKCS11 public key
+    Pkcs11ObjectKeyPublicRSA* rsaPubKey = new Pkcs11ObjectKeyPublicRSA( );
+
+    // Create the PKCS11 private key
+    RSAPrivateKeyObject* rsaPrivKey = new RSAPrivateKeyObject( );
+
+    // Populate the PKCS11 public key
+    try {
+
+        for( unsigned long i = 0 ; i < a_ulPublicKeyAttributeCount ; ++i ) {
+
+            rsaPubKey->setAttribute( a_pPublicKeyTemplate[ i ], true );
+        }
+
+        // Populate the PKCS11 private key
+        for( unsigned long i = 0 ; i < a_ulPrivateKeyAttributeCount ; ++i ) {
+
+            rsaPrivKey->setAttribute( a_pPrivateKeyTemplate[ i ], true );
+        }
+
+        // Generate the key pair on cars
+        if( rsaPrivKey->isToken( ) ) {
+
+            m_Token->generateKeyPair( rsaPubKey, rsaPrivKey, a_phPublicKey, a_phPrivateKey );
+
+        } else {
+
+            // We do not support generation of key pair in the session
+            throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+        }
+
+        // Create the PKCS11 public key object on cache if it is not a token object
+        if( rsaPubKey && !rsaPubKey->isToken( ) ) {
+
+            s->addObject( rsaPubKey, a_phPublicKey );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        // the generation failed
+        delete rsaPrivKey;
+        delete rsaPubKey;
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        // We do not support generation of key pair in the session
+        delete rsaPrivKey;
+        delete rsaPubKey;
+        throw;
+
+    } catch( ... ) {
+
+        delete rsaPrivKey;
+        delete rsaPubKey;
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::digestInit( const CK_SESSION_HANDLE& a_hSession, CK_MECHANISM_PTR a_pMechanism ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( s->isDigestActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_ACTIVE );
+    }
+
+    switch( a_pMechanism->mechanism ) {
+
+    case CKM_SHA_1:
+        s->setDigest( new CSHA1( ) );
+        break;
+
+    case CKM_SHA256:
+        s->setDigest( new CSHA256( ) );
+        break;
+
+    case CKM_MD5:
+        s->setDigest( new CMD5( ) );
+        break;
+
+    default:
+        throw PKCS11Exception( CKR_MECHANISM_INVALID );
+    }
+}
+
+
+/*
+*/
+void Slot::digest( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pData, const CK_ULONG& a_ulDataLen, CK_BYTE_PTR a_pDigest, CK_ULONG_PTR a_pulDigestLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isDigestActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    CDigest* digest = s->getDigest( );
+    if( !digest ) {
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+
+    if((*a_pulDigestLen < (CK_ULONG)digest->hashLength( )) && a_pDigest ) {
+
+        *a_pulDigestLen = (CK_ULONG)digest->hashLength( );
+
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+
+    } else if(!a_pDigest) {
+
+        *a_pulDigestLen = digest->hashLength( );
+
+    } else {
+
+        digest->hashCore(a_pData, 0, a_ulDataLen);
+
+        *a_pulDigestLen = (CK_ULONG)digest->hashLength( );
+
+        if( a_pDigest ) {
+            digest->hashFinal(a_pDigest);
+
+            s->removeDigest( );
+        }
+    }
+}
+
+
+/*
+*/
+void Slot::digestUpdate( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pPart, const CK_ULONG& a_ulPartLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isDigestActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    s->getDigest( )->hashCore( a_pPart, 0, a_ulPartLen );
+}
+
+
+/*
+*/
+void Slot::digestFinal( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pDigest, CK_ULONG_PTR a_pulDigestLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isDigestActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    CDigest* digest = s->getDigest( );
+    if( !digest ) {
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if((*a_pulDigestLen < (CK_ULONG)digest->hashLength( )) && a_pDigest ) {
+
+        *a_pulDigestLen = (CK_ULONG)digest->hashLength( );
+
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+
+    } else if( !a_pDigest ) {
+
+        *a_pulDigestLen = digest->hashLength( );
+
+    } else {
+
+        *a_pulDigestLen = (CK_ULONG)digest->hashLength( );
+
+        if ( a_pDigest ){
+
+            digest->hashFinal( a_pDigest );
+
+            s->removeDigest( );
+        }
+    }
+}
+
+
+/*
+*/
+void Slot::signInit( const CK_SESSION_HANDLE& a_hSession, CK_MECHANISM_PTR a_pMechanism, const CK_OBJECT_HANDLE& a_hKey ) {
+
+    Session* s = getSession( a_hSession );
+
+    if( s->isSignatureActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_ACTIVE );
+    }
+
+    isValidMechanism( a_pMechanism->mechanism, CKF_SIGN );
+
+    if( !isAuthenticated( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    // get the corresponding object
+    StorageObject* o = 0;
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // from object handle we can determine
+        // if it is a token object or session object
+        if( m_Token->isToken( a_hKey ) ) {
+
+            o = m_Token->getObject( a_hKey );
+
+        } else {
+
+            o = s->getObject( a_hKey );
+        }
+
+    } catch( PKCS11Exception& ) {
+
+        throw PKCS11Exception( CKR_KEY_HANDLE_INVALID );
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    isValidCryptoOperation( o, CKF_SIGN );
+
+    // Initialize this crypto operation
+    boost::shared_ptr< CryptoOperation > co( new CryptoOperation( a_pMechanism->mechanism, a_hKey ) );
+
+    s->setSignatureOperation( co );
+
+    if( CKM_SHA1_RSA_PKCS == a_pMechanism->mechanism ){
+
+        s->setDigestRSA( new CSHA1( ) );
+
+    } else if( CKM_SHA256_RSA_PKCS == a_pMechanism->mechanism ){
+
+        s->setDigestRSA( new CSHA256( ) );
+
+    } else if( CKM_MD5_RSA_PKCS == a_pMechanism->mechanism ){
+
+        s->setDigestRSA( new CMD5( ) );
+    }
+}
+
+
+/*
+*/
+void Slot::sign( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pData, const CK_ULONG& a_ulDataLen, CK_BYTE_PTR a_pSignature, CK_ULONG_PTR a_pulSignatureLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isSignatureActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    // Get the RSA private key object ot perform the signature
+    RSAPrivateKeyObject *o = (RSAPrivateKeyObject*) m_Token->getObject( s->getSignature( )->getObject( ) );
+    if( !o ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    // Get the PKCS11 mechanism to use
+    CK_ULONG m = s->getSignature( )->getMechanism( );
+
+    // TBD : Private key may not necessarily have the modulus or modulus bits
+    // if that is the case then we need to locate the corresponding public key
+    // or may be I should always put the modulus bits in private key attributes
+
+    Marshaller::u1Array* u = o->m_pModulus.get( );
+    if( !u ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if( ( ( m == CKM_RSA_PKCS ) && ( a_ulDataLen > u->GetLength( ) - 11 ) ) || ( ( m == CKM_RSA_X_509 ) && ( a_ulDataLen > u->GetLength( ) ) ) ) {
+
+        throw PKCS11Exception( CKR_DATA_LEN_RANGE );
+    }
+
+    if( !a_pSignature ) {
+
+        *a_pulSignatureLen = u->GetLength();
+
+        return;
+
+    } else if( *a_pulSignatureLen < u->GetLength( ) ) {
+
+        *a_pulSignatureLen = u->GetLength();
+
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > dataToSign;
+
+    if( s->isDigestActiveRSA( ) ) {
+
+        if( !s->_digestRSA ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        // require hashing also
+        CDigest* d = s->_digestRSA.get( );
+
+        if( !d ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        CK_BYTE_PTR h = new CK_BYTE[ d->hashLength( ) ];
+        d->hashCore( a_pData, 0, a_ulDataLen );
+        d->hashFinal( h );
+
+        dataToSign.reset( new Marshaller::u1Array( d->hashLength( ) ) );
+        dataToSign->SetBuffer( h );
+
+        delete[ ] h;
+
+    } else {
+
+        // Sign Only
+        dataToSign.reset( new Marshaller::u1Array( a_ulDataLen ) );
+        dataToSign->SetBuffer( a_pData );
+    }
+
+    try {
+
+        m_Token->sign( o, dataToSign.get( ), m, a_pSignature );
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    *a_pulSignatureLen = u->GetLength( );
+
+    s->removeDigestRSA( );
+
+    s->removeSignatureOperation( );
+
+    // Check if the user is still logged in
+    // If the smart card is configured in "always PIN" mode
+    // the PIN is automatically invalidated after a sign operation
+    try {
+
+        if( m_Device.get( ) && !m_Device->isAuthenticated( ) ) {
+
+            // No user connected
+            m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+            // Update the state of all sessions because write access is no more allowed
+            updateAllSessionsState( );
+        }
+
+    } catch( ... ) { }
+}
+
+
+/* update the hash or if hashing is not getting used we just accumulate it
+*/
+void Slot::signUpdate( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pPart, const CK_ULONG& a_ulPartLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isSignatureActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if( s->isDigestActiveRSA( ) ) {
+
+        if( !s->_digestRSA ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        s->_digestRSA->hashCore( a_pPart, 0, a_ulPartLen );
+
+    } else { // Sign Only
+
+        if( s->m_AccumulatedDataToSign ) {
+
+            // just accumulate the data
+            Marshaller::u1Array* updatedData = new Marshaller::u1Array( s->m_AccumulatedDataToSign->GetLength() + a_ulPartLen);
+
+            memcpy(updatedData->GetBuffer(),s->m_AccumulatedDataToSign->GetBuffer(),s->m_AccumulatedDataToSign->GetLength());
+
+            memcpy((u1*)&updatedData->GetBuffer()[s->m_AccumulatedDataToSign->GetLength()], a_pPart, a_ulPartLen);
+
+            s->m_AccumulatedDataToSign.reset( updatedData );
+
+        } else {
+
+            s->m_AccumulatedDataToSign.reset( new Marshaller::u1Array( a_ulPartLen ) );
+
+            s->m_AccumulatedDataToSign->SetBuffer( a_pPart );
+        }
+
+        CK_ULONG m = s->getSignature( )->getMechanism( );
+
+        StorageObject* o = NULL;
+
+        try {
+
+            o = m_Token->getObject( s->getSignature( )->getObject( ) );
+
+        } catch( MiniDriverException& x ) {
+
+            throw PKCS11Exception( Token::checkException( x ) );
+
+        } catch( PKCS11Exception& x ) {
+
+            checkAccessException( x );
+
+            throw;
+
+        } catch( ... ) {
+
+            throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+        }
+
+        if( !o ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        Marshaller::u1Array* u = ((RSAPrivateKeyObject*)o)->m_pModulus.get( );
+
+        if( !u ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        if( ( ( m == CKM_RSA_PKCS ) && ( s->m_AccumulatedDataToSign->GetLength( ) > u->GetLength( ) - 11 ) ) ||
+            ( ( m == CKM_RSA_X_509 ) && ( s->m_AccumulatedDataToSign->GetLength( ) > u->GetLength( ) ) ) ) {
+
+                throw PKCS11Exception( CKR_DATA_LEN_RANGE );
+        }
+    }
+}
+
+
+/*
+*/
+void Slot::signFinal( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pSignature, CK_ULONG_PTR a_pulSignatureLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isSignatureActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    RSAPrivateKeyObject* o = (RSAPrivateKeyObject*) m_Token->getObject( s->getSignature( )->getObject( ) );
+    if( !o ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    // TBD : Private key may not necessarily have the modulus or modulus bits
+    // if that is the case then we need to locate the corresponding public key
+    // or may be I should always put the modulus bits in private key attributes
+
+    Marshaller::u1Array* u = o->m_pModulus.get( );
+    if( !u ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if( !a_pSignature ) {
+
+        *a_pulSignatureLen = u->GetLength( );
+
+        return;
+
+    } else if( *a_pulSignatureLen < u->GetLength( ) ) {
+
+        *a_pulSignatureLen = u->GetLength( );
+
+        throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > dataToSign;
+
+    if( s->isDigestActiveRSA( ) ) {
+
+        if( !s->_digestRSA ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        // require hashing also
+        CDigest* d = s->_digestRSA.get( );
+        if( !d ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        CK_BYTE_PTR h = new CK_BYTE[ d->hashLength( ) ];
+
+        d->hashFinal( h );
+
+        dataToSign.reset( new Marshaller::u1Array( d->hashLength( ) ) );
+
+        dataToSign->SetBuffer( h );
+
+    } else {
+
+        // Sign Only
+        dataToSign = s->m_AccumulatedDataToSign;
+    }
+
+    if( !s->m_Signature ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    m_Token->sign( o, dataToSign.get( ), s->m_Signature->getMechanism( ), a_pSignature );
+
+    *a_pulSignatureLen = u->GetLength( );
+
+    s->removeDigestRSA( );
+
+    s->removeSignatureOperation( );
+
+    s->m_AccumulatedDataToSign.reset( );
+}
+
+
+/*
+*/
+void Slot::encryptInit( const CK_SESSION_HANDLE& a_hSession, CK_MECHANISM_PTR a_pMechanism, const CK_OBJECT_HANDLE& a_hKey ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( s->isEncryptionActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_ACTIVE );
+    }
+
+    isValidMechanism( a_pMechanism->mechanism, CKF_ENCRYPT );
+
+    if( !isAuthenticated( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    // get the corresponding object
+    StorageObject* o = 0;
+
+    try {
+
+        // from object handle we can determine
+        // if it is a token object or session object
+        if( m_Token->isToken( a_hKey ) ) {
+
+            o = m_Token->getObject( a_hKey );
+
+        } else {
+
+            o = s->getObject( a_hKey );
+        }
+
+    } catch( PKCS11Exception& ) {
+
+        throw PKCS11Exception( CKR_KEY_HANDLE_INVALID );
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    isValidCryptoOperation( o, CKF_ENCRYPT );
+
+    // let's initialize this crypto operation
+    s->setEncryptionOperation( new CryptoOperation( a_pMechanism->mechanism, a_hKey ) );
+}
+
+
+/*
+*/
+void Slot::encrypt( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pData, const CK_ULONG& a_ulDataLen, CK_BYTE_PTR a_pEncryptedData, CK_ULONG_PTR a_pulEncryptedDataLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isEncryptionActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    StorageObject* o = NULL;
+
+    Marshaller::u1Array* u = NULL;
+
+    try {
+
+        if( !s->_encryption ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        o = m_Token->getObject( s->_encryption->getObject( ) );
+        if( !o ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        u = ((Pkcs11ObjectKeyPublicRSA*)o)->m_pModulus.get( );
+        if( !u ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        if( !a_pEncryptedData ) {
+
+            *a_pulEncryptedDataLen = u->GetLength();
+
+            return;
+
+        } else {
+
+            if( *a_pulEncryptedDataLen < u->GetLength( ) ) {
+
+                *a_pulEncryptedDataLen = u->GetLength();
+
+                throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+            }
+        }
+
+        boost::shared_ptr< Marshaller::u1Array > dataToEncrypt( new Marshaller::u1Array( a_ulDataLen ) );
+        dataToEncrypt->SetBuffer( a_pData );
+
+        if( !s->_encryption ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        m_Token->encrypt( o, dataToEncrypt.get( ), s->_encryption->getMechanism( ), a_pEncryptedData );
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    *a_pulEncryptedDataLen = u->GetLength( );
+
+    s->removeEncryptionOperation( );
+}
+
+
+/*
+*/
+void Slot::decryptInit( const CK_SESSION_HANDLE& a_hSession, CK_MECHANISM_PTR a_pMechanism, const CK_OBJECT_HANDLE& a_hKey ) {
+
+    if( !m_Token.get( ) /*|| !m_Device.get( )*/ ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( s->isDecryptionActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_ACTIVE );
+    }
+
+    isValidMechanism( a_pMechanism->mechanism, CKF_DECRYPT );
+
+    //try {
+
+    //    if( !m_Device->isAuthenticated( ) ) {
+
+    //        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    //    }
+
+    //} catch( MiniDriverException& x ) {
+
+    //    Log::error( "Slot::decryptInit", "MiniDriverException" );
+    //    throw PKCS11Exception( Token::checkException( x ) );
+    //}
+    if( !isAuthenticated( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    // get the corresponding object
+    StorageObject* o = 0;
+
+    // from object handle we can know if it is a token or session object
+    try {
+
+        if( m_Token->isToken( a_hKey ) ) {
+
+            o = m_Token->getObject( a_hKey );
+
+        } else {
+
+            o = s->getObject( a_hKey );
+        }
+
+    } catch( PKCS11Exception& ) {
+
+        throw PKCS11Exception( CKR_KEY_HANDLE_INVALID );
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    isValidCryptoOperation( o, CKF_DECRYPT );
+
+    // let's initialize this crypto operation
+    s->setDecryptionOperation( new CryptoOperation( a_pMechanism->mechanism, a_hKey ) );
+}
+
+
+/*
+*/
+void Slot::decrypt( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pEncryptedData, const CK_ULONG& a_ulEncryptedDataLen, CK_BYTE_PTR a_pData, CK_ULONG_PTR a_pulDataLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isDecryptionActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if( !s->_decryption ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    StorageObject* o = m_Token->getObject( s->_decryption->getObject( ) );
+    if( !o ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    CK_ULONG m = s->_decryption->getMechanism( );
+
+    Marshaller::u1Array* u = ( (RSAPrivateKeyObject*) o)->m_pModulus.get( );
+    if( !u ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    unsigned long l = (unsigned long)u->GetLength( );
+
+    if( m == CKM_RSA_PKCS ) {
+
+        // Can't know exact size of returned value before decryption has been done
+        if( !a_pData ) {
+
+            *a_pulDataLen = l - 11;
+
+            return;
+        }
+    } else if( m == CKM_RSA_X_509 ) {
+
+        if( !a_pData ) {
+
+            *a_pulDataLen = l;
+
+            return;
+
+        } else {
+
+            if( *a_pulDataLen < l ) {
+
+                *a_pulDataLen = l;
+
+                throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+            }
+        }
+    } else {
+
+        throw PKCS11Exception( CKR_MECHANISM_INVALID );
+    }
+
+    if( a_ulEncryptedDataLen != l ) {
+
+        throw PKCS11Exception( CKR_ENCRYPTED_DATA_LEN_RANGE );
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > dataToDecrypt( new Marshaller::u1Array( a_ulEncryptedDataLen ) );
+
+    dataToDecrypt->SetBuffer( a_pEncryptedData );
+
+    try {
+
+        m_Token->decrypt( o, dataToDecrypt.get( ), m, a_pData, a_pulDataLen );
+
+    } catch( MiniDriverException& x ) {
+
+        s->removeDecryptionOperation( );
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        s->removeDecryptionOperation( );
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        s->removeDecryptionOperation( );
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    s->removeDecryptionOperation( );
+
+    // Check if the user is still logged in
+    // If the smart card is configured in "always PIN" mode
+    // the PIN is automatically invalidated after a sign operation
+    try {
+
+        if( m_Device.get( ) && !m_Device->isAuthenticated( ) ) {
+
+            // No user connected
+            m_ulUserType = CK_UNAVAILABLE_INFORMATION;
+
+            // Update the state of all sessions because write access is no more allowed
+            updateAllSessionsState( );
+        }
+
+    } catch( ... ) { }
+}
+
+
+/*
+*/
+void Slot::verifyInit( const CK_SESSION_HANDLE& a_hSession, CK_MECHANISM_PTR a_pMechanism, const CK_OBJECT_HANDLE& a_hKey ) {
+
+    if( !m_Token.get( )/* || !m_Device.get( )*/ ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( s->isVerificationActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_ACTIVE );
+    }
+
+    isValidMechanism( a_pMechanism->mechanism, CKF_VERIFY );
+
+    /*   try {
+
+    if( !m_Device->isAuthenticated( ) ) {
+
+    throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    } catch( MiniDriverException& x ) {
+
+    Log::error( "Slot::verifyInit", "MiniDriverException" );
+    throw PKCS11Exception( Token::checkException( x ) );
+    }*/
+    if( !isAuthenticated( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    // get the corresponding object
+    StorageObject* o = 0;
+
+    try {
+
+        // from object handle we can know if it is a token or session object
+        if( m_Token->isToken( a_hKey ) ) {
+
+            o = m_Token->getObject( a_hKey);
+
+        } else {
+
+            o = s->getObject( a_hKey );
+
+        }
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw PKCS11Exception( CKR_KEY_HANDLE_INVALID );
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    isValidCryptoOperation( o, CKF_VERIFY );
+
+    // Initialize this crypto operation
+    s->setVerificationOperation( new CryptoOperation( a_pMechanism->mechanism, a_hKey ) );
+
+    if( CKM_SHA1_RSA_PKCS == a_pMechanism->mechanism ) {
+
+        s->setDigestRSAVerification( new CSHA1( ) );
+
+    } else if( CKM_SHA256_RSA_PKCS == a_pMechanism->mechanism ) {
+
+        s->setDigestRSAVerification( new CSHA256( ) );
+
+    } else if(CKM_MD5_RSA_PKCS == a_pMechanism->mechanism ){
+
+        s->setDigestRSAVerification( new CMD5( ) );
+    }
+}
+
+
+/*
+*/
+void Slot::verify( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pData, const CK_ULONG& a_ulDataLen, CK_BYTE_PTR a_pSignature, const CK_ULONG a_ulSignatureLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isVerificationActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if( !s->_verification ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    CK_ULONG m = s->_verification->getMechanism( );
+
+    try {
+
+        StorageObject* o = m_Token->getObject( s->_verification->getObject( ) );
+        if( !o ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        Marshaller::u1Array* u = ( (Pkcs11ObjectKeyPublicRSA*) o )->m_pModulus.get( );
+        if( !u ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        if( ( ( m == CKM_RSA_PKCS ) && (a_ulDataLen > u->GetLength( ) - 11 ) ) || ( ( m == CKM_RSA_X_509 ) && ( a_ulDataLen > u->GetLength( ) ) ) ) {
+
+            throw PKCS11Exception( CKR_DATA_LEN_RANGE );
+        }
+
+        boost::shared_ptr< Marshaller::u1Array > dataToVerify;
+
+        if( s->isDigestVerificationActiveRSA( ) ) {
+
+            if( !s->_digestRSAVerification ) {
+
+                throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+            }
+
+            // require hashing also
+            CDigest* d = s->_digestRSAVerification.get( );
+            if( !d ) {
+
+                throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+            }
+
+            CK_BYTE_PTR h = new CK_BYTE[ d->hashLength( ) ];
+
+            d->hashCore( a_pData, 0, a_ulDataLen );
+
+            d->hashFinal( h );
+
+            dataToVerify.reset( new Marshaller::u1Array( d->hashLength( ) ) );
+
+            dataToVerify->SetBuffer( h );
+
+            delete[ ] h;
+
+        } else { // Sign Only
+
+            dataToVerify.reset( new Marshaller::u1Array( a_ulDataLen ) );
+
+            dataToVerify->SetBuffer( a_pData );
+        }
+
+        boost::shared_ptr< Marshaller::u1Array > signature( new Marshaller::u1Array( a_ulSignatureLen ) );
+
+        signature->SetBuffer( a_pSignature );
+
+        m_Token->verify( o, dataToVerify.get( ), m, signature.get( ) );
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+    } catch( MiniDriverException& x ) {
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+        throw;
+
+    } catch( ... ) {
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*	Update the hash or if hashing is not getting used we just accumulate it
+*/
+void Slot::verifyUpdate( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pPart, const CK_ULONG& a_ulPartLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isVerificationActive( ) ){
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    if( s->isDigestVerificationActiveRSA( ) ) {
+
+        if( !s->_digestRSAVerification ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        CDigest* digest = s->_digestRSAVerification.get( );
+        if( !digest ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        digest->hashCore( a_pPart, 0, a_ulPartLen );
+
+    } else { 
+
+        // Sign Only
+
+        if( s->m_AccumulatedDataToVerify.get( ) ) { 
+
+            // just accumulate the data
+            Marshaller::u1Array* pAccumulatedDataToVerify = s->m_AccumulatedDataToVerify.get( );
+
+            Marshaller::u1Array* updatedData = new Marshaller::u1Array( pAccumulatedDataToVerify->GetLength( ) + a_ulPartLen );
+
+            memcpy( updatedData->GetBuffer( ), pAccumulatedDataToVerify->GetBuffer( ), pAccumulatedDataToVerify->GetLength( ) );
+
+            memcpy( (u1*)&updatedData->GetBuffer()[ pAccumulatedDataToVerify->GetLength( )], a_pPart, a_ulPartLen );
+
+            s->m_AccumulatedDataToVerify.reset( updatedData );
+
+        } else {
+
+            s->m_AccumulatedDataToVerify.reset( new Marshaller::u1Array( a_ulPartLen ) );
+
+            s->m_AccumulatedDataToVerify->SetBuffer( a_pPart );
+        }
+
+        if( !s->_verification ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        CK_ULONG m = s->_verification->getMechanism( );
+
+        StorageObject* o = NULL;
+
+        try {
+
+            o = m_Token->getObject( s->_verification->getObject( ) );
+
+        } catch( MiniDriverException& x ) {
+
+            throw PKCS11Exception( Token::checkException( x ) );
+
+        } catch( PKCS11Exception& x ) {
+
+            checkAccessException( x );
+
+            throw;
+
+        } catch( ... ) {
+
+            throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+        }
+
+        if( !o ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        Marshaller::u1Array* u = ( (Pkcs11ObjectKeyPublicRSA*) o )->m_pModulus.get( );
+
+        if( !u ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        if((( m == CKM_RSA_PKCS) && (s->m_AccumulatedDataToVerify->GetLength() > u->GetLength() - 11)) ||
+            (( m == CKM_RSA_X_509) && (s->m_AccumulatedDataToVerify->GetLength() > u->GetLength())))
+        {
+            throw PKCS11Exception( CKR_DATA_LEN_RANGE );
+        }
+    }
+}
+
+
+/*
+*/
+void Slot::verifyFinal( const CK_SESSION_HANDLE& a_hSession, CK_BYTE_PTR a_pSignature, const CK_ULONG& a_ulSignatureLen ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    Session* s = getSession( a_hSession );
+
+    if( !s->isVerificationActive( ) ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > dataToVerify;
+
+    if( s->isDigestVerificationActiveRSA( ) ) {
+
+        if( !s->_digestRSAVerification ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        // require hashing also
+        CDigest* digest = s->_digestRSAVerification.get( );
+
+        if( !digest ) {
+
+            throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+        }
+
+        CK_BYTE_PTR hash = new CK_BYTE[ digest->hashLength( ) ];
+
+        digest->hashFinal( hash );
+
+        dataToVerify.reset( new Marshaller::u1Array( digest->hashLength( ) ) );
+
+        dataToVerify->SetBuffer( hash );
+
+        delete[ ] hash;
+
+    } else {
+
+        // Sign Only
+        dataToVerify = s->m_AccumulatedDataToVerify;
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > signature( new Marshaller::u1Array( a_ulSignatureLen ) );
+
+    signature->SetBuffer( a_pSignature );
+
+    if( !s->_verification ) {
+
+        throw PKCS11Exception( CKR_OPERATION_NOT_INITIALIZED );
+    }
+
+    try {
+
+        StorageObject* o = m_Token->getObject( s->_verification->getObject( ) );
+
+        m_Token->verify( o, dataToVerify.get( ), s->_verification->getMechanism( ), signature.get( ) );
+
+    } catch( MiniDriverException& x ) {
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+        s->m_AccumulatedDataToVerify.reset( );
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+        s->m_AccumulatedDataToVerify.reset( );
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        s->removeDigestRSAVerification( );
+
+        s->removeVerificationOperation( );
+
+        s->m_AccumulatedDataToVerify.reset( );
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    s->removeDigestRSAVerification( );
+
+    s->removeVerificationOperation( );
+
+    s->m_AccumulatedDataToVerify.reset( );
+}
+
+
+/*
+*/
+CK_SESSION_HANDLE Slot::addSession( const bool& a_bIsReadWrite ) {
+
+    // Prepare a unique session id
+    CK_SESSION_HANDLE h = computeSessionHandle( a_bIsReadWrite );
+
+    // Create & store the session instance
+    m_Sessions.insert( h, new Session( this, h, a_bIsReadWrite ) );
+
+    // Return the session handle
+    return h;
+}
+
+
+/*
+*/
+CK_SESSION_HANDLE Slot::computeSessionHandle( const bool& a_bIsReadWrite ) {
+
+    if( !m_Device.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // A session handle is a 4 or more bytes long unsigned data.
+    CK_SESSION_HANDLE h = 0x00000000;
+
+    // He here the convention to compute the session handle:
+
+    // byte #1: session index. We do not accept to open more than 255 sessions.
+    h |= ++s_ucSessionIndex;
+
+    // byte #2: session properties has R/W or R/O
+    h |= ( a_bIsReadWrite << 8 );
+
+    // byte #3: slot index associated to this session
+    unsigned char ucDeviceID = 0xFF;
+
+    try {
+
+        ucDeviceID = m_Device->getDeviceID( );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Slot::computeSessionHandle", "MiniDriverException" );
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    h |= ( ucDeviceID << 16 );
+
+    // byte #4: RFU and set to 0x00
+
+    return h;
+}
+
+
+/*
+*/
+void Slot::removeSession( const CK_SESSION_HANDLE& a_ulSessionId ) {
+
+    if( !m_Token.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    m_Sessions.erase( a_ulSessionId );
+
+    try {
+
+        // if this was the last session to be removed then the login 
+        // state of token for application returns to public sessions
+        if( !m_Sessions.size( ) ) {
+
+            m_Token->setLoggedRole( CK_UNAVAILABLE_INFORMATION );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& ) {
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+bool Slot::hasReadOnlySession( void ) {
+
+    BOOST_FOREACH( const MAP_SESSIONS::value_type& i, m_Sessions ) {
+
+        if( i.second && !i.second->isReadWrite( ) ) {
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+/*
+*/
+void Slot::isValidMechanism( const CK_ULONG& a_mechanism, const CK_ULONG& a_Operation )
+{
+    bool bFound = false;
+
+    size_t max = sizeof( g_mechanismList ) / sizeof( CK_ULONG );
+
+    for( size_t i = 0; i < max ; ++i ) {
+
+        if( g_mechanismList[ i ] == a_mechanism ){
+
+            if( ( g_mechanismInfo[ i ].flags & a_Operation ) != a_Operation ) {
+
+                throw PKCS11Exception( CKR_MECHANISM_INVALID );
+            }
+
+            bFound = true;
+
+            break;
+        }
+    }
+
+    if( !bFound ) {
+
+        throw PKCS11Exception( CKR_MECHANISM_INVALID );
+    }
+}
+
+
+/*
+*/
+void Slot::isValidCryptoOperation( StorageObject* a_pObject, const CK_ULONG& a_ulOperation ) {
+
+    if( !a_pObject ) {
+
+        throw PKCS11Exception( CKR_KEY_TYPE_INCONSISTENT );
+    }
+
+    CK_OBJECT_CLASS c = a_pObject->getClass( );
+
+    // Check if key is consistent
+    switch( a_ulOperation ) {
+    case CKF_ENCRYPT:
+    case CKF_VERIFY:
+    case CKF_VERIFY_RECOVER:
+        if(c != CKO_PUBLIC_KEY && c != CKO_SECRET_KEY){
+            throw PKCS11Exception(  CKR_KEY_TYPE_INCONSISTENT );
+        }
+        break;
+
+    case CKF_DECRYPT:
+    case CKF_SIGN:
+    case CKF_SIGN_RECOVER:
+        if( ( c != CKO_PRIVATE_KEY ) && ( c != CKO_SECRET_KEY ) ) {
+
+            throw PKCS11Exception( CKR_KEY_TYPE_INCONSISTENT );
+        }
+        break;
+    }
+
+    // Check if key supports the operation
+    switch( a_ulOperation )
+    {
+    case CKF_ENCRYPT:
+        if(((c == CKO_PUBLIC_KEY)&&(!((Pkcs11ObjectKeyPublicRSA*)a_pObject)->_encrypt)) ){
+            throw PKCS11Exception( CKR_KEY_FUNCTION_NOT_PERMITTED );
+        }
+        break;
+
+    case CKF_DECRYPT:
+        if(((c == CKO_PRIVATE_KEY)&&(!((RSAPrivateKeyObject*)a_pObject)->_decrypt))	){
+            throw PKCS11Exception(  CKR_KEY_FUNCTION_NOT_PERMITTED );
+        }
+        break;
+
+    case CKF_VERIFY:
+        if(((c == CKO_PUBLIC_KEY)&&(!((Pkcs11ObjectKeyPublicRSA*)a_pObject)->_verify)) ){
+            throw PKCS11Exception(  CKR_KEY_FUNCTION_NOT_PERMITTED );
+        }
+        break;
+
+    case CKF_VERIFY_RECOVER:
+        if(((c == CKO_PUBLIC_KEY)&&(!((Pkcs11ObjectKeyPublicRSA*)a_pObject)->_verifyRecover))){
+            throw PKCS11Exception(  CKR_KEY_FUNCTION_NOT_PERMITTED );
+        }
+        break;
+
+    case CKF_SIGN:
+        if(((c == CKO_PRIVATE_KEY)&&(!((RSAPrivateKeyObject*)a_pObject)->_sign)) ){
+            throw PKCS11Exception(  CKR_KEY_FUNCTION_NOT_PERMITTED );
+        }
+        break;
+
+    case CKF_SIGN_RECOVER:
+        if(((c == CKO_PRIVATE_KEY)&&(!((RSAPrivateKeyObject*)a_pObject)->_signRecover))){
+            throw PKCS11Exception(  CKR_KEY_FUNCTION_NOT_PERMITTED );
+        }
+        break;
+    }
+}
+
+
+/*
+*/
+bool Slot::isSessionOwner( const CK_SESSION_HANDLE& a_hSession ) {
+
+    MAP_SESSIONS::iterator i = m_Sessions.find( a_hSession );
+
+    if( m_Sessions.end( ) == i ) {
+
+        return false;
+    }
+
+    return true;
+}
+
+
+/*
+*/
+Session* Slot::getSession( const CK_SESSION_HANDLE& a_hSession ) { 
+
+    MAP_SESSIONS::iterator i = m_Sessions.find( a_hSession );
+
+    if( i == m_Sessions.end( ) ) {
+
+        throw PKCS11Exception( CKR_SESSION_HANDLE_INVALID ); 
+    } 
+
+    return i->second; 
+}
+
+
+/*
+*/
+void Slot::getCardProperty( CK_BYTE a_ucProperty, CK_BYTE a_ucFlags, CK_BYTE_PTR a_pValue, CK_ULONG_PTR a_pValueLen ) {
+
+    if( !m_Device.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        Marshaller::u1Array* pPropertyValue = m_Device->getCardProperty( a_ucProperty, a_ucFlags );
+
+        if( !pPropertyValue ) {
+
+            *a_pValueLen = 0;
+
+            return;
+        }
+
+        if( !a_pValue ) {
+
+            // If the incoming buffer pointer is null then only return the expected size
+            *a_pValueLen = pPropertyValue->GetLength( );
+
+            return;
+
+        } else {
+
+            // If the incoming buffer is too smal then throw an error
+            if( *a_pValueLen < pPropertyValue->GetLength( ) ) {
+
+                *a_pValueLen = pPropertyValue->GetLength( );
+
+                throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+            }
+        }
+
+        memcpy( a_pValue, pPropertyValue->GetBuffer( ), pPropertyValue->GetLength( ) );
+
+        *a_pValueLen = pPropertyValue->GetLength( );
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}
+
+
+/*
+*/
+void Slot::setCardProperty( CK_BYTE a_ucProperty, CK_BYTE a_ucFlags, CK_BYTE_PTR a_pValue, CK_ULONG a_ulValueLen ) {
+
+    if( !m_Device.get( ) ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        Marshaller::u1Array prop( a_ulValueLen );
+
+        prop.SetBuffer( a_pValue );
+
+        m_Device->setCardProperty( a_ucProperty, &prop, a_ucFlags );
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( Token::checkException( x ) );
+
+    } catch( PKCS11Exception& x ) {
+
+        checkAccessException( x );
+
+        throw;
+
+    } catch( ... ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+}

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.hpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Slot.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,222 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_SLOT__
+#define __GEMALTO_SLOT__
+
+
+#include <boost/array.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <string>
+#include "Device.hpp"
+#include "Session.hpp"
+#include "Token.hpp"
+#include "PKCS11Exception.hpp"
+
+
+/*
+*/
+class Slot {
+
+
+public:
+
+	typedef boost::ptr_map< CK_SESSION_HANDLE, Session > MAP_SESSIONS;
+
+	Slot( const boost::shared_ptr < Device >& );
+
+    inline virtual ~Slot( ) { try { closeAllSessions( ); } catch( ... ) { } }
+
+
+	/* =========== PKCS11 INTERFACE ===========  */
+
+    void finalize( void );
+	
+	void getInfo( CK_SLOT_INFO_PTR );
+
+	void getTokenInfo( CK_TOKEN_INFO_PTR );
+
+	void getMechanismList( CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR );
+
+	void getMechanismInfo( const CK_MECHANISM_TYPE&, CK_MECHANISM_INFO_PTR );
+
+	void initToken( CK_UTF8CHAR_PTR, const CK_ULONG&, CK_UTF8CHAR_PTR );
+
+	void closeAllSessions( void );
+
+	void openSession( const CK_FLAGS&, CK_VOID_PTR, CK_NOTIFY, CK_SESSION_HANDLE_PTR );
+
+	void closeSession( const CK_SESSION_HANDLE& );
+	
+	void getSessionInfo( const CK_SESSION_HANDLE&, CK_SESSION_INFO_PTR );
+
+	void login( const CK_SESSION_HANDLE&, const CK_USER_TYPE&, CK_UTF8CHAR_PTR, const CK_ULONG& );
+
+	void logout( const CK_SESSION_HANDLE& );
+
+	void initPIN( const CK_SESSION_HANDLE&, CK_UTF8CHAR_PTR, const CK_ULONG& );
+
+	void setPIN( const CK_SESSION_HANDLE&, CK_UTF8CHAR_PTR, const CK_ULONG&, CK_UTF8CHAR_PTR, const CK_ULONG& );
+
+	void createObject( const CK_SESSION_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG&, CK_OBJECT_HANDLE_PTR );
+
+	void destroyObject( const CK_SESSION_HANDLE&, const CK_OBJECT_HANDLE& );
+
+	void getAttributeValue( const CK_SESSION_HANDLE&, const CK_OBJECT_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	void setAttributeValue( const CK_SESSION_HANDLE&, const CK_OBJECT_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	void findObjectsInit( const CK_SESSION_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	void findObjects( const CK_SESSION_HANDLE&, CK_OBJECT_HANDLE_PTR, const CK_ULONG&, CK_ULONG_PTR );
+
+	void findObjectsFinal( const CK_SESSION_HANDLE& );
+
+    inline void generateRandom( const CK_SESSION_HANDLE&, CK_BYTE_PTR a_pRandomData, const CK_ULONG& a_ulRandomLen ) { if( m_Token.get( ) ) { m_Token->generateRandom( a_pRandomData, a_ulRandomLen ); } }
+
+	void generateKeyPair( const CK_SESSION_HANDLE&, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, const CK_ULONG&, CK_ATTRIBUTE_PTR, const CK_ULONG&, CK_OBJECT_HANDLE_PTR, CK_OBJECT_HANDLE_PTR );
+	
+	void encryptInit( const CK_SESSION_HANDLE&, CK_MECHANISM_PTR, const CK_OBJECT_HANDLE& );
+
+	void encrypt( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG&, CK_BYTE_PTR, CK_ULONG_PTR );
+
+	void decryptInit( const CK_SESSION_HANDLE&, CK_MECHANISM_PTR, const CK_OBJECT_HANDLE& );
+
+	void decrypt( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG&, CK_BYTE_PTR, CK_ULONG_PTR );
+
+	void signInit( const CK_SESSION_HANDLE&, CK_MECHANISM_PTR, const CK_OBJECT_HANDLE& );
+
+	void sign( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG&, CK_BYTE_PTR, CK_ULONG_PTR );
+
+	void signUpdate( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG& );
+
+	void signFinal( const CK_SESSION_HANDLE&, CK_BYTE_PTR, CK_ULONG_PTR );
+
+	void digestInit( const CK_SESSION_HANDLE&, CK_MECHANISM_PTR );
+
+	void digest( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG&, CK_BYTE_PTR, CK_ULONG_PTR );
+
+	void digestUpdate( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG& );
+
+	void digestFinal( const CK_SESSION_HANDLE&, CK_BYTE_PTR, CK_ULONG_PTR );
+
+	void verifyInit( const CK_SESSION_HANDLE&, CK_MECHANISM_PTR, const CK_OBJECT_HANDLE& );
+
+	void verify( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG&, CK_BYTE_PTR, const CK_ULONG ); 
+
+	void verifyUpdate( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG& );
+
+	void verifyFinal( const CK_SESSION_HANDLE&, CK_BYTE_PTR, const CK_ULONG& );
+
+
+	inline bool getEvent( void ) { return m_bEvent; }
+
+    inline CK_SLOT_ID getEventSlotId( void ) { return m_ucEventSlotId; }
+
+	inline void setEvent( const bool& a_bEventState, const unsigned char& a_SlotId ) { m_bEvent = a_bEventState; m_ucEventSlotId = a_SlotId; }
+
+	inline const boost::shared_ptr< Token >& getToken( void ) { return m_Token; }
+
+	bool isSessionOwner( const CK_SESSION_HANDLE& a_hSession );
+
+    inline bool isCardPresent( void ) { try { if( m_Device.get( ) ) { return m_Device->isSmartCardPresent( ); } } catch( MiniDriverException& ) { } return false; }
+
+    inline const std::string& getReaderName( void ) { try { if( m_Device.get( ) ) { return m_Device->getReaderName( ); } } catch( MiniDriverException& ) { } return m_stEmpty; }
+
+    inline CK_SLOT_ID getSlotId( void ) { try { if( m_Device.get( ) ) { return m_Device->getDeviceID( ); } } catch( MiniDriverException& ) { } return 0xFF; }
+
+// LCA: Card insertion notif
+    inline void tokenInserted( void ) { Log::log( "SLot::tokenInserted" ); m_isTokenInserted = true; }
+
+    void tokenCreate( void );
+    //inline void tokenCreate( void ) { m_ulUserType = CK_UNAVAILABLE_INFORMATION; m_Token.reset( new Token( this, m_Device.get( ) ) ); try { if( !Device::s_bEnableCache && m_Device.get( ) ) { m_Device->forceGarbageCollection( ); } updateAllSessionsState( ); } catch( ... ) { } }
+	
+    inline void tokenDelete( void ) { m_ulUserType = CK_UNAVAILABLE_INFORMATION; m_Token.reset( ); try { updateAllSessionsState( ); } catch( ... ) { } }
+
+    inline void tokenUpdate( void ) { try { if( m_Token.get( ) ) { m_Token->synchronizeIfSmartCardContentHasChanged( ); } updateAllSessionsState( ); } catch( ... ) { } }
+
+  	boost::shared_ptr< Device > m_Device;
+
+    inline bool isAuthenticated( void ) { return ( CKU_USER == m_ulUserType ); }
+
+    inline bool administratorIsAuthenticated( void ) { return ( CKU_SO == m_ulUserType ); }
+
+    inline CK_USER_TYPE getUserType( void ) { return m_ulUserType; }
+
+    inline void setUserType( const CK_USER_TYPE& a_ulUserType ) { m_ulUserType = a_ulUserType; }
+
+    void getCardProperty( CK_BYTE, CK_BYTE, CK_BYTE_PTR, CK_ULONG_PTR );
+
+    void setCardProperty( CK_BYTE, CK_BYTE, CK_BYTE_PTR, CK_ULONG );
+
+    inline bool isTokenInserted( ) { return m_isTokenInserted; }
+
+private:
+
+    void checkAccessException( const PKCS11Exception& );
+
+    Session* getSession( const CK_SESSION_HANDLE& a_hSession );
+    
+    void updateAllSessionsState( void );
+
+	void clearCache( void );
+
+	void isValidMechanism( const CK_ULONG&, const CK_ULONG& );
+
+	void isValidCryptoOperation( StorageObject*, const CK_ULONG& );
+
+	inline void clear( void ) { closeAllSessions( ); m_Token.reset( ); }
+
+	CK_SESSION_HANDLE addSession( const bool& );
+
+	void removeSession( const CK_SESSION_HANDLE& );
+
+	bool hasReadOnlySession( void );
+
+	CK_SESSION_HANDLE computeSessionHandle( const bool& );
+    
+	void createToken( void ) { m_Token.reset( new Token( this, m_Device.get( ) ) ); }
+
+    void checkTokenInsertion( void );
+
+	bool m_bEvent;
+    
+    unsigned char m_ucEventSlotId;
+
+	CK_SLOT_INFO m_SlotInfo;
+
+	MAP_SESSIONS m_Sessions;
+	
+	boost::shared_ptr< Token > m_Token;
+
+	static unsigned char s_ucSessionIndex;
+
+    std::string m_stEmpty;
+
+    CK_USER_TYPE m_ulUserType;
+
+// LCA: used to remember token insertion
+    bool m_isTokenInserted;
+
+};
+
+#endif // __GEMALTO_SLOT__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,283 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifdef __APPLE__
+#include <PCSC/winscard.h>
+#include <PCSC/wintypes.h>
+#else
+#include <winscard.h>
+#endif
+#include "SmartCardReader.hpp"
+#include "SmartCardReaderException.hpp"
+#include "CardModuleService.hpp"
+
+#ifndef WIN32
+#define SCARD_CTL_CODE(code) (0x42000000 + (code))
+#endif
+
+#include "PCSCMissing.h"
+
+
+#pragma pack(push, mdnet, 1)
+
+typedef struct PIN_VERIFY_STRUCTURE
+{
+    BYTE bTimerOut;                  /* timeout is seconds (00 means use default timeout) */
+    BYTE bTimerOut2;                 /* timeout in seconds after first key stroke */
+    BYTE bmFormatString;             /* formatting options */
+    BYTE bmPINBlockString;           /* bits 7-4 bit size of PIN length in APDU,
+                                     * bits 3-0 PIN block size in bytes after
+                                     * justification and formatting */
+    BYTE bmPINLengthFormat;          /* bits 7-5 RFU,
+                                     * bit 4 set if system units are bytes, clear if
+                                     * system units are bits,
+                                     * bits 3-0 PIN length position in system units
+                                     */
+    BYTE bPINMaxExtraDigit1;         /* Max PIN size*/
+    BYTE bPINMaxExtraDigit2;         /* Min PIN size*/
+    BYTE bEntryValidationCondition;  /* Conditions under which PIN entry should
+                                     * be considered complete */
+    BYTE bNumberMessage;             /* Number of messages to display for PIN
+                                     verification */
+    USHORT wLangId;                  /* Language for messages */
+    BYTE bMsgIndex;                  /* Message index (should be 00) */
+    BYTE bTeoPrologue[3];            /* T=1 block prologue field to use (fill with 00) */
+    ULONG ulDataLength;              /* length of Data to be sent to the ICC */
+    BYTE abData[13];                 /* Data to send to the ICC */
+} PIN_VERIFY_STRUCTURE;
+
+#pragma pack(pop, mdnet)
+
+
+#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
+
+#define FEATURE_VERIFY_PIN_DIRECT 0x06
+
+
+/*
+*/
+SmartCardReader::SmartCardReader( const std::string& a_stReaderName ) {
+
+    m_dwIoctlVerifyPIN = 0;
+
+    m_stReaderName = a_stReaderName;
+
+    m_CardHandle = 0;
+
+    m_bIsSecuredVerifyPIN = boost::logic::indeterminate;
+}
+
+
+/*
+*/
+bool SmartCardReader::isVerifyPinSecured( void ) {
+
+    if( boost::logic::indeterminate( m_bIsSecuredVerifyPIN ) ) {
+
+        // Get Reader Features
+        BYTE outBuffer[ 256 ];
+        //memset( outBuffer, 0, sizeof( outBuffer ) );
+        
+        DWORD dwLen = 0;
+        
+        LONG hResult = SCARD_F_INTERNAL_ERROR;
+
+        unsigned char ucRetry = 0;
+        
+        do {
+
+            memset( outBuffer, 0, sizeof( outBuffer ) );
+            
+            dwLen = 0;
+
+            hResult = SCardControl( m_CardHandle, CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, outBuffer, sizeof( outBuffer ), &dwLen );
+
+            //Log::log( "=============================================================================================== SmartCardReader::isVerifyPinSecured - retry <%d> - result <%#02x>", ucRetry, hResult );
+
+            ucRetry++;
+
+        } while( ( SCARD_S_SUCCESS != hResult ) && ( ucRetry < 5 ) );
+
+
+        if ( ( SCARD_S_SUCCESS == hResult ) && ( dwLen > 0 ) ) {
+
+            m_bIsSecuredVerifyPIN = false;
+
+            int i = 0;
+
+            // Search IOCTL of Verify PIN feature
+            while( ( i + 6 ) <= (int)dwLen ) {
+
+                // Search Verify PIN feature Tag
+                if( ( outBuffer[ i ] == FEATURE_VERIFY_PIN_DIRECT ) && ( outBuffer[ i + 1 ] == 4 ) ) {
+
+                    m_dwIoctlVerifyPIN += ( outBuffer[ i + 2 ] << 24 );
+                    m_dwIoctlVerifyPIN += ( outBuffer[ i + 3 ] << 16 );
+                    m_dwIoctlVerifyPIN += ( outBuffer[ i + 4 ] << 8 );
+                    m_dwIoctlVerifyPIN += outBuffer[ i + 5 ];
+
+                    m_bIsSecuredVerifyPIN = true;
+
+                    break;
+
+                } else {
+
+                    i += (outBuffer[ i + 1 ] + 2 );
+                }
+            }
+        } else {
+         
+            // The ScardControl failed. Return false and read the flag next time
+            return false;
+        }
+    }
+
+    return m_bIsSecuredVerifyPIN;
+}
+
+
+/*
+*/
+void SmartCardReader::verifyPinSecured( const unsigned char& a_ucRole ) {
+
+    if( true != m_bIsSecuredVerifyPIN ) {
+
+        throw SmartCardReaderException( SCARD_E_READER_UNSUPPORTED );
+    }
+
+    //DWORD PinId = a_ucRole;
+    LONG                 lRet;
+    BYTE                 offset;
+    DWORD                dwSendLen;
+    PIN_VERIFY_STRUCTURE pin_verify;
+    BYTE                 inBuffer[256];
+    DWORD                dwInLen = 0;
+    BYTE                 outBuffer[256];
+    DWORD                dwOutLen = 0;
+
+
+    // Time out between key stroke = max(bTimerOut, bTimerOut2). Must be between 15 and 40 sec.
+    pin_verify.bTimerOut = 30;
+    pin_verify.bTimerOut2 = 00;
+
+    // Padding V2=0x82
+    pin_verify.bmFormatString = 0x82;
+
+    pin_verify.bmPINBlockString = 0x06;
+    pin_verify.bmPINLengthFormat = 0x00;
+    // Max PIN length
+    pin_verify.bPINMaxExtraDigit1 = 0x08;
+    // Min PIN length
+    pin_verify.bPINMaxExtraDigit2 = 0x04; 
+    // Validation when key pressed
+    pin_verify.bEntryValidationCondition = 0x02;
+    pin_verify.bNumberMessage = 0x01;
+    pin_verify.wLangId = 0x0904;
+    pin_verify.bMsgIndex = 0x00;
+    pin_verify.bTeoPrologue[0] = 0x00;
+    pin_verify.bTeoPrologue[1] = 0x00;
+
+    // pin_verify.ulDataLength = 0x00; we don't know the size yet
+    pin_verify.bTeoPrologue[2] = 0x00;
+
+    offset = 0;
+    // Class
+    pin_verify.abData[offset++] = 0x00;
+    // Instruction Verify
+    pin_verify.abData[offset++] = 0x20;
+    // P1 always 0
+    pin_verify.abData[offset++] = 0x00;
+    // P2 Pin reference
+    pin_verify.abData[offset++] = a_ucRole;
+    // Lc 8 data bytes
+    pin_verify.abData[offset++] = 0x08;
+
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+    pin_verify.abData[offset++] = 0xFF;
+
+    // APDU size
+    pin_verify.ulDataLength = offset;
+
+    dwSendLen = sizeof(PIN_VERIFY_STRUCTURE);
+
+    // Select MSCM Application
+    inBuffer[0] = 0x00;   //CLA
+    inBuffer[1] = 0xA4;   //INS
+    inBuffer[2] = 0x04;   //P1
+    inBuffer[3] = 0x00;   //P2
+    inBuffer[4] = 0x04;   //Li
+
+    char pCardModuleServiceName[ ] = "MSCM";
+    memcpy( &inBuffer[ 5 ], pCardModuleServiceName, 4 ); // ??? TO DO ??? Manage the size dynamically
+
+    dwInLen = 5 + inBuffer[ 4 ];
+
+    dwOutLen = sizeof(outBuffer);
+    memset(outBuffer, 0x00, sizeof(outBuffer));
+
+    lRet = SCardTransmit( m_CardHandle, SCARD_PCI_T0, inBuffer, dwInLen, NULL, outBuffer, &dwOutLen );
+
+    // Send Verify command to the reader
+    dwOutLen = 0;
+    memset(outBuffer, 0x00, sizeof(outBuffer));
+
+    lRet = SCardControl( m_CardHandle, m_dwIoctlVerifyPIN, (BYTE *)&pin_verify, dwSendLen, outBuffer, sizeof(outBuffer), &dwOutLen );
+
+    if( ( SCARD_W_REMOVED_CARD == lRet ) || ( SCARD_W_RESET_CARD == lRet ) ) {
+
+        DWORD dwActiveProtocol = 0;
+
+        lRet = SCardReconnect( m_CardHandle, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_LEAVE_CARD, &dwActiveProtocol );
+
+        lRet = SCardControl( m_CardHandle, m_dwIoctlVerifyPIN, (BYTE *)&pin_verify, dwSendLen, outBuffer, sizeof(outBuffer), &dwOutLen );
+    }	
+
+    //Log::log( "Token::verifyPinWithPinPad - sw <%#02x %#02x>", outBuffer[ 0 ], outBuffer[ 1 ] );
+
+    if( ( 0x90 == outBuffer[ 0 ] ) && ( 0x00 == outBuffer[ 1 ] ) ) {
+        // The PIN is verified
+
+    } else if( ( 0x63 == outBuffer[ 0 ] ) && ( 0x00 == outBuffer[ 1 ] ) ) {
+
+        throw SmartCardReaderException( SCARD_W_WRONG_CHV );
+
+    } else if( ( 0x64 == outBuffer[ 0 ] ) && ( 0x01 == outBuffer[ 1 ] ) ) {
+
+        // operation was cancelled by the \x91Cancel\x92 button
+        throw SmartCardReaderException( SCARD_W_CANCELLED_BY_USER );
+
+    } else if( ( 0x64 == outBuffer[ 0 ] ) && ( 0x00 == outBuffer[ 1 ] ) ) {
+
+        // operation timed out
+        throw SmartCardReaderException( SCARD_E_TIMEOUT );
+
+    } else if( ( 0x64 == outBuffer[ 0 ] ) && ( 0x03 == outBuffer[ 1 ] ) ) {
+
+        // operation timed out
+        throw SmartCardReaderException( SCARD_E_TIMEOUT );
+    }
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReader.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,60 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_SMARTCARD_READER__
+#define __GEMALTO_SMARTCARD_READER__
+
+
+#include <string>
+#include <boost/logic/tribool.hpp>
+
+
+class SmartCardReader {
+
+public:
+
+	SmartCardReader( const std::string& );
+
+	bool isVerifyPinSecured( void );
+
+	inline const std::string& getReaderName( void ) { return m_stReaderName; }
+
+	inline void setReaderName( const std::string& a_stReaderName ) { m_stReaderName = a_stReaderName; }
+
+	void verifyPinSecured( const unsigned char& );
+
+	inline void setCardHandle( const SCARDHANDLE& a_CardHandle ) { m_CardHandle = a_CardHandle; }
+
+
+private:
+
+	std::string m_stReaderName;
+
+	DWORD m_dwIoctlVerifyPIN;
+
+	SCARDHANDLE m_CardHandle;
+
+    boost::logic::tribool m_bIsSecuredVerifyPIN;
+
+};
+
+
+#endif // __GEMALTO_SMARTCARD_READER__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReaderException.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReaderException.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/SmartCardReaderException.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,50 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifndef __GEMALTO_READER_EXCEPTION__
+#define __GEMALTO_READER_EXCEPTION__
+
+
+#include <string>
+#include <stdexcept>
+
+
+/*
+*/
+class SmartCardReaderException : public std::runtime_error {
+
+public:
+    
+	inline SmartCardReaderException( ) : std::runtime_error( "" ), m_lError( 0 ) { }
+
+    inline SmartCardReaderException(  long a_lError ) : std::runtime_error( "" ), m_lError( a_lError ) { }
+    
+	inline SmartCardReaderException( const std::string& a_stMessage, long a_lError = 0 ) : std::runtime_error( a_stMessage ), m_lError( a_lError ) { }
+
+    inline long getError( void ) const { return m_lError; }
+
+private:
+
+    long m_lError;
+
+};
+
+#endif // __GEMALTO_READER_EXCEPTION__

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Template.cpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Template.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Template.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,320 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include "Template.hpp"
+#include <boost/foreach.hpp>
+#include "PKCS11Exception.hpp"
+#include "Log.hpp"
+
+
+extern bool IS_LITTLE_ENDIAN;
+
+
+/*
+*/
+Template::Template( CK_ATTRIBUTE_PTR a_Template, const CK_ULONG& a_ulCount ) {
+
+    for( CK_ULONG i = 0 ; i < a_ulCount ; ++i ) {
+
+        CK_ATTRIBUTE a;
+
+        a.type = a_Template[ i ].type;
+
+        a.ulValueLen = a_Template[ i ].ulValueLen;
+
+        a.pValue = NULL_PTR;
+
+        if( a.ulValueLen > 0 ) {
+
+            a.pValue = new CK_BYTE[ a.ulValueLen ];
+            
+            memcpy( a.pValue, a_Template[ i ].pValue, a.ulValueLen );
+        }
+
+        m_Attributes.push_back( a );
+    }
+}
+
+
+/*
+*/
+Template::~Template( ) {
+
+    BOOST_FOREACH( CK_ATTRIBUTE& a, m_Attributes ) {
+
+        if( 1 == a.ulValueLen ) {
+
+            delete ( ( CK_BYTE* ) a.pValue );
+
+        } else if( a.ulValueLen > 1 ) {
+        
+            delete[ ] ( ( CK_BYTE* ) a.pValue );
+        }
+    }
+}
+
+
+/*
+*/
+void Template::fixEndianness( CK_ATTRIBUTE& a_attribute ) {
+
+    // Only for Little Endian processors
+    if( IS_LITTLE_ENDIAN ) {
+
+        // we need to fix the endianness if we are dealing with data on 2 or 4 or 8 bytes
+        switch( a_attribute.ulValueLen ) {
+
+        case 2:
+        case 4:
+        case 8:
+            {
+                // fix up needs to be done for specific attributes. Byte arrays may have sizes of 2,4 or 8
+                switch( a_attribute.type ) {
+
+                    // CK_ULONG data types
+                case CKA_CLASS:
+                case CKA_CERTIFICATE_TYPE:
+                case CKA_JAVA_MIDP_SECURITY_DOMAIN:
+                case CKA_KEY_TYPE:
+                case CKA_KEY_GEN_MECHANISM:
+                case CKA_MODULUS_BITS:
+                    {
+                        //PKCS11_ASSERT(attrTemplate.ulValueLen == sizeof(CK_ULONG));
+                        CK_BYTE b1 = ((CK_BYTE_PTR)a_attribute.pValue)[0];
+                        CK_BYTE b2 = ((CK_BYTE_PTR)a_attribute.pValue)[1];
+                        CK_BYTE b3 = ((CK_BYTE_PTR)a_attribute.pValue)[2];
+                        CK_BYTE b4 = ((CK_BYTE_PTR)a_attribute.pValue)[3];
+                        ((CK_BYTE_PTR)a_attribute.pValue)[3] = b1;
+                        ((CK_BYTE_PTR)a_attribute.pValue)[2] = b2;
+                        ((CK_BYTE_PTR)a_attribute.pValue)[1] = b3;
+                        ((CK_BYTE_PTR)a_attribute.pValue)[0] = b4;
+                    }
+                    break;
+                }
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
+}
+
+
+/*
+*/
+CK_OBJECT_CLASS Template::getClass( CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    for( CK_ULONG idx = 0; idx < a_ulCount ; ++idx ) {
+
+        if( CKA_CLASS == a_pTemplate[ idx ].type ) {
+
+            return (*(CK_ULONG*)a_pTemplate[ idx ].pValue);
+        }
+    }
+
+    return CK_UNAVAILABLE_INFORMATION;
+}
+
+
+/*
+*/
+CK_CERTIFICATE_TYPE Template::getCertificateType( CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    for( CK_ULONG idx = 0; idx < a_ulCount ; ++idx ) {
+
+        if( CKA_CERTIFICATE_TYPE == a_pTemplate[ idx ].type ) {
+
+            return (*(CK_ULONG*)a_pTemplate[ idx ].pValue);
+        }
+    }
+
+    return CK_UNAVAILABLE_INFORMATION;
+}
+
+
+/*
+*/
+bool Template::isToken( CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    for( CK_ULONG idx = 0; idx < a_ulCount ; ++idx ) {
+
+        if( CKA_TOKEN == a_pTemplate[ idx ].type ) {
+
+            return (*(bool*)a_pTemplate[ idx ].pValue);
+        }
+    }
+
+    return false;
+}
+
+
+/*
+*/
+bool Template::isPrivate( CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    for( CK_ULONG idx = 0; idx < a_ulCount ; ++idx ) {
+
+        if( CKA_PRIVATE == a_pTemplate[ idx ].type ) {
+
+            return (*(bool*)a_pTemplate[ idx ].pValue);
+        }
+    }
+
+    return false;
+}
+
+
+/*
+*/
+bool Template::isPresent( CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount, const CK_ATTRIBUTE_TYPE& a_ulType ) {
+
+    for( CK_ULONG idx = 0; idx < a_ulCount ; ++idx ) {
+
+        if( a_ulType == a_pTemplate[ idx ].type ) {
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+/*
+*/
+void Template::checkTemplate( CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount, const CK_BYTE& a_bMode ) {
+
+    // Get Object Class
+    CK_OBJECT_CLASS c = getClass( a_pTemplate, a_ulCount );
+
+    // Get Cert Type
+    CK_CERTIFICATE_TYPE t = CK_UNAVAILABLE_INFORMATION;
+    if( CKO_CERTIFICATE == c ) {
+
+        t = getCertificateType( a_pTemplate, a_ulCount );
+    }
+
+    // Check Creation Template
+    if( MODE_CREATE == a_bMode ) {
+
+        switch( c ) {
+
+        case CKO_DATA:
+            {
+                if( isPresent( a_pTemplate, a_ulCount, CKA_CLASS ) ) {
+                    return;
+                }
+            }
+            break;
+
+        case CKO_CERTIFICATE:
+            {
+                if( ( CKC_X_509 == t ) && isPresent( a_pTemplate, a_ulCount, CKA_CLASS ) && isPresent( a_pTemplate, a_ulCount, CKA_SUBJECT ) && isPresent( a_pTemplate, a_ulCount, CKA_VALUE ) ) {
+
+                    return;
+
+                } else if( ( CKC_X_509_ATTR_CERT == t ) && isPresent( a_pTemplate, a_ulCount, CKA_CLASS ) && isPresent( a_pTemplate, a_ulCount, CKA_OWNER ) && isPresent( a_pTemplate, a_ulCount, CKA_VALUE ) ) {
+
+                    return;
+
+                } else {
+                    throw PKCS11Exception( CKR_TEMPLATE_INCONSISTENT );
+                }
+            }
+            break;
+
+        case CKO_PUBLIC_KEY:
+            {
+                if(  isPresent( a_pTemplate, a_ulCount, CKA_CLASS ) && isPresent( a_pTemplate, a_ulCount, CKA_KEY_TYPE ) && !isPresent( a_pTemplate, a_ulCount, CKA_LOCAL ) && !isPresent( a_pTemplate, a_ulCount, CKA_KEY_GEN_MECHANISM )
+                    && isPresent( a_pTemplate, a_ulCount, CKA_MODULUS ) && !isPresent( a_pTemplate, a_ulCount, CKA_MODULUS_BITS ) && isPresent(a_pTemplate, a_ulCount, CKA_PUBLIC_EXPONENT ) ) {
+
+                        return;
+                }
+            }
+            break;
+
+        case CKO_PRIVATE_KEY:
+            {
+                if (  ( isPresent(a_pTemplate, a_ulCount, CKA_CLASS))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_KEY_TYPE))
+                    &&(!isPresent(a_pTemplate, a_ulCount, CKA_LOCAL))
+                    &&(!isPresent(a_pTemplate, a_ulCount, CKA_KEY_GEN_MECHANISM))
+                    &&(!isPresent(a_pTemplate, a_ulCount, CKA_ALWAYS_SENSITIVE))
+                    &&(!isPresent(a_pTemplate, a_ulCount, CKA_NEVER_EXTRACTABLE))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_MODULUS))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_PRIVATE_EXPONENT))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_PRIME_1))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_PRIME_2))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_EXPONENT_1))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_EXPONENT_2))
+                    &&( isPresent(a_pTemplate, a_ulCount, CKA_COEFFICIENT))
+                    )
+                {
+                    return;
+                }
+            }
+            break;
+
+        default:
+            throw PKCS11Exception( CKR_TEMPLATE_INCONSISTENT );
+
+        }
+    }
+
+    // Check Public Key Generation Template
+    else if (a_bMode == MODE_GENERATE_PUB)
+    {
+        if (  (!isPresent(a_pTemplate, a_ulCount, CKA_LOCAL))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_KEY_GEN_MECHANISM))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_MODULUS))
+            &&( isPresent(a_pTemplate, a_ulCount, CKA_MODULUS_BITS))
+            &&( isPresent(a_pTemplate, a_ulCount, CKA_PUBLIC_EXPONENT))
+            )
+        {
+            return;
+        }
+    }
+
+    // Check Private Key Generation Template
+    else if (a_bMode == MODE_GENERATE_PRIV)
+    {
+        if (  (!isPresent(a_pTemplate, a_ulCount, CKA_LOCAL))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_KEY_GEN_MECHANISM))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_ALWAYS_SENSITIVE))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_NEVER_EXTRACTABLE))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_MODULUS))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_PUBLIC_EXPONENT))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_PRIVATE_EXPONENT))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_PRIME_1))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_PRIME_2))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_EXPONENT_1))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_EXPONENT_2))
+            &&(!isPresent(a_pTemplate, a_ulCount, CKA_COEFFICIENT))
+            )
+        {
+            return;
+        }
+    }
+
+    throw PKCS11Exception( CKR_TEMPLATE_INCONSISTENT );
+
+}

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Template.hpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/template.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Template.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Template.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,67 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_TEMPLATE__
+#define __GEMALTO_TEMPLATE__
+
+
+#include <vector>
+#include "cryptoki.h"
+
+
+/*
+*/
+class Template
+{
+
+public:
+
+	enum MODE { MODE_CREATE, MODE_GENERATE_PUB, MODE_GENERATE_PRIV };
+
+	Template( ) { }
+
+	Template( CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	virtual ~Template( );
+
+	void fixEndianness( CK_ATTRIBUTE& );
+
+	CK_OBJECT_CLASS getClass( CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	CK_CERTIFICATE_TYPE getCertificateType( CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	bool isToken( CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	bool isPresent( CK_ATTRIBUTE_PTR, const CK_ULONG&, const CK_ATTRIBUTE_TYPE& );
+
+    bool isPrivate( CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+	void checkTemplate( CK_ATTRIBUTE_PTR, const CK_ULONG&, const unsigned char& );
+
+	inline std::vector< CK_ATTRIBUTE >& getAttributes( void ) { return m_Attributes; }
+
+private:
+
+	std::vector< CK_ATTRIBUTE > m_Attributes;
+
+};
+
+#endif // __GEMALTO_TEMPLATE__

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.cpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,98 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+#include <cstring>
+
+#include "Timer.hpp"
+#include "Log.hpp"
+
+
+/*
+*/
+void Timer::start( void ) {
+
+#ifdef WIN32
+	m_clockStart = clock( );
+#else	
+   gettimeofday( &m_clockStart, NULL ); 
+#endif
+}
+
+
+/*
+*/
+void Timer::stop( const char* a_pMessage ) {
+
+    if( !Log::s_bEnableLog ) {
+
+        return;
+    }
+
+    stop( );
+
+	if( 0.400 < m_Duration ) {
+
+        Log::log( "$$$$$$$$$$$$$$$$$$$$$$$ %s - Elapsed time <%f> seconds", a_pMessage, m_Duration );
+
+    } else {
+        Log::log( "%s - Elapsed time <%f> seconds", a_pMessage, m_Duration );
+    }
+}
+
+
+/*
+*/
+double Timer::getCurrentDuration( void ) {
+ 
+#ifdef WIN32
+      double duration = (double)(clock( ) - m_clockStart) / CLOCKS_PER_SEC;
+	  //m_clockStart = 0;
+#else	
+      timeval now;         
+      gettimeofday( &now, NULL );  
+
+      timeval diff;          
+      diff.tv_sec = now.tv_sec - m_clockStart.tv_sec;
+      diff.tv_usec = now.tv_usec - m_clockStart.tv_usec; 
+      while( diff.tv_usec < 0 )
+      {
+         diff.tv_sec--;
+         diff.tv_usec = 1000000 + ( now.tv_usec - m_clockStart.tv_usec );
+      }
+      double duration = diff.tv_sec;         
+      duration += (double)( diff.tv_usec / 1e6 ); 
+ 
+      //memset( &m_clockStart, 0, sizeof( timeval ) );
+#endif
+
+    //Log::log( "Timer::getCurrentDuration - Elapsed time <%f> seconds", duration );
+
+	return duration;
+}
+
+
+
+
+/*
+*/
+void Timer::stop( void ) {
+
+      m_Duration = getCurrentDuration( );
+}

Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.hpp (from rev 140, trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Timer.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,63 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_TIMER__
+#define __GEMALTO_TIMER__
+
+
+#ifdef WIN32
+#include <time.h>
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+
+/*
+*/
+class Timer {
+
+public:
+	
+	void start( void );
+
+	void stop( void );
+
+    void stop( const char* a_pMessage );
+
+    inline double getDuration( void ) { return m_Duration; }
+
+    double getCurrentDuration( void );
+
+private:
+    
+#ifdef WIN32
+	clock_t m_clockStart;
+#else
+	timeval m_clockStart;
+#endif
+
+    double m_Duration;
+
+};
+
+
+#endif // __GEMALTO_TIMER__

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Token.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Token.cpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Token.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,5487 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto->com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#include <boost/foreach.hpp>
+#include <ctime>
+#include <utility>
+#include <list>
+#include <map>
+#include <memory>
+#include "cryptoki.h"
+#include "symmalgo.h"
+#include "util.h"
+#include "x509cert.h"
+#include "attrcert.h"
+#include "Pkcs11ObjectKeyPublicRSA.hpp"
+#include "Pkcs11ObjectData.hpp"
+#include "PKCS11Exception.hpp"
+#include "md5.h"
+#include "Log.hpp"
+#include "cr_rsa.h"
+#include "Token.hpp"
+#include "MiniDriverException.hpp"
+#include "sha1.h"
+#include "cardmod.h"
+#include "Slot.hpp"
+#include "PCSCMissing.h"
+
+const unsigned char g_ucPKCS_EMEV15_PADDING_TAG = 0x02;
+
+/*
+*/
+Token::Token( Slot* a_pSlot, Device* a_pDevice ) {
+
+    Log::begin( "Token::Token" );
+    Timer t;
+    t.start( );
+
+    m_uiObjectIndex = 0;
+
+    m_bCheckSmartCardContentDone = false;
+
+    m_pSlot = a_pSlot;
+
+    // Initialize a random engine with current time as seed for the generator
+    m_RandomNumberGenerator.seed( static_cast< unsigned int >( std::time( 0 ) ) );
+
+    m_bCreateDirectoryP11 = false;
+
+    m_bCreateTokenInfoFile = false;
+
+    m_bWriteTokenInfoFile = false;
+
+    g_stPathPKCS11 = "p11";
+
+    g_stPathTokenInfo = "tinfo";
+
+    g_stPrefixData = "dat";
+    g_stPrefixKeyPublic = "puk";
+    g_stPrefixKeyPrivate = "prk";
+    // Use the default key exchange certificate extension as root certificate extension
+    g_stPrefixRootCertificate = szUSER_KEYEXCHANGE_CERT_PREFIX;
+
+    g_stPrefixPublicObject = "pub";
+    g_stPrefixPrivateObject = "pri";
+
+    m_Device = a_pDevice;
+
+    // Set the seed for the random generator
+    Marshaller::u1Array challenge( 8 );
+    generateRandom( challenge.GetBuffer( ), 8 );
+    Util::SeedRandom( challenge );
+
+    // Set the default role 
+    m_RoleLogged = CK_UNAVAILABLE_INFORMATION;
+
+    // Check if the PKCS11 directory and the token information file are present
+    checkTokenInfo( );
+
+    try {
+
+        // Populate the token info structure
+        setTokenInfo( );
+
+        // Populate the pulic and private objects
+        m_bSynchronizeObjectsPublic = true;
+        synchronizePublicObjects( );
+
+        m_bSynchronizeObjectsPrivate = true;
+        synchronizePrivateObjects( );
+
+        initializeObjectIndex( );
+
+    } catch( ... ) {
+
+    }
+
+    t.stop( "Token::Token" );
+    Log::end( "Token::Token" );
+}
+
+
+/*
+*/
+void Token::initializeObjectIndex( void ) {
+
+    if( m_bCreateDirectoryP11 ) {
+
+        return;
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    MiniDriverFiles::FILES_NAME fs( m_Device->enumFiles( g_stPathPKCS11 ) );
+
+    m_uiObjectIndex = m_Device->containerCount( ) + 1;
+
+    unsigned char idx = 0xFF;
+
+    BOOST_FOREACH( const std::string& s, fs ) {
+
+        if( s.find( g_stPrefixData ) != std::string::npos ) {
+
+            idx = computeIndex( s );
+
+            if( idx > m_uiObjectIndex ) {
+
+                m_uiObjectIndex = idx;
+            }
+        }
+    }
+
+    Log::log( "Token::initializeObjectIndex - Index <%ld>", m_uiObjectIndex );
+}
+
+
+/*
+*/
+void Token::incrementObjectIndex( void ) {
+
+    if( 0xFF == m_uiObjectIndex ) {
+
+        m_uiObjectIndex = m_Device->containerCount( ) + 1;
+
+    } else {
+
+        ++m_uiObjectIndex;
+    }
+}
+
+
+/*
+*/
+void Token::checkTokenInfo( void ) {
+
+    Log::begin( "Token::checkTokenInfo" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    MiniDriverFiles::FILES_NAME fs;
+
+    try {
+
+        if( m_Device->isV2Plus( ) ) {
+
+            // Check if the P11 directory is present by listing the root directory content
+            std::string s( "root" );
+
+            fs = m_Device->enumFiles( s );
+
+            MiniDriverFiles::FILES_NAME::iterator i = fs.find( g_stPathPKCS11 );
+
+            if( fs.end( ) == i ) {
+
+                m_bCreateDirectoryP11 = true;
+                m_bCreateTokenInfoFile = true;
+                m_bWriteTokenInfoFile = true;
+            }
+
+        } else {
+
+            // Check if the P11 directory is present by listing the directory content
+            fs = m_Device->enumFiles( g_stPathPKCS11 );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        // The token info file does not exist
+        switch( x.getError( ) ) {
+
+            // because the PKCS11 directory is not present
+        case SCARD_E_DIR_NOT_FOUND:
+            m_bCreateDirectoryP11 = true;
+            m_bCreateTokenInfoFile = true;
+            m_bWriteTokenInfoFile = true;
+            break;
+
+        case SCARD_E_NO_SMARTCARD:
+            throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+
+        default:
+            break;
+        }
+    }
+
+    // Check if the token information file is present
+    if( !m_bCreateDirectoryP11 ) {
+
+        try {
+
+            fs = m_Device->enumFiles( g_stPathPKCS11 );
+
+            MiniDriverFiles::FILES_NAME::iterator i = fs.find( g_stPathTokenInfo );
+
+            if( fs.end( ) != i ) {
+
+                try {
+
+                    m_Device->readFile( g_stPathPKCS11, g_stPathTokenInfo );
+
+                } catch( MiniDriverException& x ) {
+
+                    // The token info file does not exist
+                    switch( x.getError( ) ) {
+
+                        // because the token information file is not present
+                    case SCARD_E_FILE_NOT_FOUND:
+                        m_bCreateDirectoryP11 = false;
+                        m_bCreateTokenInfoFile = true;
+                        m_bWriteTokenInfoFile = true;
+
+                    default:
+                        break;
+                    }
+                }
+
+            } else {
+
+                m_bCreateDirectoryP11 = false;
+                m_bCreateTokenInfoFile = true;
+                m_bWriteTokenInfoFile = true;      
+            }
+        
+        } catch( ... ) { }
+    }
+
+    t.stop( "Token::checkTokenInfo" );
+    Log::end( "Token::checkTokenInfo" );
+}
+
+
+/* SerializeTokenInfo
+*/
+void Token::writeTokenInfo( void ) {
+
+    if( !m_bWriteTokenInfoFile ) {
+
+        return;
+    }
+
+    Log::begin( "Token::writeTokenInfo" );
+    Timer t;
+    t.start( );
+
+    std::vector< unsigned char > v;
+
+    // Version
+    CK_BBOOL _version = 1;
+    Util::PushBBoolInVector( &v, _version );
+
+    // Label
+    Marshaller::u1Array l( sizeof( m_TokenInfo.label ) );
+    l.SetBuffer( m_TokenInfo.label );
+    Util::PushByteArrayInVector( &v, &l );
+
+    size_t z = v.size( );
+
+    Marshaller::u1Array objData( z );
+
+    for( unsigned int i = 0 ; i < z ; ++i ) {
+
+        objData.SetU1At( i, v.at( i ) );
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    try {
+
+        m_Device->writeFile( g_stPathPKCS11, g_stPathTokenInfo, &objData );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::log( "## Error ## Token::SerializeTokenInfo - writeFile failed" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    m_bWriteTokenInfoFile = false;
+
+    t.stop( "Token::writeTokenInfo" );
+    Log::end( "Token::writeTokenInfo" );
+}
+
+
+/* Only read the label
+*/
+void Token::readTokenInfo( void ) {
+
+    if( m_bCreateTokenInfoFile ) {
+
+        return;
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    Log::begin( "Token::readTokenInfo" );
+    Timer t;
+    t.start( );
+
+    try {
+
+        Marshaller::u1Array* fileData = m_Device->readFile( g_stPathPKCS11, g_stPathTokenInfo );
+
+        std::vector< unsigned char > v;
+
+        unsigned int l = fileData->GetLength( );
+
+        if( !l ) {
+
+            // The file exists but is empty
+            m_bWriteTokenInfoFile = true;
+
+            return;
+        }
+
+        for( unsigned int u = 0 ; u < l ; ++u ) {
+
+            v.push_back( fileData->GetBuffer( )[ u ] );
+        }
+
+        CK_ULONG idx = 0;
+
+        // Format version. Shall be 0 for this version
+        /*CK_BBOOL _version =*/ Util::ReadBBoolFromVector( v, &idx );
+
+        // label
+        std::auto_ptr< Marshaller::u1Array > label( Util::ReadByteArrayFromVector( v, &idx ) );
+
+        memset( m_TokenInfo.label, ' ', sizeof( m_TokenInfo.label ) );
+
+        memcpy( m_TokenInfo.label, label->GetBuffer( ), label->GetLength( ) );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::readTokenInfo", "MiniDriverException" );
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::readTokenInfo" );
+    Log::end( "Token::readTokenInfo" );
+}
+
+
+/*
+*/
+void Token::createTokenInfo( void ) {
+
+    Log::begin( "Token::createTokenInfo" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    if( m_bCreateDirectoryP11 ) {
+
+        // Create the P11 directory into the smart card
+        try {
+
+            m_Device->createDirectory( std::string( "root" ), g_stPathPKCS11 );
+
+            m_bCreateDirectoryP11 = false;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Token::createTokenInfo", "MiniDriverException" );
+
+            throw PKCS11Exception( checkException( x ) );
+        }
+    }
+
+    if( m_bCreateTokenInfoFile ) {
+
+        // Create the P11 token information file
+        try {
+
+            m_Device->createFile( g_stPathPKCS11, g_stPathTokenInfo, false );
+
+            m_bCreateTokenInfoFile = false;
+
+            m_bWriteTokenInfoFile = true;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Token::createTokenInfo", "MiniDriverException" );
+
+            throw PKCS11Exception( checkException( x ) );
+        }
+    }
+
+    t.stop( "Token::createTokenInfo" );
+    Log::end( "Token::createTokenInfo" );
+}
+
+
+
+/*
+*/
+/*
+void Token::initializeTokenInfo( void ) {
+
+    Log::begin( "Token::initializeTokenInfo" );
+    Timer t;
+    t.start( );
+
+    // flush TokenInfo
+    memset( &m_TokenInfo, 0, sizeof( CK_TOKEN_INFO ) );
+
+    // Set serial number
+    memset( m_TokenInfo.serialNumber, ' ', sizeof( m_TokenInfo.serialNumber ) );
+
+    // Set the default label
+    memset( m_TokenInfo.label, ' ', sizeof( m_TokenInfo.label ) );
+    m_TokenInfo.label[0] = '.';
+    m_TokenInfo.label[1] = 'N';
+    m_TokenInfo.label[2] = 'E';
+    m_TokenInfo.label[3] = 'T';
+    m_TokenInfo.label[4] = ' ';
+    m_TokenInfo.label[5] = '#';
+    memcpy( &m_TokenInfo.label[6], m_TokenInfo.serialNumber, sizeof( m_TokenInfo.serialNumber ) );
+
+    // Set manufacturer id
+    memset( m_TokenInfo.manufacturerID, ' ', sizeof( m_TokenInfo.manufacturerID ) );
+    m_TokenInfo.manufacturerID[0] = 'G';
+    m_TokenInfo.manufacturerID[1] = 'e';
+    m_TokenInfo.manufacturerID[2] = 'm';
+    m_TokenInfo.manufacturerID[3] = 'a';
+    m_TokenInfo.manufacturerID[4] = 'l';
+    m_TokenInfo.manufacturerID[5] = 't';
+    m_TokenInfo.manufacturerID[6] = 'o';
+
+    // Set model
+    memset( m_TokenInfo.model, ' ', sizeof( m_TokenInfo.model ) );
+    m_TokenInfo.model[0] = '.';
+    m_TokenInfo.model[1] = 'N';
+    m_TokenInfo.model[2] = 'E';
+    m_TokenInfo.model[3] = 'T';
+    m_TokenInfo.model[4] = ' ';
+    m_TokenInfo.model[5] = 'C';
+    m_TokenInfo.model[6] = 'a';
+    m_TokenInfo.model[7] = 'r';
+    m_TokenInfo.model[8] = 'd';
+
+    // Set flags
+    m_TokenInfo.flags  =  CKF_LOGIN_REQUIRED | CKF_TOKEN_INITIALIZED | CKF_USER_PIN_INITIALIZED; // | CKF_RNG
+    
+    try {
+
+            if( !m_Device->isPinInitialized( ) ) {
+
+                Log::log( "Token::setTokenInfo - Disable CKF_USER_PIN_INITIALIZED" );
+                m_TokenInfo.flags &= ~CKF_USER_PIN_INITIALIZED;
+            }
+
+            // Is login required ?
+            if(  m_Device->isNoPin( ) || ( m_Device->isSSO( ) && m_pSlot->isAuthenticated( ) ) ) {
+
+                m_TokenInfo.flags &= ~CKF_LOGIN_REQUIRED;
+                Log::log( "Token::setTokenInfo - No login required" );
+            }
+
+            // Check if the CKF_PROTECTED_AUTHENTICATION_PATH flag must be raised
+            if( m_Device->isExternalPin( ) || ( ( m_Device->isModePinOnly( ) && m_Device->isVerifyPinSecured( ) ) || m_Device->isModeNotPinOnly( ) ) ) {
+
+                Log::log( "Token::setTokenInfo - Enable CKF_PROTECTED_AUTHENTICATION_PATH" );
+                m_TokenInfo.flags  |= CKF_PROTECTED_AUTHENTICATION_PATH;
+            }
+        }
+
+    // Set the sessions information
+    m_TokenInfo.ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
+    m_TokenInfo.ulSessionCount = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
+    m_TokenInfo.ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulMaxPinLen = 255;
+    m_TokenInfo.ulMinPinLen = 4;
+
+    // Set the memory information
+    m_TokenInfo.ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
+
+    // Set the version of the Card Operating system
+    m_TokenInfo.hardwareVersion.major  = 0;
+    m_TokenInfo.hardwareVersion.minor  = 0;
+
+    // Set the version of Card Module application
+    m_TokenInfo.firmwareVersion.major  = 0;
+    m_TokenInfo.firmwareVersion.minor  = 0;
+
+    t.stop( "Token::setTokenInfo" );
+    Log::end( "Token::setTokenInfo" );
+}
+*/
+
+/*
+*/
+void Token::setTokenInfo( void )
+{
+    Log::begin( "Token::setTokenInfo" );
+    Timer t;
+    t.start( );
+
+    // flush TokenInfo
+    memset( &m_TokenInfo, 0, sizeof( CK_TOKEN_INFO ) );
+
+    // Set serial number
+    memset( m_TokenInfo.serialNumber, ' ', sizeof( m_TokenInfo.serialNumber ) );
+
+    // If serial number length is too big to fit in 16 (hex) digit field, then use the 8 first bytes of MD5 hash of the original serial number.
+    const Marshaller::u1Array* sn = NULL;
+
+    try {
+
+        if( m_Device ) {
+
+            sn = m_Device->getSerialNumber( );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::setTokenInfo", "MiniDriverException" );
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    if( sn ) {
+
+        unsigned int l = sn->GetLength( );
+
+        unsigned char* p = (unsigned char*) sn->GetBuffer( );
+
+        if( l > 8 ) {
+
+            CMD5 md5;
+            CK_BYTE hash[ 16 ];
+            md5.hashCore( p, 0, l );
+            md5.hashFinal( hash );
+            Util::ConvAscii( hash, 8, m_TokenInfo.serialNumber );
+
+        } else {
+
+            Util::ConvAscii( p, l, m_TokenInfo.serialNumber );
+        }
+    } else {
+
+        CK_CHAR emptySerialNumber[ ] = { 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30 }; 
+
+        memcpy( m_TokenInfo.serialNumber, emptySerialNumber, sizeof( emptySerialNumber ) );
+    }
+
+    // Set the default label
+    memset( m_TokenInfo.label, ' ', sizeof( m_TokenInfo.label ) );
+    m_TokenInfo.label[0] = '.';
+    m_TokenInfo.label[1] = 'N';
+    m_TokenInfo.label[2] = 'E';
+    m_TokenInfo.label[3] = 'T';
+    m_TokenInfo.label[4] = ' ';
+    m_TokenInfo.label[5] = '#';
+    memcpy( &m_TokenInfo.label[6], m_TokenInfo.serialNumber, sizeof( m_TokenInfo.serialNumber ) );
+
+    // Try to read the token information from the smart card (only read the label)
+    try {
+
+        readTokenInfo( );
+
+    } catch( MiniDriverException& ) {
+
+        m_bCreateTokenInfoFile = true;
+        m_bWriteTokenInfoFile = true;
+    }
+
+    // Set manufacturer id
+    memset( m_TokenInfo.manufacturerID, ' ', sizeof( m_TokenInfo.manufacturerID ) );
+    m_TokenInfo.manufacturerID[0] = 'G';
+    m_TokenInfo.manufacturerID[1] = 'e';
+    m_TokenInfo.manufacturerID[2] = 'm';
+    m_TokenInfo.manufacturerID[3] = 'a';
+    m_TokenInfo.manufacturerID[4] = 'l';
+    m_TokenInfo.manufacturerID[5] = 't';
+    m_TokenInfo.manufacturerID[6] = 'o';
+
+    // Set model
+    memset( m_TokenInfo.model, ' ', sizeof( m_TokenInfo.model ) );
+    m_TokenInfo.model[0] = '.';
+    m_TokenInfo.model[1] = 'N';
+    m_TokenInfo.model[2] = 'E';
+    m_TokenInfo.model[3] = 'T';
+    m_TokenInfo.model[4] = ' ';
+    m_TokenInfo.model[5] = 'C';
+    m_TokenInfo.model[6] = 'a';
+    m_TokenInfo.model[7] = 'r';
+    m_TokenInfo.model[8] = 'd';
+
+    // Set flags
+    m_TokenInfo.flags  = /*CKF_RNG |*/ CKF_LOGIN_REQUIRED | CKF_TOKEN_INITIALIZED /*| CKF_USER_PIN_INITIALIZED*/;
+
+    try {
+
+        if( m_Device && m_pSlot ) {
+
+            Log::log( "Token::Token - No Pin <%d>", m_Device->isNoPin( ) );
+            Log::log( "Token::Token - SSO <%d>", m_Device->isSSO( ) );
+            Log::log( "Token::Token - External <%d>", m_Device->isExternalPin( ) );
+            Log::log( "Token::Token - isAuthenticated <%d>", m_pSlot->isAuthenticated( ) );
+            Log::log( "Token::Token - isReadOnly <%d>", m_Device->isReadOnly( ) );
+            Log::log( "Token::Token - isPinInitialized <%d>", m_Device->isPinInitialized( ) );
+            Log::log( "Token::Token - isVerifyPinSecured <%d>", m_Device->isVerifyPinSecured( ) );
+
+            if( m_Device->isReadOnly( ) ) {
+
+                Log::log( "Token::setTokenInfo - Enable CKF_WRITE_PROTECTED" );
+                m_TokenInfo.flags |= CKF_WRITE_PROTECTED;
+            }
+
+            if( m_Device->isPinInitialized( ) ) {
+
+                Log::log( "Token::setTokenInfo - Enable CKF_USER_PIN_INITIALIZED" );
+                m_TokenInfo.flags |= CKF_USER_PIN_INITIALIZED;
+            }
+
+            // Is login required ?
+            if(  m_Device->isNoPin( ) || ( m_Device->isSSO( ) && m_pSlot->isAuthenticated( ) ) ) {
+
+                m_TokenInfo.flags &= ~CKF_LOGIN_REQUIRED;
+                Log::log( "Token::setTokenInfo - No login required" );
+            }
+
+            // Check if the CKF_PROTECTED_AUTHENTICATION_PATH flag must be raised
+            if( m_Device->isExternalPin( ) || ( ( m_Device->isModePinOnly( ) && m_Device->isVerifyPinSecured( ) ) || m_Device->isModeNotPinOnly( ) ) ) {
+
+                Log::log( "Token::setTokenInfo - Enable CKF_PROTECTED_AUTHENTICATION_PATH" );
+                m_TokenInfo.flags  |= CKF_PROTECTED_AUTHENTICATION_PATH;
+            }
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::setTokenInfo", "MiniDriverException" );
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    // Set the sessions information
+    m_TokenInfo.ulMaxSessionCount = CK_EFFECTIVELY_INFINITE;
+    m_TokenInfo.ulSessionCount = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulMaxRwSessionCount = CK_EFFECTIVELY_INFINITE;
+    m_TokenInfo.ulRwSessionCount = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulMaxPinLen = 255;
+    m_TokenInfo.ulMinPinLen = 4;
+    try {
+        if( m_Device ) {
+
+            m_TokenInfo.ulMaxPinLen = m_Device->getPinMaxPinLength( );
+
+            m_TokenInfo.ulMinPinLen = m_Device->getPinMinPinLength( );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::setTokenInfo", "MiniDriverException" );
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    // Set the memory information
+    m_TokenInfo.ulTotalPublicMemory = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulTotalPrivateMemory = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulFreePrivateMemory = CK_UNAVAILABLE_INFORMATION;
+    m_TokenInfo.ulFreePublicMemory = CK_UNAVAILABLE_INFORMATION;
+
+    // Set the version of the Card Operating system
+    m_TokenInfo.hardwareVersion.major  = 0;
+    m_TokenInfo.hardwareVersion.minor  = 0;
+
+    // Set the version of Card Module application
+    m_TokenInfo.firmwareVersion.major  = 0;
+    m_TokenInfo.firmwareVersion.minor  = 0;
+
+    t.stop( "Token::setTokenInfo" );
+    Log::end( "Token::setTokenInfo" );
+}
+
+
+/*
+*/
+void Token::authenticateUser( Marshaller::u1Array* a_pPin ) {
+
+    Log::begin( "Token::authenticateUser" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        m_Device->verifyPin( a_pPin );
+
+        m_TokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
+        m_TokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
+        m_TokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
+
+        m_RoleLogged = CKU_USER;
+
+    } catch( MiniDriverException& x ) {
+
+        m_RoleLogged = CK_UNAVAILABLE_INFORMATION;
+
+        checkAuthenticationStatus( CKU_USER, x );
+    }
+
+    t.stop( "Token::authenticateUser" );
+    Log::end( "Token::authenticateUser" );
+}
+
+
+/*
+*/
+void Token::checkAuthenticationStatus( CK_ULONG a_ulRole, MiniDriverException& a_Exception ) {
+
+    switch( a_Exception.getError( ) ) {
+
+    case SCARD_W_CARD_NOT_AUTHENTICATED:
+    case SCARD_W_WRONG_CHV:
+        {
+            // Authentication failed due to an incorrect PIN
+            int triesRemaining = 0;
+
+            try {
+
+                triesRemaining = ( ( CKU_USER == a_ulRole ) ? m_Device->getTriesRemaining( ) : m_Device->administratorGetTriesRemaining( ) );                  
+
+            } catch( MiniDriverException& x ) {
+
+                Log::error( "Token::checkAuthenticationStatus", "MiniDriverException" );
+                throw PKCS11Exception( checkException( x ) );
+            }
+
+            // Update the token information structure
+            if( 0 == triesRemaining ) {
+
+                // PIN / Admin key is blocked
+                if( CKU_USER == a_ulRole ) {
+
+                    m_TokenInfo.flags |= CKF_USER_PIN_LOCKED;
+                    m_TokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
+                    m_TokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
+
+                } else {
+
+                    m_TokenInfo.flags |= CKF_SO_PIN_LOCKED;
+                    m_TokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
+                    m_TokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
+                }
+
+                throw PKCS11Exception( CKR_PIN_LOCKED );
+
+            } else if( 1 == triesRemaining ) {
+
+                // Last retry
+                if( CKU_USER == a_ulRole ) {
+
+                    m_TokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
+                    m_TokenInfo.flags |= CKF_USER_PIN_FINAL_TRY;
+                    m_TokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
+
+                } else {
+
+                    m_TokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
+                    m_TokenInfo.flags |= CKF_SO_PIN_FINAL_TRY;
+                    m_TokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
+                }
+            } else { //if(triesRemaining < MAX_USER_PIN_TRIES)
+
+                if( CKU_USER == a_ulRole ) {
+
+                    m_TokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
+                    m_TokenInfo.flags |= CKF_USER_PIN_FINAL_TRY;
+                    m_TokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
+
+                } else {
+
+                    m_TokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
+                    m_TokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
+                    m_TokenInfo.flags |= CKF_SO_PIN_COUNT_LOW;
+                }
+            }
+
+            throw PKCS11Exception ( CKR_PIN_INCORRECT );
+        }
+        break;
+
+    case SCARD_W_CANCELLED_BY_USER:
+    case SCARD_E_TIMEOUT:
+        throw PKCS11Exception( CKR_FUNCTION_CANCELED );
+
+    default:
+        throw PKCS11Exception( checkException( a_Exception ) );
+    }
+
+}
+
+
+/*
+*/
+void Token::authenticateAdmin( Marshaller::u1Array* a_pPin ) {
+
+    Log::begin( "Token::authenticateAdmin" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        m_Device->administratorLogin( a_pPin );
+
+        m_RoleLogged = CKU_SO;
+
+    } catch( MiniDriverException& x ) {
+
+        m_RoleLogged = CK_UNAVAILABLE_INFORMATION;
+
+        checkAuthenticationStatus( CKU_SO, x );
+    }
+
+    t.stop( "Token::authenticateAdmin" );
+    Log::end( "Token::authenticateAdmin" );
+}
+
+
+/*
+*/
+void Token::logout( void ) {
+
+    Log::begin( "Token::logout" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device || !m_pSlot ) {
+
+        Log::log( "Token::logout - Token not present" );
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    m_RoleLogged = CK_UNAVAILABLE_INFORMATION;
+
+    try {
+
+        if( m_pSlot->isAuthenticated( ) ) {
+
+            m_Device->logOut( );
+
+        } else if( m_pSlot->administratorIsAuthenticated( ) ) {
+
+            m_Device->administratorLogout( );
+
+        } else {
+
+            Log::log( "Token::logout - user not logged in" );
+            throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+        }    
+
+    } catch( MiniDriverException& x ) {
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::logout" );
+    Log::end( "Token::logout" );
+}
+
+
+/*
+*/
+void Token::login( const CK_ULONG& a_ulUserType, Marshaller::u1Array* a_pPin ) {
+
+    Log::begin( "Token::login" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device || !m_pSlot ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        if( CKU_USER == a_ulUserType ) {
+
+            if( ( m_TokenInfo.flags & CKF_USER_PIN_INITIALIZED ) != CKF_USER_PIN_INITIALIZED ) {
+
+                throw PKCS11Exception( CKR_USER_PIN_NOT_INITIALIZED );
+            }
+
+            if( m_pSlot->administratorIsAuthenticated( ) ) {
+
+                throw PKCS11Exception( CKR_USER_ANOTHER_ALREADY_LOGGED_IN );
+            }
+
+            if( m_pSlot->isAuthenticated( ) ) {
+
+                throw PKCS11Exception( CKR_USER_ALREADY_LOGGED_IN );
+            }
+
+            if( !m_pSlot->isAuthenticated( ) ) {
+
+                authenticateUser( a_pPin );
+                m_pSlot->setUserType( a_ulUserType );
+            }
+
+        } else if( CKU_SO == a_ulUserType ) {
+
+            if( m_pSlot->administratorIsAuthenticated( ) ) {
+
+                throw PKCS11Exception( CKR_USER_ALREADY_LOGGED_IN );
+            }
+
+            if( m_pSlot->isAuthenticated( ) ) {
+
+                throw PKCS11Exception( CKR_USER_ANOTHER_ALREADY_LOGGED_IN );
+            }
+
+            if( !m_pSlot->administratorIsAuthenticated( ) ) {
+
+                authenticateAdmin( a_pPin );
+
+                m_pSlot->setUserType( a_ulUserType );
+            }
+
+        } else {
+
+            throw PKCS11Exception( CKR_USER_TYPE_INVALID );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::login", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    try {
+
+        // The smart card is checked to avoid to have empty containers with certificates
+        if( checkSmartCardContent( ) ) {
+
+            m_ObjectsToCreate.clear( );
+
+            synchronizeObjects( );
+        } 
+
+        BOOST_FOREACH( StorageObject* p, m_ObjectsToCreate ) {
+
+            Log::log( "Token::login - *** CREATE LATER *** <%s>", p->m_stFileName.c_str( ) );
+
+            try {
+
+                writeObject( p );
+
+            } catch( ... ) {
+
+            }
+        }
+
+        m_ObjectsToCreate.clear( );
+
+        // After a successfull login, the cache has to be updated to get all private objects
+        synchronizePrivateObjects( );
+        //}
+
+    } catch( ... ) { 
+
+    }
+
+    if( !Log::s_bEnableLog ) {
+
+        Log::log(" Token::login - <<<<< P11 OBJ LIST >>>>>");
+        BOOST_FOREACH( const TOKEN_OBJECTS::value_type& o, m_Objects ) { printObject( o.second ); }
+        Log::log(" Token::login - <<<<< P11 OBJ LIST >>>>>");
+    }
+
+    t.stop( "Token::login" );
+    Log::end( "Token::login" );
+}
+
+
+/*
+*/
+void Token::generateRandom( CK_BYTE_PTR a_pRandomData, const CK_ULONG& a_ulLen ) {
+
+    Log::begin( "Token::generateRandom" );
+    Timer t;
+    t.start( );
+
+    // Initialize the range from the 0 to 255 for the generator
+    boost::uniform_smallint< > range( 0, 255 );
+
+    // initialize the generator
+    boost::variate_generator< boost::mt19937&, boost::uniform_smallint< > > generator( m_RandomNumberGenerator, range );
+
+    // Generate the random buffer
+    for( CK_ULONG i = 0 ; i < a_ulLen ; ++i ) {
+
+        a_pRandomData[ i ] = (CK_BYTE)generator( );
+    }
+
+    t.stop( "Token::generateRandom" );
+    Log::end( "Token::generateRandom" );
+}
+
+
+/*
+*/
+void Token::findObjects( Session* a_pSession, CK_OBJECT_HANDLE_PTR a_phObject, const CK_ULONG& a_ulMaxObjectCount, CK_ULONG_PTR a_pulObjectCount ) {
+
+    //Log::begin( "Token::findObjects" );
+    //Timer t;
+
+    //t.start( );
+
+    bool bUserAuthenticated = false;
+
+    if( m_pSlot ) {
+
+        bUserAuthenticated = m_pSlot->isAuthenticated( );
+
+    }
+
+    // For each P11 object
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& o, m_Objects ) {
+
+        // Check if the search has reached the allowed maximum of objects to search 
+        if( *a_pulObjectCount >= a_ulMaxObjectCount ) {
+
+            break;
+        }
+
+        // Check if this object has been already compared to the search template
+        if( m_TokenObjectsReturnedInSearch.end( ) != m_TokenObjectsReturnedInSearch.find( o->first ) ) {
+
+            // This object has already been analysed by a previous call of findObjects for this template
+            continue;
+        }
+
+        // If the object is private and the user is not logged in
+        if( ( !bUserAuthenticated ) && o->second->isPrivate( ) )
+        {
+            // Then avoid this element. 
+            // Do not add it the list of already explored objects (may be a C_Login can occur)
+            continue;
+        }
+
+        // Add the object to the list of the objects compared to the search template
+        m_TokenObjectsReturnedInSearch.insert( o->first );
+
+        // If the template is NULL then return all objects
+        if( !a_pSession->_searchTempl ) {
+
+            a_phObject[ *a_pulObjectCount ] = o->first;
+
+            ++(*a_pulObjectCount);
+
+        } else {
+            // The template is not NULL.
+
+            bool match = true;
+
+            // In this case the template attributes have to be compared to the objects ones.
+            BOOST_FOREACH( CK_ATTRIBUTE& t, a_pSession->_searchTempl->getAttributes( ) ) {
+
+                if( ! o->second->compare( t ) ) {
+
+                    match = false;
+
+                    break;
+                }
+            }
+
+            // The attributes match
+            if( match ) {
+
+                // Add the object handle to the outgoing list
+                a_phObject[ *a_pulObjectCount ] = o->first;
+
+                // Increment the number of found objects
+                ++(*a_pulObjectCount);
+            }
+        }
+    }
+
+    //t.stop( "Token::findObjects" );
+    //Log::end( "Token::findObjects" );
+}
+
+
+/*
+*/
+void Token::computeObjectFileName( StorageObject* a_pObject, std::string& a_stFileName ) {
+
+    Log::begin( "Token::computeObjectFileName" );
+    Timer t;
+    t.start( );
+
+    // Add the public or private prefix
+    std::string stName /*a_stFileName*/ = "";//( a_pObject->isPrivate( ) ? g_stPrefixPrivateObject : g_stPrefixPublicObject );
+
+    switch( a_pObject->getClass ( ) ) {
+
+    case CKO_DATA:
+        computeObjectNameData( /*a_stFileName*/stName, a_pObject );
+        break;
+
+    case CKO_PUBLIC_KEY:
+        computeObjectNamePublicKey( /*a_stFileName*/stName, a_pObject );
+        break;
+
+    case CKO_PRIVATE_KEY:
+        computeObjectNamePrivateKey( /*a_stFileName*/stName, a_pObject );
+        break;
+
+    case CKO_CERTIFICATE:
+        computeObjectNameCertificate( /*a_stFileName*/stName, a_pObject );
+        break;
+
+    default:
+        throw PKCS11Exception( CKR_FUNCTION_FAILED );
+    }
+
+    a_stFileName = stName;
+    
+    Log::log( "Token::computeObjectFileName - Name <%s>", a_stFileName.c_str( ) );
+    t.stop( "Token::computeObjectFileName" );
+    Log::end( "Token::computeObjectFileName" );
+}
+
+
+/*
+*/
+void Token::computeObjectNameData( std::string& a_stFileName, /*const*/ StorageObject* a_pObject ) {
+
+    // Add the public or private prefix
+    a_stFileName = ( a_pObject->isPrivate( ) ? g_stPrefixPrivateObject : g_stPrefixPublicObject );
+
+    // Add the prefix
+    a_stFileName.append( g_stPrefixData );
+
+    MiniDriverFiles::FILES_NAME filesPKCS11;
+    
+    if( !m_bCreateDirectoryP11 ) {
+        
+        filesPKCS11 = m_Device->enumFiles( g_stPathPKCS11 );
+    }
+
+    bool bGoodNameFound = false;
+
+    std::string s;
+
+    do {
+        
+        s = a_stFileName;
+        
+        incrementObjectIndex( );
+
+        // Add the index of the data object
+        Util::toStringHex( m_uiObjectIndex, s );
+
+        if( isObjectNameValid( s, filesPKCS11 ) ) {
+        
+            bGoodNameFound = true;
+
+            a_stFileName = s;
+        }
+
+    } while( !bGoodNameFound );
+}
+
+
+/*
+*/
+bool Token::isObjectNameValid( const std::string& a_stFileName, const MiniDriverFiles::FILES_NAME& a_filesList ) {
+
+    bool bReturn = true;
+
+    BOOST_FOREACH( const std::string& s, a_filesList ) {
+
+        if( s.compare( a_stFileName ) == 0 ) {
+
+            bReturn = false;
+
+            break;
+        }
+    }
+
+    return bReturn;
+}
+
+
+/*
+*/
+void Token::computeObjectNamePublicKey( std::string& a_stFileName, /*const*/ StorageObject* a_pObject ) {
+
+    // Add the public or private prefix
+    a_stFileName = ( a_pObject->isPrivate( ) ? g_stPrefixPrivateObject : g_stPrefixPublicObject );
+
+    // Add the prefix
+    a_stFileName.append( g_stPrefixKeyPublic );
+
+    unsigned char ucContainerIndex = ( (Pkcs11ObjectKeyPublicRSA*) a_pObject )->m_ucContainerIndex;
+
+    MiniDriverFiles::FILES_NAME filesPKCS11;
+    
+    if( !m_bCreateDirectoryP11 ) {
+        
+        filesPKCS11 = m_Device->enumFiles( g_stPathPKCS11 );
+    }
+
+    bool bGoodNameFound = false;
+
+    std::string s;
+
+    // The container index excists the file name must have the same name
+    if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID != ucContainerIndex ) {
+
+        Util::toStringHex( ucContainerIndex, a_stFileName );
+
+    } else {
+
+        unsigned int uiStartIndex = m_Device->containerCount( );
+
+        // In the case of the public is created before te private key, there is no container index available
+        do {
+        
+            s = a_stFileName;
+        
+            incrementObjectIndex( );
+
+            // Add the index of the data object
+            Util::toStringHex( uiStartIndex + m_uiObjectIndex, s );
+
+            if( isObjectNameValid( s, filesPKCS11 ) ) {
+        
+                bGoodNameFound = true;
+
+                a_stFileName = s;
+            }
+
+        } while( !bGoodNameFound );
+    }
+}
+
+
+/*
+*/
+void Token::computeObjectNamePrivateKey( std::string& a_stFileName, /*const*/ StorageObject* a_pObject ) {
+
+        // Add the public or private prefix
+    a_stFileName = ( a_pObject->isPrivate( ) ? g_stPrefixPrivateObject : g_stPrefixPublicObject );
+
+    // Add the key suffix
+    a_stFileName.append( g_stPrefixKeyPrivate );
+
+    unsigned char ucContainerIndex = ( (RSAPrivateKeyObject*) a_pObject )->m_ucContainerIndex;
+
+    // Add the index of MiniDriver key container associated to this PKCS11 key object
+    Util::toStringHex( ucContainerIndex, a_stFileName );
+}
+
+
+/*
+*/
+void Token::computeObjectNameCertificate( std::string& a_stFileName, /*const*/ StorageObject* a_pObject ) {
+
+    // Add the public or private prefix
+    a_stFileName = ( a_pObject->isPrivate( ) ? g_stPrefixPrivateObject : g_stPrefixPublicObject );
+
+    a_stFileName.append( a_pObject->m_stFileName );
+}
+
+
+/* WriteObject
+*/
+void Token::writeObject( StorageObject* a_pObject ) {
+
+    Log::begin( "Token::writeObject" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device || !m_pSlot ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Compute this attribute for backward compatibility with odl version of P11 library
+    a_pObject->_uniqueId = Util::MakeUniqueId( );
+
+    // Build the content of the file
+    std::vector< unsigned char > to;
+    a_pObject->serialize( &to );
+
+    Marshaller::u1Array o( to );
+
+    try {
+
+        if( m_pSlot->isAuthenticated( ) ) {
+
+            if( m_bCreateDirectoryP11 ) {
+
+                m_Device->createDirectory( std::string( "root" ), g_stPathPKCS11 );
+            }
+
+            try {
+
+                // If the user is authenticated then create the file on card
+                m_Device->createFile( g_stPathPKCS11, a_pObject->m_stFileName, a_pObject->isPrivate( ) );
+
+            } catch( MiniDriverException& e ) {
+
+                // The file may be already created. In this case the file must only be written.
+                // It could be the case for the public key which is created 
+                // but not deleted by the application (for example Firefox)
+                if( SCARD_E_WRITE_TOO_MANY != e.getError( ) ) {
+
+                    // Otherwise the error must be thrown
+                    throw;
+                }
+            }
+
+            if ( ( CKO_DATA == a_pObject->getClass( ) ) && a_pObject->isPrivate( ) ) {
+
+                m_Device->cacheDisable( a_pObject->m_stFileName );
+            }
+
+            m_Device->writeFile( g_stPathPKCS11, a_pObject->m_stFileName, &o );
+
+            Log::log( "Token::writeObject - Create & write <%s>", a_pObject->m_stFileName.c_str( ) );
+
+        } else {
+
+            Log::log( "Token::writeObject - *** CREATE LATER *** <%s>", a_pObject->m_stFileName.c_str( ) );
+
+            // If the user is not authenticated then store the object to create it later
+            m_ObjectsToCreate.push_back( a_pObject );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::writeObject", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::writeObject" );
+    Log::end( "Token::writeObject" );
+}
+
+
+/* Create an object required by the PKCS11 API (C_CreateObject
+*/
+void Token::addObject( StorageObject* a_pObject, CK_OBJECT_HANDLE_PTR a_pHandle, const bool& a_bRegisterObject ) {
+
+    Log::begin( "Token::addObject" );
+    Timer t;
+    t.start( );
+
+    *a_pHandle = CK_UNAVAILABLE_INFORMATION;
+
+    try {
+
+        // Build the name of the file
+        computeObjectFileName( a_pObject, a_pObject->m_stFileName );
+
+        // Write the file into the smart card
+        writeObject( a_pObject );
+
+        // Add the object into the list of managed objects
+        if( a_bRegisterObject ) {
+
+            *a_pHandle = registerStorageObject( a_pObject );
+        }
+
+    } catch( MiniDriverException &x ) {
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::addObject" );
+    Log::end( "Token::addObject" );
+}
+
+
+/* AddPrivateKeyObject
+*/
+void Token::addObjectPrivateKey( RSAPrivateKeyObject* a_pObject, CK_OBJECT_HANDLE_PTR a_phObject ) {
+
+    Log::begin( "Token::addObjectPrivateKey" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // No private key for public object
+    if( !a_pObject->isPrivate( ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    // Public key modulus is mandatory
+    if( !a_pObject->m_pModulus ) {
+
+        throw PKCS11Exception( CKR_TEMPLATE_INCOMPLETE );
+    }
+
+    // Check the modulus length
+    unsigned int uiModulusLength = a_pObject->m_pModulus->GetLength( );
+
+    if( ( ( uiModulusLength * 8 ) < MiniDriver::s_iMinLengthKeyRSA ) || ( (uiModulusLength * 8 ) > MiniDriver::s_iMaxLengthKeyRSA ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    // Get the middle size
+    unsigned int uiKeyHalfSize = uiModulusLength / 2;
+
+    // Check the Prime P (PKCS11 prime 1 attribute) size
+    unsigned int uiPrimePLength = a_pObject->m_pPrime1->GetLength( );
+
+    if( uiPrimePLength > uiKeyHalfSize ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    if( uiPrimePLength < uiKeyHalfSize ) {
+
+        // Pad with zeros in the front since big endian
+        Marshaller::u1Array* val = new Marshaller::u1Array( uiKeyHalfSize );
+
+        memset( val->GetBuffer( ), 0, uiKeyHalfSize );
+
+        size_t i = uiKeyHalfSize - uiPrimePLength;
+
+        memcpy( val->GetBuffer( ) + i, a_pObject->m_pPrime1->GetBuffer( ), uiPrimePLength );
+
+        a_pObject->m_pPrime1.reset( val );
+
+        uiPrimePLength = uiKeyHalfSize;
+    }
+
+    // Check the Prime Q (PKCS11 prime 2 attribute) size
+    unsigned int uiPrimeQLength = a_pObject->m_pPrime2->GetLength( );
+
+    if( uiPrimeQLength > uiKeyHalfSize ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    if( uiPrimeQLength < uiKeyHalfSize ) {
+
+        // Pad with zeros in the front since big endian
+        Marshaller::u1Array* val = new Marshaller::u1Array( uiKeyHalfSize );
+
+        memset( val->GetBuffer( ), 0, uiKeyHalfSize );
+
+        size_t i = uiKeyHalfSize - uiPrimeQLength;
+
+        memcpy( val->GetBuffer( ) + i, a_pObject->m_pPrime2->GetBuffer( ), uiPrimeQLength );
+
+        a_pObject->m_pPrime2.reset( val );
+
+        uiPrimeQLength = uiKeyHalfSize;
+    }
+
+    // Check the Inverse Q (PKCS11 coefficient attribute) size
+    unsigned int uiInverseQLength = a_pObject->m_pCoefficient->GetLength( );
+
+    if( uiInverseQLength > uiKeyHalfSize ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    if( uiInverseQLength < uiKeyHalfSize ) {
+
+        // Pad with zeros in the front since big endian
+        Marshaller::u1Array* val = new Marshaller::u1Array( uiKeyHalfSize );
+
+        memset( val->GetBuffer( ), 0, uiKeyHalfSize );
+
+        size_t i = uiKeyHalfSize - uiInverseQLength;
+
+        memcpy( val->GetBuffer( ) + i, a_pObject->m_pCoefficient->GetBuffer( ), uiInverseQLength );
+
+        a_pObject->m_pCoefficient.reset( val );
+
+        uiInverseQLength = uiKeyHalfSize;
+    }
+
+    // Check the DP Length (PKCS11 CKA_EXPONENT_1 attribute) size
+    unsigned int uiDPLength = a_pObject->m_pExponent1->GetLength( );
+
+    if( uiDPLength > uiKeyHalfSize ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    if( uiDPLength < uiKeyHalfSize ) {
+
+        // Pad with zeros in the front since big endian
+        Marshaller::u1Array* val = new Marshaller::u1Array( uiKeyHalfSize );
+
+        memset( val->GetBuffer( ), 0, uiKeyHalfSize );
+
+        size_t i = uiKeyHalfSize - uiDPLength;
+
+        memcpy( val->GetBuffer( ) + i, a_pObject->m_pExponent1->GetBuffer( ), uiDPLength );
+
+        a_pObject->m_pExponent1.reset( val );
+
+        uiDPLength = uiKeyHalfSize;
+    }
+
+    // Check the DQ Length (PKCS11 CKA_EXPONENT_2 attribute) size
+    unsigned int uiDQLength = a_pObject->m_pExponent2->GetLength( );
+
+    if( uiDQLength > uiKeyHalfSize ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    if( uiDQLength < uiKeyHalfSize ) {
+
+        // Pad with zeros in the front since big endian
+        Marshaller::u1Array* val = new Marshaller::u1Array( uiKeyHalfSize );
+
+        memset( val->GetBuffer( ), 0, uiKeyHalfSize );
+
+        size_t i = uiKeyHalfSize - uiDQLength;
+
+        memcpy( val->GetBuffer( ) + i, a_pObject->m_pExponent2->GetBuffer( ), uiDQLength );
+
+        a_pObject->m_pExponent2.reset( val );
+
+        uiDQLength = uiKeyHalfSize;
+    }
+
+    // Check the Private Exponent Length (PKCS11 CKA_PRIVATE_EXPONENT attribute) size
+    unsigned int uiPrivateExponentLength = a_pObject->m_pPrivateExponent->GetLength( );
+
+    if( uiPrivateExponentLength > uiModulusLength ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    if( uiPrivateExponentLength < uiModulusLength ) {
+
+        // Pad with zeros in the front since big endian
+        Marshaller::u1Array* val = new Marshaller::u1Array( uiModulusLength );
+
+        memset( val->GetBuffer( ), 0, uiPrivateExponentLength );
+
+        size_t i = uiModulusLength - uiPrivateExponentLength;
+
+        memcpy( val->GetBuffer( ) + i, a_pObject->m_pPrivateExponent->GetBuffer( ), uiPrivateExponentLength );
+
+        a_pObject->m_pPrivateExponent.reset( val );
+
+        uiPrivateExponentLength = uiModulusLength;
+    }
+
+    // Check the public exponent size
+    unsigned int uiPublicExponentLength = a_pObject->m_pPublicExponent->GetLength( );
+
+    if( ( uiPublicExponentLength < 1 ) || ( uiPublicExponentLength > 4 ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    // Check the public key exponent size    
+    Marshaller::u1Array* pPublicExponent = a_pObject->m_pPublicExponent.get( );
+
+    if( uiPublicExponentLength < 4 ) {
+
+        // Pad with zeros in the front since big endian
+        pPublicExponent = new Marshaller::u1Array( 4 );
+
+        memset( pPublicExponent->GetBuffer( ), 0, 4 );
+
+        size_t i = 4 - uiPublicExponentLength;
+
+        memcpy( pPublicExponent->GetBuffer( ) + i, a_pObject->m_pPublicExponent->GetBuffer( ), uiPublicExponentLength );
+
+        uiPublicExponentLength = 4;
+    }
+
+    //if( uiPublicExponentLength < 4 ) {
+
+    //    // Pad with zeros in the front since big endian
+    //    Marshaller::u1Array* exp = new Marshaller::u1Array( 4 );
+
+    //    memset( exp->GetBuffer( ), 0, 4 );
+
+    //    size_t i = 4 - uiPublicExponentLength;
+
+    //    memcpy( exp->GetBuffer( ) + i, a_pObject->m_pPublicExponent->GetBuffer( ), uiPublicExponentLength );
+
+    //    a_pObject->m_pPublicExponent.reset( exp );
+
+    //    uiPublicExponentLength = 4;
+    //}
+
+    // compute the total length;
+    unsigned int uiKeyLength = uiPrimePLength + uiPrimeQLength + uiInverseQLength + uiDPLength + uiDQLength + uiPrivateExponentLength + uiModulusLength + 4;
+
+    // Prepare the keyValue
+    Marshaller::u1Array keyValue( uiKeyLength );
+
+    unsigned char* p = keyValue.GetBuffer( );
+
+    memset( p, 0, uiKeyLength );
+
+    // Add the Prime P
+    memcpy( p, a_pObject->m_pPrime1->GetBuffer( ), uiPrimePLength );
+
+    int offset = uiPrimePLength;
+
+    // Add the the Prime Q
+    memcpy( p + offset, a_pObject->m_pPrime2->GetBuffer( ), uiPrimeQLength );
+
+    offset += uiPrimeQLength;
+
+    // Add the inverse Q
+    memcpy( p + offset, a_pObject->m_pCoefficient->GetBuffer( ), uiInverseQLength );
+
+    offset += uiInverseQLength;
+
+    // Add the DP
+    memcpy( p + offset, a_pObject->m_pExponent1->GetBuffer( ), uiDPLength );
+
+    offset += uiDPLength;
+
+    // Add the DQ
+    memcpy( p + offset, a_pObject->m_pExponent2->GetBuffer( ), uiDQLength );
+
+    offset += uiDQLength;
+
+    // Addt he private exponent D
+    memcpy( p + offset, a_pObject->m_pPrivateExponent->GetBuffer( ), uiPrivateExponentLength );
+
+    offset += uiPrivateExponentLength;
+
+    // Add the modulus
+    memcpy( p + offset, a_pObject->m_pModulus->GetBuffer( ), uiModulusLength );
+
+    offset += uiModulusLength;
+
+    // Add the public exponent
+    //memcpy( p + offset, a_pObject->m_pPublicExponent->GetBuffer( ), uiPublicExponentLength );
+    memcpy( p + offset, pPublicExponent->GetBuffer( ), uiPublicExponentLength );
+
+    // Specify what is able to do the key (sign only or sign & decrypt)
+    a_pObject->m_ucKeySpec = (unsigned char)( a_pObject->_decrypt ? MiniDriverContainer::KEYSPEC_EXCHANGE : MiniDriverContainer::KEYSPEC_SIGNATURE );
+
+    // Create the on card key container
+    // This method checks if a certificate with the same public key exists.
+    // In this case this new key must be imported into the key container already associated with this certificate and the key spec is also updated
+    a_pObject->m_ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+
+    try {
+
+        m_Device->containerCreate( a_pObject->m_ucContainerIndex, true, a_pObject->m_ucKeySpec, a_pObject->m_pModulus.get( ), ( uiModulusLength * 8 ), &keyValue );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::addObjectPrivateKey", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    if( a_pObject->m_ucContainerIndex == MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID ) {
+
+        // No free container available
+        Log::error( "Token::AddPrivateKeyObject", "no index available - Return CKR_DEVICE_MEMORY" );
+
+        throw PKCS11Exception( CKR_DEVICE_MEMORY );
+    }
+
+    setDefaultAttributesKeyPrivate( a_pObject );
+
+    a_pObject->_local = CK_FALSE;
+
+    // Create the associated PKCS#11 key object
+    addObject( a_pObject, a_phObject ); 
+
+    t.stop( "Token::addObjectPrivateKey" );
+    Log::end( "Token::addObjectPrivateKey" );
+}
+
+
+/*
+*/
+void Token::addObjectCertificate( X509PubKeyCertObject* a_pObject, CK_OBJECT_HANDLE_PTR a_phObject ) {
+
+    Log::begin( "Token::addObjectCertificate" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Private certificate object is not allowed
+    if( !a_pObject || a_pObject->isPrivate( ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    // Set the certificate with sign & decrypt purposes by default
+    a_pObject->m_ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+
+    // Set the certificate container as invalid
+    a_pObject->m_ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+
+    // Actually the certificates attributes have been provided by the creation template.
+    // But some of then can be not set.
+    // Get all empty attributes from the certificate
+    // Set the same CKA_LABEL, CKA_ID and CKA_SUBJECT for this certificate 
+    // than an existing private key using the same public key modulus attribute
+    setDefaultAttributesCertificate( a_pObject );
+
+    Log::log( "Token::addObjectCertificate - Smart card logon <%d>", a_pObject->m_bIsSmartCardLogon );
+    Log::log( "Token::addObjectCertificate - root <%d>", a_pObject->m_bIsRoot );
+    Log::log( "Token::addObjectCertificate - index <%d>", a_pObject->m_ucContainerIndex );
+
+    //unsigned char ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+    //unsigned char ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+    std::string stFileName = "";
+    m_Device->containerGetMatching( a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec, stFileName, a_pObject->m_pModulus.get( ) );
+    Log::log( "Token::addObjectCertificate - m_ucContainerIndex <%d>", a_pObject->m_ucContainerIndex );
+    Log::log( "Token::addObjectCertificate - m_ucKeySpec <%d>", a_pObject->m_ucKeySpec );
+    Log::log( "Token::addObjectCertificate - stFileName <%s>", stFileName.c_str( ) );
+
+    if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID != a_pObject->m_ucContainerIndex ) {
+
+        Log::log( "Token::addObjectCertificate - Create a certificate associated to a key pair container" );
+
+        // Create the certificate into the smart card
+        try {
+
+            // If a container already exists using the same public key modulus then the container index will be updated with the index of this container.
+            // The keyspec will also be updated
+            // The file name will anyway built automaticaly
+            m_Device->createCertificate( a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec, a_pObject->m_stFileName, a_pObject->m_pValue.get( ), a_pObject->m_pModulus.get( ), a_pObject->m_bIsSmartCardLogon );
+
+            a_pObject->m_stCertificateName = a_pObject->m_stFileName;//.substr( 3, 5 );
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Token::addObjectCertificate", "MiniDriverException" );
+
+            throw PKCS11Exception( checkException( x ) );
+        }
+
+    } else {
+
+        Log::log( "Token::addObjectCertificate - Create a ROOT certificate" );
+
+        // Create the ROOT certificate into the smart card
+        try {
+
+            m_Device->createCertificateRoot( a_pObject->m_stFileName, a_pObject->m_pValue.get( ) );
+
+            a_pObject->m_stCertificateName = a_pObject->m_stFileName;
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Token::addObjectCertificate", "MiniDriverException" );
+
+            throw PKCS11Exception( checkException( x ) );
+        }
+    }
+
+    // Write the PKCS#11 certificate object into the smart card
+    addObject( a_pObject, a_phObject );
+
+    t.stop( "Token::addObjectCertificate" );
+    Log::end( "Token::addObjectCertificate" );
+}
+
+
+/*
+*/
+void Token::addObjectPublicKey( Pkcs11ObjectKeyPublicRSA* a_pObject, CK_OBJECT_HANDLE_PTR a_phObject ) {
+
+    Log::begin( "Token::addObjectPublicKey" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Private public key object is not allowed
+    if( a_pObject->isPrivate( ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_VALUE_INVALID );
+    }
+
+    // Create the certificate into the smart card
+    try {
+
+        // If a container already exists using the same public key modulus then the container index will be updated with the index of this container.
+        // The keyspec will also be updated
+        // The file name will anyway be build automaticaly
+        m_Device->containerGetMatching( a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec, a_pObject->m_stFileName, a_pObject->m_pModulus.get( ) );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::addObjectPublicKey", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    setDefaultAttributesKeyPublic( a_pObject );
+
+    a_pObject->_local = CK_FALSE;
+
+    // Write the PKCS#11 certificate object into the smart card
+    addObject( a_pObject, a_phObject );
+
+    t.stop( "Token::addObjectPublicKey" );
+    Log::end( "Token::addObjectPublicKey" );
+}
+
+
+/*
+*/
+void Token::deleteObject( const CK_OBJECT_HANDLE& a_hObject ) {
+
+    Log::begin( "Token::deleteObject" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Are we allowed to delete objects ? We must be logged in
+    if( !m_Device->isAuthenticated( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    StorageObject* o = getObject( a_hObject );
+
+    printObject( o );
+
+    // Delete the PKCS#11 object & MiniDriver file/container from card
+    deleteObjectFromCard( o );
+
+    // Delete the PKCS#11 object from inner list of managed objects
+    unregisterStorageObject( a_hObject );
+
+    t.stop( "Token::deleteObject" );
+    Log::end( "Token::deleteObject" );
+}
+
+
+/*
+*/
+void Token::deleteObjectFromCard( StorageObject* a_pObject ) {
+
+    Log::begin( "Token::deleteObjectFromCard" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // Delete the file from the MiniDriver file system
+        switch( a_pObject->getClass( ) ) {
+
+        case CKO_CERTIFICATE:
+            {
+                CertificateObject* t = static_cast< CertificateObject* >( a_pObject );
+
+                // Delete the certificate file
+                //try {
+
+                try {
+                    
+                    // Check if the container is still valid. Throw an exception if not.
+                    MiniDriverContainer c = m_Device->containerGet( t->m_ucContainerIndex );
+                
+                    // Delete the associated certificate
+                    m_Device->certificateDelete( t->m_ucContainerIndex );
+
+                } catch( MiniDriverException ) {
+                
+                    // The container is not associated to this certitifcate object
+                    // Delete the MiniDriver file from the PKCS11 object file name
+                    m_Device->deleteFile( std::string( szBASE_CSP_DIR ), t->m_stCertificateName );
+
+                }
+
+                //if( 0xFF == t->m_ucContainerIndex ) {
+
+                //    // The container is not associated to this certitifcate object
+                //    // Delete the MiniDriver file from the PKCS11 object file name
+                //    m_Device->deleteFile( std::string( szBASE_CSP_DIR ), t->m_stCertificateName );
+
+                //} else {
+
+                //    m_Device->certificateDelete( t->m_ucContainerIndex );
+                //}
+
+                ////} catch( MiniDriverException& ex ) {
+
+                ////    // The container is not associated to this certitifcate object
+                ////    // Delete the MiniDriver file from the PKCS11 object file name
+                ////    m_Device->deleteFile( std::string( szBASE_CSP_DIR ), t->m_stCertificateName );
+
+                ////    throw ex;
+                ////}
+            }
+            break;
+
+        case CKO_PRIVATE_KEY:
+            {
+                RSAPrivateKeyObject * v = static_cast< RSAPrivateKeyObject* >( a_pObject );
+
+                // Delete the key container
+                m_Device->containerDelete( v->m_ucContainerIndex );
+            }
+            break;
+
+        default:
+            break;
+        }
+
+        // Delete the PKCS#11 file from card
+        if( !a_pObject->m_stFileName.empty( ) && !a_pObject->m_bOffCardObject ) {
+
+            m_Device->deleteFile( g_stPathPKCS11, a_pObject->m_stFileName );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::deleteObjectFromCard", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::deleteObjectFromCard" );
+    Log::end( "Token::deleteObjectFromCard" );
+}
+
+
+/*
+*/
+void Token::getAttributeValue( const CK_OBJECT_HANDLE& a_hObject, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    //Log::begin( "Token::getAttributeValue" );
+    //Timer t;
+    //t.start( );
+
+    if( !m_pSlot) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    StorageObject* o = getObject( a_hObject );
+
+
+    // Check if we are allowed to retreive the queried attributes
+    if( o->isPrivate( ) && !m_pSlot->isAuthenticated( ) ) {
+
+        for( CK_ULONG i = 0 ; i < a_ulCount ; ++i ) {
+
+            a_pTemplate[ i ].ulValueLen = CK_UNAVAILABLE_INFORMATION;
+        }
+
+        throw PKCS11Exception(CKR_USER_NOT_LOGGED_IN);
+    }
+
+
+    // Get the attributes from the object
+    for( CK_ULONG i = 0 ; i < a_ulCount ; ++i ) {
+
+        o->getAttribute( &a_pTemplate[ i ] );
+    }
+
+    //t.stop( "Token::getAttributeValue" );
+    //Log::end( "Token::getAttributeValue" );
+}
+
+
+/*
+*/
+void Token::setAttributeValue( const CK_OBJECT_HANDLE& a_hObject, CK_ATTRIBUTE_PTR a_pTemplate, const CK_ULONG& a_ulCount ) {
+
+    // ??? TODO : verify the new attribute is different from the existing attribute. If both are the same do nothing
+
+    Log::begin( "Token::setAttributeValue" );
+    Timer t;
+    t.start( );
+
+    if( !m_pSlot ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    StorageObject* o = getObject( a_hObject );
+
+    // Check if we are allowed to write
+    if( /*o->isPrivate( ) && 	*/ !m_pSlot->isAuthenticated( ) ) {
+
+        throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+    }
+
+    for( CK_ULONG i = 0 ; i < a_ulCount ; ++i ) {
+
+        o->setAttribute( a_pTemplate[ i ], false );
+    }
+
+    // Check if the object is not read-only
+    if( ! o->isModifiable( ) ) {
+
+        throw PKCS11Exception( CKR_ATTRIBUTE_READ_ONLY );
+    }
+
+    // Compute this attribute for backward compatibilit with old version of the P11 library
+    o->_uniqueId = Util::MakeUniqueId();
+
+    // Get the object buffer
+    std::vector< unsigned char > v;
+    o->serialize( &v );
+    size_t l =  v.size( );
+    Marshaller::u1Array d( l );
+    for( unsigned int i = 0 ; i <l ; ++i ) {
+
+        d.SetU1At( i, v.at( i ) );
+    }
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        if( o->m_bOffCardObject ) {
+
+            m_Device->createFile( g_stPathPKCS11, o->m_stFileName, ( o->m_Private == CK_TRUE ) );
+
+            o->m_bOffCardObject = false;
+        }
+
+        m_Device->writeFile( g_stPathPKCS11, o->m_stFileName, &d );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::setAttributeValue", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    printObject( o );
+
+    t.stop( "Token::setAttributeValue" );
+    Log::end( "Token::setAttributeValue" );
+}
+
+
+/*
+*/
+void Token::generateKeyPair( Pkcs11ObjectKeyPublicRSA* a_pObjectPublicKeyRSA, RSAPrivateKeyObject* a_pObjectPrivateKeyRSA, CK_OBJECT_HANDLE_PTR a_pHandlePublicKeyRSA, CK_OBJECT_HANDLE_PTR a_pHandlePrivateKeyRSA ) {
+
+    Log::begin( "Token::generateKeyPair" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    if( ( a_pObjectPublicKeyRSA->m_ulModulusBits < MiniDriver::s_iMinLengthKeyRSA ) || ( a_pObjectPublicKeyRSA->m_ulModulusBits > MiniDriver::s_iMaxLengthKeyRSA ) ) {
+
+        throw PKCS11Exception(CKR_ATTRIBUTE_VALUE_INVALID);
+    }
+
+    // Create a smart card container to generate and store the new key pair
+    unsigned char ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+
+    unsigned char ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+
+    try {
+
+        m_Device->containerCreate( ucContainerIndex, false, ucKeySpec, a_pObjectPublicKeyRSA->m_pModulus.get( ), a_pObjectPublicKeyRSA->m_ulModulusBits, 0 );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::generateKeyPair", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    if( ucContainerIndex == MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID ) {
+
+        throw PKCS11Exception( CKR_DEVICE_MEMORY );
+    }
+
+    a_pObjectPrivateKeyRSA->m_ucContainerIndex = ucContainerIndex;
+
+    a_pObjectPrivateKeyRSA->m_ucKeySpec = ucKeySpec;
+
+    a_pObjectPublicKeyRSA->m_ucContainerIndex = ucContainerIndex;
+
+    a_pObjectPublicKeyRSA->m_ucKeySpec = ucKeySpec;
+
+    try {
+
+        // Populate these objects with the new key material
+        MiniDriverContainer c = m_Device->containerGet( ucContainerIndex );
+
+        // Fill the PKCS#11 object with the information about the new key pair
+        a_pObjectPublicKeyRSA->_local = CK_TRUE;
+
+        ///// ???
+        //a_pObjectPublicKeyRSA->m_pPublicExponent = c.getExchangePublicKeyExponent( );
+
+        a_pObjectPublicKeyRSA->m_pModulus = c.getExchangePublicKeyModulus( );
+
+        // Copy these modulus and exponent in the private key component also
+        a_pObjectPrivateKeyRSA->_local = CK_TRUE;
+
+        //// ???
+        //a_pObjectPrivateKeyRSA->m_pPublicExponent = c.getExchangePublicKeyExponent( );
+
+        a_pObjectPrivateKeyRSA->m_pModulus = c.getExchangePublicKeyModulus( );
+
+        setDefaultAttributesKeyPrivate( a_pObjectPrivateKeyRSA );
+
+        setDefaultAttributesKeyPublic( a_pObjectPublicKeyRSA );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::generateKeyPair", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    // The public key may be a session object, in that case, don't save it.
+    if( a_pObjectPublicKeyRSA->isToken( ) ) {
+
+        addObject( a_pObjectPublicKeyRSA, a_pHandlePublicKeyRSA );
+    }
+
+    try {
+
+        addObject( a_pObjectPrivateKeyRSA, a_pHandlePrivateKeyRSA );
+
+    } catch( MiniDriverException& x ) {
+
+        if( a_pObjectPublicKeyRSA->isToken( ) ) {
+
+            deleteObject( *a_pHandlePublicKeyRSA );
+
+            try {
+
+                m_Device->containerDelete( ucContainerIndex );
+
+            } catch( MiniDriverException& ) {
+
+                Log::error( "Token::generateKeyPair", "MiniDriverException" );
+            }
+
+            throw PKCS11Exception( checkException( x ) );
+        }
+    }
+
+    t.stop( "Token::generateKeyPair" );
+    Log::end( "Token::generateKeyPair" );
+}
+
+
+/*
+*/
+void Token::encrypt( const StorageObject* pubObj, Marshaller::u1Array* dataToEncrypt, const CK_ULONG& mechanism, CK_BYTE_PTR pEncryptedData ) {
+
+    Pkcs11ObjectKeyPublicRSA* object = ( Pkcs11ObjectKeyPublicRSA* )pubObj;
+
+    if(mechanism == CKM_RSA_PKCS){
+        // first do the length checks
+        if(dataToEncrypt->GetLength() > (object->m_pModulus->GetLength() - 11)){
+            throw PKCS11Exception(CKR_DATA_LEN_RANGE);
+        }
+
+        rsaPublicKey_t key;
+
+        key.modulus = object->m_pModulus->GetBuffer() ;
+        key.modulusLength = object->m_pModulus->GetLength() * 8 ;
+        key.publicExponent = object->m_pPublicExponent->GetBuffer();
+        key.publicExponentLength =  object->m_pPublicExponent->GetLength() * 8;
+
+        unsigned int outLength = object->m_pModulus->GetLength();
+
+        //DWORD rv ;
+        DWORD size ;
+        DWORD pubSize ;
+        R_RSA_PUBLIC_KEY	rsaKeyPublic ;
+
+        rsaKeyPublic.bits = key.modulusLength ;
+
+        size = (key.modulusLength + 7) / 8 ;
+        memcpy(rsaKeyPublic.modulus, key.modulus, size) ;
+
+        pubSize = (key.publicExponentLength + 7) / 8 ;
+        memset(rsaKeyPublic.exponent, 0, size) ;
+        memcpy(&rsaKeyPublic.exponent[size - pubSize], key.publicExponent, pubSize) ;
+
+        R_RANDOM_STRUCT & randomStruct = Util::RandomStruct();
+
+        RSAPublicEncrypt(
+            pEncryptedData,
+            &outLength,
+            (unsigned char*)dataToEncrypt->GetBuffer(),
+            dataToEncrypt->GetLength(),
+            &rsaKeyPublic,
+            &randomStruct);
+
+    }else{
+
+        unsigned int modulusLen = object->m_pModulus->GetLength();
+
+        if(dataToEncrypt->GetLength() > (modulusLen)){
+            throw PKCS11Exception(CKR_DATA_LEN_RANGE);
+        }
+
+        // pre-pad with zeros
+        Marshaller::u1Array messageToEncrypt(modulusLen);
+        memset(messageToEncrypt.GetBuffer(),0,modulusLen);
+
+        s4 offsetMsgToEncrypt = modulusLen - dataToEncrypt->GetLength();
+
+        unsigned int l = dataToEncrypt->GetLength( );
+        for( unsigned int i = 0, j = offsetMsgToEncrypt ; i < l ; ++i, ++j ) {
+
+            messageToEncrypt.GetBuffer()[j] = dataToEncrypt->GetBuffer()[i];
+        }
+
+        // just block transform now
+        s4 size ;
+        s4 pubSize ;
+        R_RSA_PUBLIC_KEY	rsaKeyPublic ;
+
+        //Build the RSA public key context
+        rsaKeyPublic.bits = object->m_pModulus->GetLength() * 8;
+
+        size = (rsaKeyPublic.bits  + 7) / 8 ;
+        memcpy(rsaKeyPublic.modulus,object->m_pModulus->GetBuffer(),size) ;
+
+        pubSize = ((object->m_pPublicExponent->GetLength() * 8) + 7) / 8 ;
+        memset(rsaKeyPublic.exponent, 0, size) ;
+        memcpy(&rsaKeyPublic.exponent[size - pubSize], object->m_pPublicExponent->GetBuffer(), pubSize) ;
+
+        unsigned int outputLen = size;
+
+        RSAPublicBlock(pEncryptedData,&outputLen,messageToEncrypt.GetBuffer(),size,&rsaKeyPublic);
+    }
+}
+
+
+/*
+*/
+void Token::decrypt( const StorageObject* privObj, Marshaller::u1Array* dataToDecrypt, const CK_ULONG& mechanism, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen ) {
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    RSAPrivateKeyObject* rsaKey = (RSAPrivateKeyObject*)privObj;
+
+    boost::shared_ptr< Marshaller::u1Array > data;
+
+    try {
+
+        data = m_Device->privateKeyDecrypt( rsaKey->m_ucContainerIndex, rsaKey->m_ucKeySpec, dataToDecrypt );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::decrypt", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    if( !data ) {
+
+        throw PKCS11Exception( CKR_ENCRYPTED_DATA_INVALID );
+    }
+
+    unsigned int l = data->GetLength( );
+
+    unsigned char* p = (unsigned char*)data->GetBuffer( );
+
+    if( CKM_RSA_PKCS == mechanism ) {
+
+        unsigned char* decryptedMessage = p;
+
+        if( decryptedMessage[ 0 ] || ( g_ucPKCS_EMEV15_PADDING_TAG != decryptedMessage[ 1 ] ) ) {
+
+            // invalid message padding
+            throw PKCS11Exception( CKR_ENCRYPTED_DATA_INVALID );
+
+        } else {
+
+            // seach message padding separator
+            unsigned int mPos = 2 + 8;
+
+            while( decryptedMessage[ mPos ] && (mPos < l ) ) {
+
+                ++mPos;
+            }
+
+            // point on message itself.
+            ++mPos;
+
+            l = l - mPos;
+
+            data.reset( new Marshaller::u1Array( l ) );
+
+            p = data->GetBuffer( );
+
+            memcpy( p, (unsigned char*)&decryptedMessage[ mPos ],  l );
+        }
+    }
+    // else... CKM_RSA_X_509: Ignore padding
+
+    if( data ) {
+
+        if ( *pulDataLen >= l ) {
+
+            memset( pData, 0, *pulDataLen );
+
+            memcpy( pData, p, l );
+
+            *pulDataLen = l;
+        } else {
+
+            *pulDataLen = l;
+
+            throw PKCS11Exception( CKR_BUFFER_TOO_SMALL );
+        }
+    }
+}
+
+
+/*
+*/
+void Token::verify( const StorageObject* pubObj, Marshaller::u1Array* dataToVerify, const CK_ULONG& mechanism, Marshaller::u1Array* signature) {
+
+    Pkcs11ObjectKeyPublicRSA* o = (Pkcs11ObjectKeyPublicRSA*)pubObj;
+
+    if(((mechanism == CKM_RSA_PKCS) && (dataToVerify->GetLength() > (o->m_pModulus->GetLength() - 11))) ||
+        ((mechanism == CKM_RSA_X_509) && (dataToVerify->GetLength() > o->m_pModulus->GetLength())))
+    {
+        throw PKCS11Exception(CKR_DATA_LEN_RANGE);
+    }
+
+    if( signature->GetLength( ) != o->m_pModulus->GetLength( ) ){
+
+        throw PKCS11Exception(CKR_SIGNATURE_LEN_RANGE);
+    }
+
+    s4 size;
+    s4 pubSize;
+    R_RSA_PUBLIC_KEY rsaKeyPublic ;
+
+    //Build the RSA public key context
+    rsaKeyPublic.bits = o->m_pModulus->GetLength() * 8;
+
+    size = (rsaKeyPublic.bits  + 7) / 8 ;
+    memcpy(rsaKeyPublic.modulus, o->m_pModulus->GetBuffer(),size) ;
+
+    pubSize = ((o->m_pPublicExponent->GetLength() * 8) + 7) / 8 ;
+    memset(rsaKeyPublic.exponent, 0, size) ;
+    memcpy(&rsaKeyPublic.exponent[size - pubSize], o->m_pPublicExponent->GetBuffer(), pubSize) ;
+
+    unsigned int messageToVerifyLen = size;
+    Marshaller::u1Array messageToVerify( messageToVerifyLen );
+
+    RSAPublicBlock(messageToVerify.GetBuffer(),&messageToVerifyLen,signature->GetBuffer(),size,&rsaKeyPublic);
+
+    switch(mechanism){
+
+    case CKM_RSA_PKCS:
+        verifyRSAPKCS1v15( &messageToVerify,dataToVerify,size);
+        break;
+
+    case CKM_RSA_X_509:
+        verifyRSAX509( &messageToVerify,dataToVerify,size);
+        break;
+
+
+    case CKM_SHA1_RSA_PKCS:
+        verifyHash( &messageToVerify,dataToVerify,size,CKM_SHA_1);
+        break;
+
+    case CKM_SHA256_RSA_PKCS:
+        verifyHash( &messageToVerify,dataToVerify,size,CKM_SHA256);
+        break;
+
+    case CKM_MD5_RSA_PKCS:
+        verifyHash( &messageToVerify,dataToVerify,size,CKM_MD5);
+        break;
+
+    default:
+        throw PKCS11Exception( CKR_GENERAL_ERROR );
+    }
+}
+
+
+/*
+*/
+void Token::verifyHash( Marshaller::u1Array* messageToVerify, Marshaller::u1Array* dataToVerify, const unsigned int& modulusLen, const CK_ULONG& hashAlgo ) {
+
+    const unsigned char* msg  = messageToVerify->GetBuffer( );
+
+    // Check the decoded value against the expected data.
+    if( ( msg[ 0 ] != 0x00 ) || ( msg[ 1 ] != 0x01 ) ) {
+
+        throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+    }
+    unsigned char DER_SHA1_Encoding[]   = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
+    unsigned char DER_SHA256_Encoding[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
+    unsigned char DER_MD5_Encoding[]    = {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00,0x04,0x10};
+
+    s4  DER_Encoding_Len = 0;
+
+    switch(hashAlgo){
+    case CKM_SHA_1:
+        DER_Encoding_Len = sizeof(DER_SHA1_Encoding);
+        break;
+
+    case CKM_SHA256:
+        DER_Encoding_Len = sizeof(DER_SHA256_Encoding);
+        break;
+
+    case CKM_MD5:
+        DER_Encoding_Len = sizeof(DER_MD5_Encoding);
+        break;
+
+    }
+
+    const unsigned char* hash = dataToVerify->GetBuffer();
+    unsigned int hashLen = dataToVerify->GetLength();
+
+    s4 posn = modulusLen - DER_Encoding_Len - hashLen;
+
+    for(s4 i = 2; i < (posn - 1); i++)
+    {
+        if(msg[i] != 0xFF){
+            throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+        }
+    }
+
+    if(msg[posn - 1] != 0x00){
+        throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+    }
+
+    for (unsigned int i = 0; i < hashLen; ++i){
+        if (msg[posn + i + DER_Encoding_Len] != hash[i]){
+            throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+        }
+    }
+}
+
+
+/*
+*/
+void Token::verifyRSAX509( Marshaller::u1Array* messageToVerify, Marshaller::u1Array* dataToVerify, const unsigned int& modulusLen ) {
+
+    // Reach the first non-zero bytes in data
+    unsigned int usDataLen = dataToVerify->GetLength( );
+    unsigned int pos1=0;
+    const unsigned char* pData = dataToVerify->GetBuffer( );
+    for( ; pos1 < usDataLen ; ++pos1 ) {
+
+        if( pData[ pos1 ] ) {
+
+            break;
+        }
+    }
+
+    // Reach the first non-zero bytes in decrypted signature
+    unsigned int usMessageLen = messageToVerify->GetLength( );
+    const unsigned char* pMessage = messageToVerify->GetBuffer( );
+    unsigned int pos2=0;
+    for( ; pos2 < usMessageLen ; ++pos2 ) {
+
+        if( pMessage[ pos2 ] ) {
+
+            break;
+        }
+    }
+
+    if( ( usDataLen - pos1 ) != ( modulusLen - pos2 ) ) {
+
+        throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+    }
+
+
+    for( unsigned int i = pos1, j = pos2 ; i < ( modulusLen - pos2 ) ; ++i, ++j ) {
+
+        if( pData[ i ] != pMessage[ j ] ) {
+
+            throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+        }
+    }
+}
+
+
+/*
+*/
+void Token::verifyRSAPKCS1v15( Marshaller::u1Array* messageToVerify, Marshaller::u1Array* dataToVerify, const unsigned int& modulusLen ) {
+
+    // Skip the PKCS block formatting data
+    unsigned int pos = 2;
+    const unsigned char* pMessage = messageToVerify->GetBuffer( ); 
+    for( ; pos < modulusLen ; ++pos) {
+
+        if( !pMessage[ pos ] ) { //== 0x00
+
+            ++pos;
+            break;
+        }
+    }
+
+    if( dataToVerify->GetLength( ) != ( modulusLen - pos ) ) {
+
+        throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+    }
+
+    const unsigned char* pData = dataToVerify->GetBuffer( ); 
+    for( unsigned int i = 0, j = pos ; i < ( modulusLen - pos ) ; ++i, ++j ) {
+
+        if( pData[ i ] != pMessage[ j ] ) {
+
+            throw PKCS11Exception( CKR_SIGNATURE_INVALID );
+        }
+    }
+}
+
+
+/*
+*/
+void Token::sign( const RSAPrivateKeyObject* privObj, Marshaller::u1Array* dataToSign, const CK_ULONG& mechanism, CK_BYTE_PTR pSignature ) {
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > messageToSign;
+
+    RSAPrivateKeyObject* rsaKey = ( RSAPrivateKeyObject* ) privObj;
+
+    if( !(rsaKey->m_pModulus) ) {
+
+        throw PKCS11Exception( CKR_KEY_FUNCTION_NOT_PERMITTED );
+    }
+
+    CK_ULONG modulusLen = rsaKey->m_pModulus->GetLength( );
+
+    if( ( ( mechanism == CKM_RSA_PKCS ) && ( dataToSign->GetLength( ) > ( modulusLen - 11 ) ) ) || ( ( mechanism == CKM_RSA_X_509 ) && ( dataToSign->GetLength( ) > modulusLen ) ) ) {
+
+        throw PKCS11Exception( CKR_DATA_LEN_RANGE );
+    }
+
+    switch( mechanism ) {
+
+    case CKM_RSA_PKCS:
+        messageToSign.reset( PadRSAPKCS1v15( dataToSign, modulusLen ) );
+        break;
+
+    case CKM_RSA_X_509:
+        messageToSign.reset( PadRSAX509( dataToSign, modulusLen ) );
+        break;
+
+    case CKM_SHA1_RSA_PKCS:
+        messageToSign.reset( EncodeHashForSigning( dataToSign, modulusLen, CKM_SHA_1 ) );
+        break;
+
+    case CKM_SHA256_RSA_PKCS:
+        messageToSign.reset( EncodeHashForSigning( dataToSign, modulusLen, CKM_SHA256 ) );
+        break;
+
+    case CKM_MD5_RSA_PKCS:
+        messageToSign.reset( EncodeHashForSigning( dataToSign, modulusLen, CKM_MD5 ) );
+        break;
+    }
+
+    boost::shared_ptr< Marshaller::u1Array > signatureData;
+
+    try {
+
+        signatureData = m_Device->privateKeyDecrypt( rsaKey->m_ucContainerIndex, rsaKey->m_ucKeySpec, messageToSign.get( ) );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::sign", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    if( !signatureData ) {
+
+        throw PKCS11Exception( CKR_FUNCTION_FAILED );
+    }
+
+    memcpy( pSignature, signatureData->GetBuffer( ), signatureData->GetLength( ) );
+}
+
+
+/*
+*/
+Marshaller::u1Array* Token::PadRSAPKCS1v15( Marshaller::u1Array* dataToSign, const CK_ULONG& modulusLen ) {
+
+    Marshaller::u1Array* messageToSign = new Marshaller::u1Array( modulusLen );
+
+    memset( messageToSign->GetBuffer( ), 0, modulusLen );
+
+    messageToSign->SetU1At( 1, 1 );
+
+    s4 offsetMessageToSign = modulusLen - dataToSign->GetLength( ) - 3;
+
+    for( s4 i = 0 ; i < offsetMessageToSign ; ++i ) {
+
+        messageToSign->SetU1At( 2 + i, 0xFF );
+    }
+
+    offsetMessageToSign += 3;
+
+    memcpy( (unsigned char*)&messageToSign->GetBuffer( )[ offsetMessageToSign ], dataToSign->GetBuffer( ), dataToSign->GetLength( ) );
+
+    return messageToSign;
+}
+
+
+/*
+*/
+Marshaller::u1Array* Token::PadRSAX509( Marshaller::u1Array* dataToSign, const CK_ULONG& modulusLen ) {
+
+    Marshaller::u1Array* messageToSign = new Marshaller::u1Array( modulusLen );
+
+    memset( messageToSign->GetBuffer( ), 0, modulusLen );
+
+    s4 offsetMessageToSign = modulusLen - dataToSign->GetLength( );
+
+    memcpy( (unsigned char*)&messageToSign->GetBuffer( )[ offsetMessageToSign ], dataToSign->GetBuffer( ), dataToSign->GetLength( ) );
+
+    return messageToSign;
+}
+
+
+/*
+*/
+Marshaller::u1Array* Token::EncodeHashForSigning( Marshaller::u1Array* hashedData, const CK_ULONG& modulusLen, const CK_ULONG& hashAlgo ) {
+
+    unsigned char DER_SHA1_Encoding[ ]   = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 };
+
+    unsigned char DER_SHA256_Encoding[ ] = { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20 };
+
+    unsigned char DER_MD5_Encoding[ ]    = { 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+
+    unsigned char* DER_Encoding = NULL_PTR;
+
+    s4 DER_Encoding_Len = 0;
+
+    switch( hashAlgo ) {
+
+    case CKM_SHA_1:
+        DER_Encoding_Len = sizeof(DER_SHA1_Encoding);
+        DER_Encoding = new unsigned char[DER_Encoding_Len]; //(unsigned char*)malloc(DER_Encoding_Len);
+        memcpy(DER_Encoding,DER_SHA1_Encoding,DER_Encoding_Len);
+        break;
+
+    case CKM_SHA256:
+        DER_Encoding_Len = sizeof(DER_SHA256_Encoding);
+        DER_Encoding = new unsigned char[DER_Encoding_Len]; //(unsigned char*)malloc(DER_Encoding_Len);
+        memcpy(DER_Encoding,DER_SHA256_Encoding,DER_Encoding_Len);
+        break;
+
+    case CKM_MD5:
+        DER_Encoding_Len = sizeof(DER_MD5_Encoding);
+        DER_Encoding = new unsigned char[DER_Encoding_Len]; //(unsigned char*)malloc(DER_Encoding_Len);
+        memcpy(DER_Encoding,DER_MD5_Encoding,DER_Encoding_Len);
+        break;
+
+    }
+
+    Marshaller::u1Array* messageToSign = new Marshaller::u1Array( modulusLen );
+
+    memset( messageToSign->GetBuffer( ), 0, modulusLen );
+
+    messageToSign->SetU1At( 1, 1 );
+
+    // caluclate pos
+    int pos = modulusLen - DER_Encoding_Len - hashedData->GetLength( );
+
+    for( int i = 2 ; i < (pos - 1) ; ++i ) {
+
+        messageToSign->SetU1At( i, 0xFF );
+    }
+
+    memcpy((unsigned char*)&messageToSign->GetBuffer()[pos],DER_Encoding,DER_Encoding_Len);
+    memcpy((unsigned char*)&messageToSign->GetBuffer()[pos+DER_Encoding_Len],hashedData->GetBuffer(),hashedData->GetLength());
+
+    delete DER_Encoding;
+
+    return messageToSign;
+}
+
+
+/* Add a PKCS11 object to the token object list
+*/ 
+CK_OBJECT_HANDLE Token::registerStorageObject( StorageObject* a_pObject ) {
+
+    Log::begin( "Token::registerStorageObject" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject ) {
+
+        Log::error( "Token::registerStorageObject", "Invalid object" );
+        return CK_UNAVAILABLE_INFORMATION;
+    }
+
+    // increment the object index
+    CK_OBJECT_HANDLE h = computeObjectHandle( a_pObject->getClass( ), a_pObject->isPrivate( ) );
+
+    // Expand the object list
+    m_Objects.insert( h, a_pObject );
+
+    Log::log( "registerStorageObject - Handle <%#02x> - Type <%ld> - File <%s>", h, a_pObject->getClass( ), a_pObject->m_stFileName.c_str( ) );
+    printObject( a_pObject );
+
+    t.stop( "Token::registerStorageObject" );
+    Log::end( "Token::registerStorageObject" );
+
+    // Return the object index
+    return h;
+}
+
+
+/*
+*/
+void Token::printObject( StorageObject* a_pObject ) {
+
+    if( !Log::s_bEnableLog ) {
+
+        return;
+    }
+
+    Log::log( "    ====" );
+
+    switch( a_pObject->getClass( ) ) {
+
+    case CKO_DATA:
+        Log::log( "Object CKO_DATA" );
+        ( (DataObject*) a_pObject )->print( );
+        break;
+
+    case CKO_CERTIFICATE:
+        Log::log( "Object CKO_CERTIFICATE" );
+        ( (X509PubKeyCertObject*) a_pObject )->print( );
+        break;
+
+    case CKO_PRIVATE_KEY:
+        Log::log( "Object CKO_PRIVATE_KEY" );
+        ( (RSAPrivateKeyObject*) a_pObject )->print( );
+        break;
+
+    case CKO_PUBLIC_KEY:
+        Log::log( "Object CKO_PUBLIC_KEY" );
+        ( (Pkcs11ObjectKeyPublicRSA*) a_pObject )->print( );
+        break;
+    };
+
+    Log::log( "    ====" );
+
+}
+
+
+/*
+*/
+void Token::unregisterStorageObject( const CK_OBJECT_HANDLE& a_pObject ) {
+
+    Log::begin( "Token::unregisterStorageObject" );
+    Timer t;
+    t.start( );
+
+    TOKEN_OBJECTS::iterator i = m_Objects.find( a_pObject );
+
+    if( i != m_Objects.end( ) ) {
+
+        m_Objects.erase( i );
+
+        Log::log( "unregisterStorageObject - Handle <%#02x> erased", a_pObject );
+    }
+
+    t.stop( "Token::unregisterStorageObject" );
+    Log::end( "Token::unregisterStorageObject" );
+}
+
+
+/*
+*/
+void Token::initPIN( Marshaller::u1Array* a_PinSo, Marshaller::u1Array* a_PinUser ) {
+
+    Log::begin( "Token::initPIN" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // Initialize the PIN
+        m_Device->unblockPin( a_PinSo, a_PinUser );
+
+        // ??? TO DO ??? Utiliser la propriet\xE9 card pin initalize
+        m_TokenInfo.flags |= CKF_USER_PIN_INITIALIZED;
+
+        // Reset some User PIN flags
+        m_TokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
+        m_TokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
+        m_TokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
+
+    } catch( MiniDriverException& ) {
+
+        // incorrect pin
+        unsigned char triesRemaining = 0;
+
+        try {
+
+            triesRemaining = m_Device->administratorGetTriesRemaining( );
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Token::initPIN", "MiniDriverException" );
+            throw PKCS11Exception( checkException( x ) );
+        }
+
+        // blocked
+        if(triesRemaining == 0) {
+
+            // update tokeninfo flahs
+            m_TokenInfo.flags |= CKF_SO_PIN_LOCKED;
+            m_TokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
+            m_TokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
+
+        } else if( triesRemaining == 1 ) {
+
+            m_TokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
+            m_TokenInfo.flags |= CKF_SO_PIN_FINAL_TRY;
+            m_TokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
+
+        }else /*if( triesRemaining < MAX_SO_PIN_TRIES )*/ {
+
+            m_TokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
+            m_TokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
+            m_TokenInfo.flags |= CKF_SO_PIN_COUNT_LOW;
+
+        }
+
+        throw PKCS11Exception( CKR_PIN_INCORRECT );
+    }
+
+    t.stop( "Token::initPIN" );
+    Log::end( "Token::initPIN" );
+}
+
+
+/*
+*/
+void Token::setPIN( Marshaller::u1Array* a_pOldPIN, Marshaller::u1Array* a_pNewPIN ) {
+
+    Log::begin( "Token::setPIN" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device || !m_pSlot ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // According the logical state of the slot the PIN is set for the user or the administrator
+    // The logical state is based on the PKCS11 state of the slot's sessions
+    try {
+
+        if( m_pSlot->isAuthenticated( ) ) {
+
+            m_Device->changePin( a_pOldPIN, a_pNewPIN );
+
+        } else if( m_pSlot->administratorIsAuthenticated( ) ) {
+
+            m_Device->administratorChangeKey( a_pOldPIN, a_pNewPIN );
+
+        } else {
+
+            throw PKCS11Exception( CKR_USER_NOT_LOGGED_IN );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        checkAuthenticationStatus( m_RoleLogged, x );
+    }
+
+    t.stop( "Token::setPIN" );
+    Log::end( "Token::setPIN" );
+}
+
+
+/*
+*/
+void Token::initToken( Marshaller::u1Array* a_pinSO, Marshaller::u1Array* a_label ) {
+
+    Log::begin( "Token::initToken" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Check that label does not contain null-characters
+    unsigned int l = a_label->GetLength( );
+
+    for( unsigned int i = 0 ; i < l; ++i ) {
+
+        if( !a_label->ReadU1At( i ) ) {
+
+            throw PKCS11Exception( CKR_ARGUMENTS_BAD );
+        }
+    }
+
+    // actual authentication
+    authenticateAdmin( a_pinSO );
+
+    try
+    {
+        // Destroy all the token objects present into the PKCS11 directory
+        // Note that when the private key is destroyed the associated container is also deleted
+        BOOST_FOREACH( const TOKEN_OBJECTS::value_type& o, m_Objects ) {
+
+            // Delete the PKCS#11 object file from card
+            deleteObjectFromCard( o->second );
+        }
+
+        // Destroy all PKCS11 objects from the inner list of objects to manage
+        m_Objects.clear( );
+
+        // Destroy all the token objects present into the MSCP directory
+        try {
+
+            m_Device->deleteFileStructure( );
+
+        } catch( MiniDriverException& x ) {
+
+            Log::error( "Token::initToken", "MiniDriverException" );
+            throw PKCS11Exception( checkException( x ) );
+        }
+
+        // Update the token's label and flags attribute.
+        m_TokenInfo.flags |= CKF_TOKEN_INITIALIZED;
+
+        m_TokenInfo.flags &= ~CKF_USER_PIN_INITIALIZED;
+
+        memcpy( m_TokenInfo.label, a_label->GetBuffer( ), sizeof( m_TokenInfo.label ) );
+
+        createTokenInfo( );
+
+        // Write the new token information file into the smart card
+        m_bWriteTokenInfoFile = true;
+
+        writeTokenInfo( );
+
+        // Log out
+        m_Device->administratorLogout( );
+
+        m_RoleLogged = CK_UNAVAILABLE_INFORMATION;
+
+    } catch( MiniDriverException& x) {
+
+        m_RoleLogged = CK_UNAVAILABLE_INFORMATION;
+
+        try { m_Device->administratorLogout( ); } catch(...) {}
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::initToken" );
+    Log::end( "Token::initToken" );
+}
+
+
+/*
+*/
+CK_OBJECT_HANDLE Token::computeObjectHandle( const CK_OBJECT_CLASS& a_ulClass, const bool& a_bIsPrivate ) { 
+
+    // Increment the object counter
+    incrementObjectIndex( );
+
+    // Register the token object id (value from 0 to 255)
+    unsigned char ucByte1 = m_uiObjectIndex;
+
+    // Register the object class and if the object is private:
+    // Private Data	        1000 [08] = set class to CKO_DATA (0x00) and Private to TRUE (0x08)
+    // Public Data	        0000 [00] = set class to CKO_DATA (0x00) and Private to FALSE (0x00)	
+    // Private Certificate	1001 [09] = set class to CKO_CERTIFICATE (0x01) and Private to TRUE (0x08)
+    // Public Certificate	0001 [01] = set class to CKO_CERTIFICATE (0x01) and Private to FALSE (0x00)		
+    // Private Public Key	1010 [0A] = set class to CKO_PUBLIC_KEY (0x02) and Private to TRUE (0x08)
+    // Public Public Key	0010 [02] = set class to CKO_PUBLIC_KEY (0x02) and Private to FALSE (0x00)    
+    // Private Private Key	1011 [0B] = set class to CKO_PRIVATE_KEY (0x03) and Private to TRUE (0x08)			
+    // Public Private Key	0011 [03] = set class to CKO_PRIVATE_KEY (0x03) and Private to FALSE (0x00)
+    unsigned char ucByte2 = (unsigned char)a_ulClass | ( a_bIsPrivate ? 0x10 : 0x00 );
+
+    // Register if the object is owned by the token (value 0) or the session (value corresponding to the session id from 1 to 255)
+    unsigned char ucByte3 = 0;
+
+    // Register the slot id
+    unsigned char ucByte4 = 0xFF;
+    try {
+
+        if( m_Device ) {
+
+            ucByte4 = (unsigned char) ( 0x000000FF & m_Device->getDeviceID( ) );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::computeObjectHandle", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    // Compute the object handle: byte4 as Slot Id, byte3 as Token/Session, byte2 as attributes and byte1 as object Id					
+    CK_OBJECT_HANDLE h = ( ucByte4 << 24 ) + ( ucByte3 << 16 ) + ( ucByte2 << 8 )+ ucByte1;
+
+    return h; 
+}
+
+
+/*
+*/
+StorageObject* Token::getObject( const CK_OBJECT_HANDLE& a_hObject ) {
+
+    TOKEN_OBJECTS::iterator i = m_Objects.find( a_hObject );
+
+    if( i == m_Objects.end( ) ) {
+
+        throw PKCS11Exception( CKR_OBJECT_HANDLE_INVALID );
+    }
+
+    return i->second;
+}
+
+
+/*
+*/
+bool isFileExists( const std::string& a_stFileName, const MiniDriverFiles::FILES_NAME& a_stFilesList ) {
+
+    // Look if the file name is present intot the list
+    BOOST_FOREACH( const std::string& fileName, a_stFilesList ) {
+
+        // The file name has been found
+        if( std::string::npos != a_stFileName.find( fileName ) ) {
+
+            return true;
+        }
+    }
+
+    return false;
+}
+
+
+/*
+*/
+void Token::synchronizeObjects( void ) {
+
+    Log::begin( "Token::synchronizeObjects" );
+    Timer t;
+    t.start( );
+
+    try {
+
+        initializeObjectIndex( );
+
+        // PIN changed, so re-synchronize
+        synchronizePIN( );		
+
+        // Remove all PKCS11 objects
+        m_Objects.clear( );
+
+        // Files changed, so re-synchronize
+        m_bSynchronizeObjectsPublic = true;
+        synchronizePublicObjects( );
+
+        m_bSynchronizeObjectsPrivate = true;
+        synchronizePrivateObjects( );	
+
+    } catch( ... ) {
+
+    }
+
+    t.stop( "Token::synchronizeObjects" );
+    Log::end( "Token::synchronizeObjects" );
+}
+
+
+/*
+*/
+bool Token::synchronizeIfSmartCardContentHasChanged( void ) {
+
+    Log::begin( "Token::synchronizeIfSmartCardContentHasChanged" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    bool bSynchronizationPerformed = false;
+
+    try {
+
+        // Check if the smart card content has changed
+        MiniDriverCardCacheFile::ChangeType pins = MiniDriverCardCacheFile::NONE;
+        MiniDriverCardCacheFile::ChangeType containers = MiniDriverCardCacheFile::NONE;
+        MiniDriverCardCacheFile::ChangeType files = MiniDriverCardCacheFile::NONE;
+        m_Device->hasChanged( pins, containers, files );
+
+        if( MiniDriverCardCacheFile::PINS == pins ) {
+
+            // PIN changed, so re-synchronize
+            synchronizePIN( );		
+        }
+
+        if( ( MiniDriverCardCacheFile::CONTAINERS == containers ) || ( MiniDriverCardCacheFile::FILES == files ) ) {
+
+            synchronizeObjects( );
+
+            bSynchronizationPerformed = true;
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::synchronizeIfSmartCardContentHasChanged", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+
+    }
+
+    t.stop( "Token::synchronizeIfSmartCardContentHasChanged" );
+    Log::end( "Token::synchronizeIfSmartCardContentHasChanged" );
+
+    return bSynchronizationPerformed;
+}
+
+
+/* Synchronise the cache with the smart card content
+*/
+void Token::synchronizePublicObjects( void ) {
+
+    try {
+
+        if( !m_bSynchronizeObjectsPublic ) {
+
+            return;
+        }
+        m_bSynchronizeObjectsPublic = false;
+
+        Log::begin( "Token::synchronizeObjectsPublic" );
+        Timer t;
+        t.start( );
+
+        synchronizeRootCertificateObjects( );
+
+        synchronizePublicDataObjects( );
+
+        synchronizePublicCertificateAndKeyObjects( );
+
+        t.stop( "Token::synchronizePublicObjects" );
+        Log::end( "Token::synchronizePublicObjects" );
+
+    } catch( ... ) {
+
+    }
+}
+
+
+/*
+*/
+void Token::synchronizePrivateObjects( void ) {
+
+    if( !m_bSynchronizeObjectsPrivate ) {
+
+        return;
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    try {
+
+        // Synchronization of the private objects is only possible is the user is logged in
+        
+        //========= TEST
+        if( m_pSlot && !m_pSlot->isAuthenticated( ) ) {
+        //if( !m_Device->isAuthenticated( ) ) {
+
+            return;
+        }
+
+        Log::begin( "Token::synchronizeObjectsPrivate" );
+        Timer t;
+        t.start( );
+
+        synchronizePrivateDataObjects( );
+
+        synchronizePrivateKeyObjects( );
+
+        m_bSynchronizeObjectsPrivate = false;
+
+        t.stop( "Token::synchronizeObjectsPrivate" );
+        Log::end( "Token::synchronizeObjectsPrivate" );
+
+    } catch( ... ) {
+
+        m_bSynchronizeObjectsPrivate = true;
+    }
+
+    //m_bSynchronizeObjectsPrivate = false;
+}
+
+
+/*
+*/
+void Token::synchronizePIN( void ) {
+
+    try {
+
+        Log::begin( "Token::synchronizePIN" );
+        Timer t;
+        t.start( );
+
+        // ??? TO DO ???
+
+        t.stop( "Token::synchronizePIN" );
+        Log::end( "Token::synchronizePIN" );
+
+    } catch( ... ) {
+
+    }
+}
+
+
+/*
+*/
+void Token::synchronizeRootCertificateObjects( void ) {
+
+    Log::begin( "Token::synchronizeRootCertificateObjects" );
+    Timer t;
+    t.start( );
+
+    // No directory ? So object to load
+    if( m_bCreateDirectoryP11 ) {
+
+        return;
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    unsigned char ucIndex = 0;
+    unsigned char ucIndexMax = m_Device->containerCount( );
+
+    try {
+
+        // Get all PKCS11 object files from the PKCS11 directory into the smart card
+        MiniDriverFiles::FILES_NAME filesPKCS11 = m_Device->enumFiles( g_stPathPKCS11 );
+
+        // Get all certificate files from the smart card
+        MiniDriverFiles::FILES_NAME filesMiniDriver = m_Device->enumFiles( std::string( szBASE_CSP_DIR ) );
+
+        std::string stPrefixMiniDriver = std::string( szUSER_KEYEXCHANGE_CERT_PREFIX );
+
+        std::string stPrefixPKCS11 = g_stPrefixPublicObject + g_stPrefixRootCertificate;
+
+        std::string stFilePKCS11 = "";
+
+        BOOST_FOREACH( const std::string& stFileMiniDriver, filesMiniDriver ) {
+
+            // All files must begin with a fixed prefix for public objects
+            if( stFileMiniDriver.find( stPrefixMiniDriver ) != 0 ) {
+
+                // Only deal with objects corresponding to the incoming prefix
+                continue;
+            }
+
+            // The index of a root certificate is out of the range of the valid MiniDriver containers
+            ucIndex = computeIndex( stFileMiniDriver );
+            if ( ucIndex <= ucIndexMax ) {
+
+                continue;
+            }
+
+            stFilePKCS11 = stPrefixPKCS11;
+            Util::toStringHex( ucIndex, stFilePKCS11 );
+
+            MiniDriverFiles::FILES_NAME::iterator it = filesPKCS11.find( stFilePKCS11 );
+
+            if( it != filesPKCS11.end( ) ) {
+
+                // The PKCS11 object exists. Load it.
+                createCertificateFromPKCS11ObjectFile( stFilePKCS11, stFileMiniDriver );
+
+            } else {
+
+                // The PKCS11 object does not exists. Create a memory object from the MiniDriver file.
+                createCertificateFromMiniDriverFile( stFileMiniDriver, MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID,  MiniDriverContainer::KEYSPEC_SIGNATURE );
+            }
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::synchronizeRootCertificateObjects", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::synchronizeRootCertificateObjects" );
+    Log::end( "Token::synchronizeRootCertificateObjects" );
+}
+
+
+/* Read all public data
+*/
+void Token::synchronizePublicDataObjects( void ) {
+
+    Log::begin( "Token::synchronizePublicDataObjects" );
+    Timer t;
+    t.start( );
+
+    if( m_bCreateDirectoryP11 ) {
+
+        return;
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    try {
+
+        // Get all PKCS11 object files from the PKCS11 directory into the smart card
+        MiniDriverFiles::FILES_NAME files = m_Device->enumFiles( g_stPathPKCS11 );
+
+        std::string a_stPrefix = g_stPrefixPublicObject + g_stPrefixData;
+
+        BOOST_FOREACH( const std::string& s, files ) {
+
+            // All files must begin with a fixed prefix for public objects
+            if( s.find( a_stPrefix ) != 0 ) {
+
+                // Only deal with objects corresponding to the incoming prefix
+                continue;
+            }
+
+            // Read the file
+            Marshaller::u1Array* f = m_Device->readFile( g_stPathPKCS11, s );
+
+            // Construct the PKCS11 object attributes from the file
+            std::vector< unsigned char > attributes;
+
+            unsigned int l = f->GetLength( );
+
+            for( unsigned int u = 0 ; u < l ; ++u ) {
+
+                attributes.push_back( f->GetBuffer( )[ u ] );
+            }
+
+            // Create the PKCS11 object
+            DataObject* o = new DataObject( );
+
+            // Put the file content into the object
+            CK_ULONG idx = 0;
+            o->deserialize( attributes, &idx );
+
+            // Save the fileName in the object 
+            o->m_stFileName = s;
+
+            Log::log( "Found %s - Public data object created", s.c_str( ) );
+
+            registerStorageObject( o );
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::synchronizePublicDataObjects", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::synchronizePublicDataObjects" );
+    Log::end( "Token::synchronizePublicDataObjects" );
+}
+
+
+/* Read all private data
+*/
+void Token::synchronizePrivateDataObjects( void ) {
+
+    Log::begin( "Token::synchronizePrivateDataObjects" );
+    Timer t;
+    t.start( );
+
+    if( m_bCreateDirectoryP11 ) {
+
+        return;
+    }
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    try {
+
+        // Get all PKCS11 object files from the PKCS11 directory into the smart card
+        MiniDriverFiles::FILES_NAME files = m_Device->enumFiles( g_stPathPKCS11 );
+
+        std::string a_stPrefix = g_stPrefixPrivateObject + g_stPrefixData;
+
+        BOOST_FOREACH( const std::string& s, files ) {
+
+            // All files must begin with a fixed prefix for public objects
+            if( s.find( a_stPrefix ) != 0 ) {
+
+                // Only deal with objects corresponding to the incoming prefix
+                continue;
+            }
+
+            // Read the file
+            Marshaller::u1Array* f = m_Device->readFile( g_stPathPKCS11, s );
+
+            // Construct the PKCS11 object attributes from the file
+            std::vector< unsigned char > attributes;
+
+            unsigned int l = f->GetLength( );
+
+            for( unsigned int u = 0 ; u < l ; ++u ) {
+
+                attributes.push_back( f->GetBuffer( )[ u ] );
+            }
+
+            // Create the PKCS11 object
+            DataObject* o = new DataObject( );
+
+            // Put the file content into the object
+            CK_ULONG idx = 0;
+            o->deserialize( attributes, &idx );
+
+            // Save the fileName in the object 
+            o->m_stFileName = s;
+
+            Log::log( "Found %s - Private data created", s.c_str( ) );
+
+            registerStorageObject( o );
+
+            m_Device->cacheDisable( s );
+        }
+
+    } catch( MiniDriverException& ) {
+
+        Log::error( "Token::synchronizePrivateDataObjects", "MiniDriverException" );
+    }
+
+    t.stop( "Token::synchronizePrivateDataObjects" );
+    Log::end( "Token::synchronizePrivateDataObjects" );
+}
+
+
+/*
+*/
+bool Token::checkSmartCardContent( void ) {
+
+    Log::begin( "Token::checkSmartCardContent" );
+    Timer t;
+    t.start( );
+
+    if( m_bCheckSmartCardContentDone ) {
+     
+        return false;
+    }
+
+    Log::log(" Token::checkSmartCardContent -$$$$$$$$$$$$$ Obj BEFORE P11 clean");
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& o, m_Objects ) {
+
+        printObject( o.second );
+    }
+    Log::log(" Token::checkSmartCardContent -$$$$$$$$$$$$$ Obj BEFORE P11 clean");
+
+
+    bool bReturn = false;
+
+    if( !m_Device ) {
+
+        return bReturn;
+    }
+
+    // Get all PKCS11 object files from the PKCS11 directory into the smart card
+    MiniDriverFiles::FILES_NAME filesPKCS11;
+
+    if( !m_bCreateDirectoryP11 ) {
+
+        try {
+
+            filesPKCS11 = m_Device->enumFiles( g_stPathPKCS11 );
+
+        } catch( ... ) { }
+    }
+
+    // Get all certificate files from the smart card
+    MiniDriverFiles::FILES_NAME filesMiniDriver = m_Device->enumFiles( std::string( szBASE_CSP_DIR ) );
+
+    std::string stContainerIndex = "";
+    unsigned char ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+    unsigned int uiKeySize = 0;
+    std::string stPrefix = "";
+    std::string stCertificateFileName = "";
+    std::string stObjectPKCS11 = "";
+    std::string stPublicCertificateExchange = g_stPrefixPublicObject + std::string( szUSER_KEYEXCHANGE_CERT_PREFIX );
+    std::string stPublicCertificateSignature = g_stPrefixPublicObject + std::string( szUSER_SIGNATURE_CERT_PREFIX );
+    std::string stPublicKey = g_stPrefixPublicObject + g_stPrefixKeyPublic;
+    std::string stPrivateKey = g_stPrefixPrivateObject + g_stPrefixKeyPrivate;
+    unsigned char ucKeyContainerIndexReal = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+    std::string stFileName = "";
+
+    try {
+
+        // Explore each smart card key container to fix any CMapFile anomaly or wrong associated certificate
+        unsigned char ucContainerCount = m_Device->containerCount( );
+
+        for( unsigned char ucContainerIndex = 0 ; ucContainerIndex < ucContainerCount ; ++ucContainerIndex ) {
+
+            stContainerIndex = "";
+            Util::toStringHex( ucContainerIndex, stContainerIndex );
+
+            // Get the current container
+            MiniDriverContainer cont = m_Device->containerGet( ucContainerIndex );
+
+            Log::log( "=========" );
+            Log::log( "Token::checkSmartCardContent - Container <%d>", ucContainerIndex );
+
+            unsigned char flags = cont.getFlags( );
+            if ( flags == MiniDriverContainer::CMAPFILE_FLAG_EMPTY ) {
+
+                // The current container is empty
+
+                // Check that none P11 object is associated to this container
+                // If a P11 object using this index then it must be associated to the good container or be deleted
+
+                // Check that none MiniDriver certificate is associated to this container
+                // If a MiniDriver certificate exists then it must be associated to the good contained or be deleted
+                // It could also be a root certificate enrolled by an old P11 version
+
+                // Check the container properties is compliant with the CMapFile state
+                // If the CMapFile state shows a type (signature/exchange), a size (1024/2048) or a state (empty/valid/valid & default) different 
+                // from the information given by the container property then the CMapFile must be changed
+
+                Log::log( "Token::checkSmartCardContent - This container is empty" );
+
+                stCertificateFileName = szUSER_KEYEXCHANGE_CERT_PREFIX;
+                stCertificateFileName += stContainerIndex;
+                Log::log( "Token::checkSmartCardContent - Check if the certificate <%s> is present", stCertificateFileName.c_str( ) );
+
+                MiniDriverFiles::FILES_NAME::iterator it = filesMiniDriver.find( stCertificateFileName );
+
+                if( it != filesMiniDriver.end( ) ) {
+
+                    // The container is empty but a certificate is associated into the MiniDriver file structure.
+                    // That certificate must be moved from the MiniDriver file structure to the PKCS11 one.
+
+                    // Create a new root certificate
+                    X509PubKeyCertObject* pNewCertificate = new X509PubKeyCertObject( );
+
+                    pNewCertificate->m_stCertificateName = "";
+
+                    pNewCertificate->m_stFileName = "";
+
+                    pNewCertificate->m_ucContainerIndex = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+
+                    try {
+
+                        // Read the file
+                        m_Device->readCertificate( stCertificateFileName, pNewCertificate->m_pValue );
+
+                    } catch( MiniDriverException& ) {
+
+                        // Unable to read the on card certificate.
+                        // The P11 object creation is skipped.
+                        Log::error( "Token::createCertificateFromMiniDriverFile", "Unable to read the certificate" );
+                        continue;
+                    }
+
+                    if( pNewCertificate->m_pValue.get( ) ) {
+
+                        generatePublicKeyModulus( pNewCertificate->m_pValue, pNewCertificate->m_pModulus, pNewCertificate->_checkValue );
+
+                        generateRootAndSmartCardLogonFlags( pNewCertificate->m_pValue, pNewCertificate->m_bIsRoot, pNewCertificate->_certCategory, pNewCertificate->m_bIsSmartCardLogon );
+                    }
+
+                    // Delete the old certificate from the MiniDriver file structure
+                    m_Device->deleteFile( std::string( szBASE_CSP_DIR ), stCertificateFileName );
+                    Log::log( "Token::checkSmartCardContent - delete <%s> in MSCP dir", stCertificateFileName.c_str( ) );
+                    bReturn = true;
+
+                    // Remove the previous PKCS11 certificate associated to the MiniDriver certificate
+                    std::string stIndex = stCertificateFileName.substr( stCertificateFileName.length( ) - 2, 2 );
+                    std::string stPKCS11CertificateName = stPublicCertificateExchange + stIndex;
+                    m_Device->deleteFile( g_stPathPKCS11, stPKCS11CertificateName );
+                    Log::log( "Token::checkSmartCardContent - delete <%s> in P11 dir", stPKCS11CertificateName.c_str( ) );
+
+                    //// Delete the PKCS#11 object from inner list of managed objects
+                    //unregisterStorageObject( p );
+                    //Log::log( "Token::checkSmartCardContent - delete <%s> in MSCP dir", stCertificateFileName.c_str( ) );
+
+                    // Create the new root certificate intot the MniDriver & PKCS11 file structures
+                    CK_OBJECT_HANDLE h = CK_UNAVAILABLE_INFORMATION;
+                    addObjectCertificate( pNewCertificate, &h );
+                    Log::log( "Token::checkSmartCardContent - add new P11 root certificate <%s>", pNewCertificate->m_stFileName.c_str( ) );
+
+                    pNewCertificate->m_stCertificateName = pNewCertificate->m_stFileName.substr( 3, 5 );
+
+                    // Delete the container from the MiniDriver file structure
+                    m_Device->containerDelete( ucContainerIndex );
+                    Log::log( "Token::checkSmartCardContent - delete container <%d>", ucContainerIndex );
+
+                    // Check if a private or a public key was associated to this container
+                    std::string stPrefix = stPrivateKey;
+
+                    do {
+
+                        stObjectPKCS11 = stPrefix + stIndex;
+
+                        MiniDriverFiles::FILES_NAME::iterator it = filesPKCS11.find( stObjectPKCS11 );
+
+                        if( it != filesPKCS11.end( ) ) {
+
+                            // The PKCS11 private/public key exists.
+                            // Check the public key modulus to find a new container to associate with
+
+                            // Read the file
+                            Marshaller::u1Array* f = m_Device->readFile( g_stPathPKCS11, stObjectPKCS11 );
+
+                            // Construct the PKCS11 object attributes from the file
+                            std::vector< unsigned char > attributes;
+
+                            unsigned int l = f->GetLength( );
+
+                            for( unsigned int u = 0 ; u < l ; ++u ) {
+
+                                attributes.push_back( f->GetBuffer( )[ u ] );
+                            }
+
+                            // Create the PKCS11 object from the file content
+                            boost::shared_ptr< StorageObject > oldObjectOnCard;
+
+                            CK_ULONG idx = 0;
+
+                            if( stPrefix.compare( stPublicKey ) == 0 ) {
+
+                                oldObjectOnCard.reset( new Pkcs11ObjectKeyPublicRSA ); 
+
+                                ( ( Pkcs11ObjectKeyPublicRSA* ) oldObjectOnCard.get( ) )->deserialize( attributes, &idx );
+
+                            } else {
+
+                                oldObjectOnCard.reset( new RSAPrivateKeyObject );
+
+                                ( ( RSAPrivateKeyObject* ) oldObjectOnCard.get( ) )->deserialize( attributes, &idx );
+                            }
+
+                            // Set the old file name
+                            oldObjectOnCard->m_stFileName = stObjectPKCS11;
+
+                            // Get the container index written into the object
+                            unsigned char ucKeyContainerIndexInObject = ( ( KeyObject* ) oldObjectOnCard.get( ) )->m_ucContainerIndex;
+                            Log::log( "Token::checkSmartCardContent - Container index found into the P11 object <%d>", ucKeyContainerIndexInObject );
+
+                            // Get the container index set into the file name
+                            unsigned char ucKeyContainerIndexInFileName = computeIndex( stIndex );
+                            Log::log( "Token::checkSmartCardContent - Container index found into the P11 file name <%d>", ucKeyContainerIndexInFileName );
+
+                            // Get the public key modulus
+                            Marshaller::u1Array* pPublicKeyModulus = NULL;
+
+                            if( 0 == stPrefix.compare( stPublicKey ) ) {
+
+                                pPublicKeyModulus = ( ( Pkcs11ObjectKeyPublicRSA* ) oldObjectOnCard.get( ) )->m_pModulus.get( );
+
+                            } else {
+
+                                pPublicKeyModulus = ( ( RSAPrivateKeyObject* ) oldObjectOnCard.get( ) )->m_pModulus.get( );
+                            }
+
+                            if( pPublicKeyModulus ) {
+
+                                Log::logCK_UTF8CHAR_PTR( "Token::checkSmartCardContent - File Public key modulus", pPublicKeyModulus->GetBuffer( ), pPublicKeyModulus->GetLength( ) );
+
+                                // Search for a container using the same public key container
+                                ucKeyContainerIndexReal = MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID;
+                                ucKeySpec = 0xFF;
+                                stFileName = "";
+                                m_Device->containerGetMatching( ucKeyContainerIndexReal, ucKeySpec, stFileName, pPublicKeyModulus );
+                                Log::log( "Token::checkSmartCardContent - Real container index found comparing the public key modulus of each container with the P11 object one <%d>", ucKeyContainerIndexReal );
+
+                                // Compare the container index defined in the PKCS11 object with the container index using that public key modulus
+                                if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == ucKeyContainerIndexReal ) {
+
+                                    // No container exists into the smart card matching with the public key set into the P11 object
+                                    // This object should be deleted
+                                    Log::log( "Token::checkSmartCardContent - No inner container index for <%s>", stObjectPKCS11.c_str( ) );
+
+                                } else if( ucKeyContainerIndexInFileName != ucKeyContainerIndexReal ) {
+
+                                    // The both index are different !
+
+                                    CK_OBJECT_HANDLE h = CK_UNAVAILABLE_INFORMATION;
+                                    if( stPrefix.compare( stPublicKey ) == 0 ) { 
+
+                                        Pkcs11ObjectKeyPublicRSA* pNewKey = new Pkcs11ObjectKeyPublicRSA( ( const Pkcs11ObjectKeyPublicRSA* ) oldObjectOnCard.get( ) );
+
+                                        // Set the good container index into the PKCS11 object
+                                        pNewKey->m_ucContainerIndex = ucKeyContainerIndexReal;
+
+                                        // Set the good file name in to the PKCS11 object
+                                        pNewKey->m_stFileName = stPrefix;
+                                        Util::toStringHex( ucKeyContainerIndexReal, pNewKey->m_stFileName );
+
+                                        // Create the new root certificate
+                                        addObject( pNewKey, &h );
+
+                                        //m_bSynchronizeObjectsPublic = true;
+
+                                        Log::log( "Token::checkSmartCardContent - add new P11 public key <%s>", pNewKey->m_stFileName.c_str( ) );
+
+                                    } else {
+
+                                        RSAPrivateKeyObject* pNewKey = new RSAPrivateKeyObject( ( const RSAPrivateKeyObject* ) oldObjectOnCard.get( ) );
+
+                                        // Set the good container index into the PKCS11 object
+                                        pNewKey->m_ucContainerIndex = ucKeyContainerIndexReal;
+
+                                        // Set the good file name in to the PKCS11 object
+                                        pNewKey->m_stFileName = stPrefix;
+                                        Util::toStringHex( ucKeyContainerIndexReal, pNewKey->m_stFileName );
+
+                                        // Create the new root certificate
+                                        addObject( pNewKey, &h ); 
+
+                                        //m_bSynchronizeObjectsPrivate = true;
+
+                                        Log::log( "Token::checkSmartCardContent - add new P11 private key <%s>", pNewKey->m_stFileName.c_str( ) );
+                                    }
+
+                                    // Delete the old PKCS#11 object & MiniDriver file/container from card
+                                    m_Device->deleteFile( g_stPathPKCS11, oldObjectOnCard->m_stFileName );
+                                    Log::log( "Token::checkSmartCardContent - delete old P11 key <%s>", oldObjectOnCard->m_stFileName.c_str( ) );
+
+                                    // Delete the old PKCS#11 object from inner list of managed objects
+                                    TOKEN_OBJECTS::iterator i = m_Objects.begin( );
+                                    while( i != m_Objects.end( ) ) {
+
+                                        if( 0 == i->second->m_stFileName.compare( oldObjectOnCard->m_stFileName ) ) {
+
+                                            m_Objects.erase( i );
+
+                                            break;
+                                        }
+
+                                        ++i;
+                                    }	
+                                }
+
+                            } else {
+
+                                // The public key modulus is missing. The public/private key is not well formated
+                                Log::log( "Token::checkSmartCardContent - No modulus for <%s>", stObjectPKCS11.c_str( ) );
+                            }
+                        }
+
+                        if( stPrefix.compare( stPrivateKey ) == 0 ) {
+
+                            stPrefix = stPublicKey;
+
+                        } else if( stPrefix.compare( stPublicKey ) == 0 ) {
+
+                            stPrefix ="";
+                            break;
+                        }
+
+                    } while( 0 != stPrefix.compare( "" ) );
+                }
+            }
+        }
+    } catch( MiniDriverException& ) {
+
+        Log::error( "Token::checkSmartCardContent", "MiniDriverException" );
+    }
+
+    Log::log(" Token::checkSmartCardContent -$$$$$$$$$$$$$ Obj after P11 clean");
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& o, m_Objects ) {
+
+        printObject( o.second );
+    }
+    Log::log(" Token::checkSmartCardContent -$$$$$$$$$$$$$ Obj after P11 clean");
+
+    t.stop( "Token::checkSmartCardContent" );
+    Log::end( "Token::checkSmartCardContent" );
+
+    m_bCheckSmartCardContentDone = true;
+
+    return bReturn;
+}
+
+
+/*
+*/
+void Token::synchronizePublicCertificateAndKeyObjects( void ) {
+
+    Log::begin( "Token::synchronizePublicCertificateAndKeyObjects" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    try {
+
+        // Get all PKCS11 object files from the PKCS11 directory into the smart card
+        MiniDriverFiles::FILES_NAME filesPKCS11;
+
+        if( !m_bCreateDirectoryP11 ) {
+
+            try {
+
+                filesPKCS11 = m_Device->enumFiles( g_stPathPKCS11 );
+
+            } catch( ... ) {
+
+            }
+        }
+
+        // Get all certificate files from the smart card
+        MiniDriverFiles::FILES_NAME filesMiniDriver = m_Device->enumFiles( std::string( szBASE_CSP_DIR ) );
+
+        std::string stContainerIndex = "";
+        unsigned char ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+        unsigned int uiKeySize = 0;
+        std::string stPrefix = "";
+        std::string stCertificateFileName = "";
+        std::string stObjectPKCS11 = "";
+
+        // Explore each smart card key container
+        unsigned char ucContainerCount = m_Device->containerCount( );
+
+        for( unsigned char ucContainerIndex = 0 ; ucContainerIndex < ucContainerCount ; ++ucContainerIndex ) {
+
+            stContainerIndex = "";
+            Util::toStringHex( ucContainerIndex, stContainerIndex );
+
+            // Get the current container
+            MiniDriverContainer c = m_Device->containerGet( ucContainerIndex );
+
+            // Only deal with valid containers
+            if( MiniDriverContainer::CMAPFILE_FLAG_EMPTY != c.getFlags( ) ) {
+
+                // Get the key information
+                ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+
+                uiKeySize = c.getKeyExchangeSizeBits( );
+
+                boost::shared_ptr< Marshaller::u1Array > pPublicKeyExponent = c.getExchangePublicKeyExponent( );
+
+                boost::shared_ptr< Marshaller::u1Array > pPublicKeyModulus = c.getExchangePublicKeyModulus( );
+
+                stPrefix = szUSER_KEYEXCHANGE_CERT_PREFIX; 
+
+                if( !uiKeySize ) {
+
+                    ucKeySpec = MiniDriverContainer::KEYSPEC_SIGNATURE;
+
+                    uiKeySize = c.getKeySignatureSizeBits( );
+
+                    pPublicKeyExponent = c.getSignaturePublicKeyExponent( );
+
+                    pPublicKeyModulus = c.getSignaturePublicKeyModulus( );
+
+                    stPrefix = szUSER_SIGNATURE_CERT_PREFIX;
+                }
+
+                Log::log( "Token::synchronizePublicCertificateAndKeyObjects - <%d> valid container", ucContainerIndex );
+
+                // Build the certificate file name associated to this container
+                stCertificateFileName = stPrefix + stContainerIndex;
+
+                // Locate the associated certificate into the MiniDriver file structure
+                bool bExistsMSCPFile = isFileExists( stCertificateFileName, filesMiniDriver );
+
+                //??? TO ??? si le fichier n'existe pas il faut supprimer le container
+
+                Log::log( "Token::synchronizePublicCertificateAndKeyObjects - check for <%s> - Exists in MSCP <%d>", stCertificateFileName.c_str( ), bExistsMSCPFile );
+
+                // A public PKCS11 certificate object must exist on cache and on card to represent this MiniDriver certificate
+                stObjectPKCS11 = g_stPrefixPublicObject + stCertificateFileName;
+
+                // Does this certificate also exist as a PKCS11 object ?
+                bool bExistsPKCS11Object = isFileExists( stObjectPKCS11, filesPKCS11 );
+
+                Log::log( "Token::synchronizePublicCertificateAndKeyObjects - check for <%s> - Exists in P11 <%d>", stObjectPKCS11.c_str( ), bExistsPKCS11Object );
+
+                if( bExistsMSCPFile ) { 
+
+                    // The associated certificate exists into the mscp directory
+
+                    if( bExistsPKCS11Object ) { 
+
+                        // The PCKS11 certificate object exists
+
+                        // Load the PKCS11 object from the already existing PKCS11 file
+                        try {
+
+                            createCertificateFromPKCS11ObjectFile( stObjectPKCS11, stCertificateFileName );
+
+                        } catch( ... ) {
+
+                            Log::log( "**************************************************** CASE #1 [P11 cert exists but not possible read] - <%s> <%s>", stObjectPKCS11.c_str( ), stCertificateFileName.c_str( ) );
+
+                            // Create the PKCS11 object from the MSCP file
+                            createCertificateFromMiniDriverFile( stCertificateFileName, ucContainerIndex, ucKeySpec ); 
+
+                            //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                        }
+
+                    } else { 
+
+                        // The PKCS11 file does not exist
+
+                        // Create the PKCS11 object from the MSCP file
+                        createCertificateFromMiniDriverFile( stCertificateFileName, ucContainerIndex, ucKeySpec );
+                    }
+
+                } else { 
+
+                    // The associated certificate does not exist into the mscp directory
+
+                    // If a old corresponding PKCS11 object exists then delete it
+                    if( bExistsPKCS11Object ) {
+
+                        Log::log( "**************************************************** CASE #2 [P11 cert exists but no associated KXC] - <%s> <%s>", stObjectPKCS11.c_str( ), stCertificateFileName.c_str( ) );
+
+                        // NO DELETE
+                        //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                    }
+                }
+
+                // Locate the associated PUBLIC key
+                // Build the public key file name associated to this container
+                stObjectPKCS11 = g_stPrefixPublicObject + g_stPrefixKeyPublic + stContainerIndex;
+
+                // Does this public key also exist as a PKCS11 object ?
+                bExistsPKCS11Object = isFileExists( stObjectPKCS11, filesPKCS11 );
+
+                if( bExistsPKCS11Object ) { 
+
+                    // The PCKS11 public key object exists
+                    // Create the PKCS11 object from the already existing PKCS11 file
+                    try {
+
+                        createPublicKeyFromPKCS11ObjectFile( stObjectPKCS11 );
+
+                    } catch( ... ) {
+
+                        Log::log( "**************************************************** CASE #3 [P11 pub key exists but no read possible] - <%s>", stObjectPKCS11.c_str( ) );
+
+                        createPublicKeyFromMiniDriverFile( stObjectPKCS11, ucContainerIndex, ucKeySpec, pPublicKeyExponent.get( ), pPublicKeyModulus.get( ) );
+
+                        //stObjectPKCS11 = g_stPrefixPublicObject + std::string( szUSER_SIGNATURE_CERT_PREFIX ) + stContainerIndex;
+                        //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                    }
+
+                } else { 
+
+                    // The PKCS11 public key object does not exist
+                    // Create the PKCS11 object from the MSCP key container
+                    createPublicKeyFromMiniDriverFile( stObjectPKCS11, ucContainerIndex, ucKeySpec, pPublicKeyExponent.get( ), pPublicKeyModulus.get( ) );
+                }
+
+            } else { 
+
+                // The container is empty
+                // Search for an old corresponding PKCS11 object to delete it
+                Log::log( "Token::synchronizePublicCertificateAndKeyObjects - <%d> empty container", ucContainerIndex );
+
+                //// Build the certificate file name associated to this container
+                //stObjectPKCS11 = g_stPrefixPublicObject + std::string( szUSER_SIGNATURE_CERT_PREFIX ) + stContainerIndex;
+                //bool bExistsPKCS11Object = isFileExists( stObjectPKCS11, filesPKCS11 );
+                //if( bExistsPKCS11Object ) {
+
+                //    // NO DELETE
+                //    //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                //    Log::log( "**************************************************** CASE #4.1 [P11 obj exists] - <%s>", stObjectPKCS11.c_str( ) );
+                //}
+
+                //stObjectPKCS11 = g_stPrefixPublicObject + std::string( szUSER_KEYEXCHANGE_CERT_PREFIX ) + stContainerIndex;
+                //bExistsPKCS11Object = isFileExists( stObjectPKCS11, filesPKCS11 );
+                //if( bExistsPKCS11Object ) {
+
+                //    // NO DELETE
+                //    //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                //    Log::log( "**************************************************** CASE #4.2 [P11 obj exists] - <%s>", stObjectPKCS11.c_str( ) );
+                //}
+
+                //stObjectPKCS11 = g_stPrefixPublicObject + g_stPrefixKeyPublic + stContainerIndex;
+                //bExistsPKCS11Object = isFileExists( stObjectPKCS11, filesPKCS11 );
+                //if( bExistsPKCS11Object ) {
+
+                //    // NO DELETE
+                //    //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                //    Log::log( "**************************************************** CASE #4.3 [P11 obj exists] - <%s>", stObjectPKCS11.c_str( ) );
+                //}
+
+                //stObjectPKCS11 = g_stPrefixPrivateObject + g_stPrefixKeyPrivate + stContainerIndex;
+                //bExistsPKCS11Object = isFileExists( stObjectPKCS11, filesPKCS11 );
+                //if( bExistsPKCS11Object ) {
+
+                //    // NO DELETE
+                //    //m_ObjectsToDelete.push_back( stObjectPKCS11 );
+                //    Log::log( "**************************************************** CASE #4.4 [P11 obj exists] - <%s>", stObjectPKCS11.c_str( ) );
+                //}
+            }
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::synchronizePublicCertificateAndKeyObjects", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::synchronizePublicCertificateAndKeyObjects" );
+    Log::end( "Token::synchronizePublicCertificateAndKeyObjects" );
+}
+
+
+/*
+*/
+void Token::synchronizePrivateKeyObjects( void ) {
+
+    Log::begin( "Token::synchronizePrivateKeyObjects" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        return;
+    }
+
+    try {
+
+        // Get all PKCS11 object files from the PKCS11 directory into the smart card
+        MiniDriverFiles::FILES_NAME filesPKCS11;
+
+        if( !m_bCreateDirectoryP11 ) {
+
+            try {
+
+                filesPKCS11 = m_Device->enumFiles( g_stPathPKCS11 );
+
+            } catch( ... ) {
+
+            }
+        }
+
+        // Get all certificate files from the smart card
+        MiniDriverFiles::FILES_NAME filesMiniDriver = m_Device->enumFiles( std::string( szBASE_CSP_DIR ) );
+
+        std::string stContainerIndex = "";
+        unsigned char ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+        unsigned int uiKeySize = 0;
+        std::string stPrefix = "";
+        std::string stCertificateFileName = "";
+        std::string stKeyFileName = "";
+        bool bExistsPKCS11Object = false;
+
+        // Explore each smart card key container
+        unsigned char ucContainerCount = m_Device->containerCount( );
+
+        for( unsigned char ucContainerIndex = 0 ; ucContainerIndex < ucContainerCount ; ++ucContainerIndex ) {
+
+            // Get the current container
+            MiniDriverContainer c = m_Device->containerGet( ucContainerIndex );
+
+            // Build the certificate file name associated to this container
+            stContainerIndex = "";
+            Util::toStringHex( ucContainerIndex, stContainerIndex );
+
+            // Locate the associated PRIVATE key
+            // Build the private key file name associated to this container
+            stKeyFileName = g_stPrefixPrivateObject + g_stPrefixKeyPrivate + stContainerIndex;
+
+            // Does this private key also exist as a PKCS11 object ?
+            bExistsPKCS11Object = isFileExists( stKeyFileName, filesPKCS11 );
+
+            // Only deal with valid containers
+            if( MiniDriverContainer::CMAPFILE_FLAG_EMPTY != c.getFlags( ) ) {
+
+                // Get the key information
+                ucKeySpec = MiniDriverContainer::KEYSPEC_EXCHANGE;
+
+                uiKeySize = c.getKeyExchangeSizeBits( );
+
+                boost::shared_ptr< Marshaller::u1Array > pPublicKeyExponent = c.getExchangePublicKeyExponent( );
+
+                boost::shared_ptr< Marshaller::u1Array > pPublicKeyModulus = c.getExchangePublicKeyModulus( );
+
+                stPrefix = std::string( szUSER_KEYEXCHANGE_CERT_PREFIX ); 
+
+                if( !uiKeySize ) {
+
+                    ucKeySpec = MiniDriverContainer::KEYSPEC_SIGNATURE;
+
+                    uiKeySize = c.getKeySignatureSizeBits( );
+
+                    pPublicKeyExponent = c.getSignaturePublicKeyExponent( );
+
+                    pPublicKeyModulus = c.getSignaturePublicKeyModulus( );
+
+                    stPrefix = std::string( szUSER_SIGNATURE_CERT_PREFIX );
+                } 
+
+                if( bExistsPKCS11Object ) { 
+
+                    // The PCKS11 key object exists
+                    // Create the PKCS11 object from the already existing PKCS11 file
+                    try {
+
+                        createPrivateKeyFromPKCS11ObjectFile( stKeyFileName );
+
+                    } catch( ... ) {
+
+                        // Create the PKCS11 object from the MSCP key container
+                        createPrivateKeyFromMiniDriverFile( stKeyFileName, ucContainerIndex, ucKeySpec, pPublicKeyExponent.get( ), pPublicKeyModulus.get( ) );
+                    }
+
+                } else { 
+
+                    // The PKCS11 private key object does not exist
+                    // Create the PKCS11 object from the MSCP key container
+                    createPrivateKeyFromMiniDriverFile( stKeyFileName, ucContainerIndex, ucKeySpec, pPublicKeyExponent.get( ), pPublicKeyModulus.get( ) );
+                }
+
+            } else { 
+
+                // The container is empty
+            }
+        }
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::synchronizePrivateKeyObjects", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::synchronizePrivateKeyObjects" );
+    Log::end( "Token::synchronizePrivateKeyObjects" );
+}
+
+
+/* Create the PKCS11 certifcate object associated to the MiniDriver certificate file
+*/
+void Token::createCertificateFromPKCS11ObjectFile( const std::string& a_CertificateFileP11, const std::string& a_CertificateFileMiniDriver ) {
+
+    Log::begin( "Token::createCertificateFromPKCS11ObjectFile" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // Read the file
+        Marshaller::u1Array* f = m_Device->readFile( g_stPathPKCS11, a_CertificateFileP11 );
+
+        // Construct the PKCS11 object attributes from the file
+        std::vector< unsigned char > attributes;
+
+        unsigned int l = f->GetLength( );
+
+        for( unsigned int u = 0 ; u < l ; ++u ) {
+
+            attributes.push_back( f->GetBuffer( )[ u ] );
+        }
+
+        // Create the PKCS11 object
+        X509PubKeyCertObject* o = new X509PubKeyCertObject( );
+
+        // Put the file content into the object
+        CK_ULONG idx = 0;
+        o->deserialize( attributes, &idx );
+
+        // Save the fileName in the object 
+        o->m_stFileName = a_CertificateFileP11;
+
+        o->m_stCertificateName = a_CertificateFileMiniDriver;
+
+        // Read the file
+        m_Device->readCertificate( a_CertificateFileMiniDriver, o->m_pValue );
+
+        if( o->m_pValue ) {
+
+            generateRootAndSmartCardLogonFlags( o->m_pValue, o->m_bIsRoot, o->_certCategory, o->m_bIsSmartCardLogon );
+
+            generatePublicKeyModulus( o->m_pValue, o->m_pModulus, o->_checkValue );
+        }
+
+        if( o->m_pModulus && ( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == o->m_ucContainerIndex ) ) {
+
+            searchContainerIndex( o->m_pModulus, o->m_ucContainerIndex, o->m_ucKeySpec );
+        }
+
+        // As the PKCS11 file exists on card, the PKCS11 object has just to be added to the list of the PKCS11 managed object list.
+        registerStorageObject( o );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::createCertificateFromPKCS11ObjectFile", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::createCertificateFromPKCS11ObjectFile" );
+    Log::end( "Token::createCertificateFromPKCS11ObjectFile" );
+}
+
+
+/* Create the PKCS11 certifcate object associated to the MiniDriver certificate file
+*/
+void Token::createCertificateFromMiniDriverFile( const std::string& a_CertificateFile, const unsigned char& a_ucIndex, const unsigned char& a_ucKeySpec ) {
+
+    Log::begin( "Token::createCertificateFromMiniDriverFile" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    // Create the PKCS11 object
+    X509PubKeyCertObject* o = new X509PubKeyCertObject( );
+
+    o->m_ucKeySpec = a_ucKeySpec;
+
+    o->m_ucContainerIndex = a_ucIndex;
+
+    o->m_bOffCardObject = true;
+
+    o->m_Token = CK_TRUE;
+
+    o->m_Private = CK_FALSE;
+
+    o->m_Modifiable = CK_TRUE;
+
+    // No PKCS#11 certificate name for an offcard object. There is only a MiniDriver certificate into the smart card
+    o->m_stFileName = ""; 
+
+    o->m_stCertificateName = a_CertificateFile;
+
+    try {
+
+        // Read the file
+        m_Device->readCertificate( a_CertificateFile, o->m_pValue );
+
+    } catch( MiniDriverException& x ) {
+
+        // Unable to read the on card certificate.
+        // The P11 object creation is skipped.
+        Log::error( "Token::createCertificateFromMiniDriverFile", "Unable to read the certificate" );
+
+        delete o;
+
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    // Get object attributes from the parsed certificate
+    generateDefaultAttributesCertificate( o );
+
+    // Register this PKCS11 object into the list of the PKCS11 managed objects
+    registerStorageObject( o );
+
+    t.stop( "Token::createCertificateFromMiniDriverFile" );
+    Log::end( "Token::createCertificateFromMiniDriverFile" );
+}
+
+
+/* Create the PKCS11 public key object associated to the PKCS11 public key file stored into the smart card
+*/
+void Token::createPublicKeyFromPKCS11ObjectFile( const std::string& a_PKCS11PublicKeyFile ) {
+
+    Log::begin( "Token::createPublicKeyFromPKCS11ObjectFile" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // Read the file
+        Marshaller::u1Array* f = m_Device->readFile( g_stPathPKCS11, a_PKCS11PublicKeyFile );
+
+        // Construct the PKCS11 object attributes from the file
+        std::vector< unsigned char > attributes;
+
+        unsigned int l = f->GetLength( );
+
+        for( unsigned int u = 0 ; u < l ; ++u ) {
+
+            attributes.push_back( f->GetBuffer( )[ u ] );
+        }
+
+        // Create the PKCS11 object
+        Pkcs11ObjectKeyPublicRSA* o = new Pkcs11ObjectKeyPublicRSA( );
+
+        // Put the file content into the object
+        CK_ULONG idx = 0;
+        o->deserialize( attributes, &idx );
+
+        // Save the fileName in the object 
+        o->m_stFileName = a_PKCS11PublicKeyFile;
+
+        if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == o->m_ucContainerIndex ) {
+
+            searchContainerIndex( o->m_pModulus, o->m_ucContainerIndex, o->m_ucKeySpec );
+        }
+
+        registerStorageObject( o );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::createPublicKeyFromPKCS11ObjectFile", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::createPublicKeyFromPKCS11ObjectFile" );
+    Log::end( "Token::createPublicKeyFromPKCS11ObjectFile" );
+}
+
+
+/* Create the PKCS11 public key object associated to the MiniDriver container
+*/
+void Token::createPublicKeyFromMiniDriverFile( const std::string& a_stKeyFileName, const unsigned char& a_ucIndex, const unsigned int& a_ucKeySpec, Marshaller::u1Array* a_pPublicKeyExponent, Marshaller::u1Array* a_pPublicKeyModulus ) {
+
+    Log::begin( "Token::createPublicKeyFromMiniDriverFile" );
+    Timer t;
+    t.start( );
+
+    // Create the PKCS11 object
+    Pkcs11ObjectKeyPublicRSA* o = new Pkcs11ObjectKeyPublicRSA( );
+
+    o->m_stFileName = ""; // No PKCS#11 key file into the smart card. This object is build for a off card usage using the information given by the container //a_stKeyFileName;
+
+    o->m_Token = CK_TRUE;
+
+    o->m_Private = CK_FALSE;
+
+    o->m_Modifiable = CK_TRUE;
+
+    o->m_ucContainerIndex = a_ucIndex;
+
+    o->m_ucKeySpec = (unsigned char)a_ucKeySpec;
+
+    o->m_bOffCardObject = true;
+
+    o->_wrap = CK_FALSE;
+
+    o->_trusted = CK_TRUE;
+
+    o->_derive = CK_FALSE;
+
+    o->_local = CK_FALSE;
+
+    o->_verifyRecover = CK_FALSE;
+
+    if( MiniDriverContainer::KEYSPEC_EXCHANGE == a_ucKeySpec ) {
+
+        o->_verify = CK_TRUE;
+
+        o->_encrypt = CK_TRUE;
+
+        if( m_Device ) {
+
+            if( !m_Device->containerIsImportedExchangeKey( a_ucIndex ) ) {
+
+                o->_local = CK_TRUE;
+            }
+        }
+
+    } else {
+
+        o->_verify = CK_TRUE;
+
+        o->_encrypt = CK_FALSE;
+
+        if( m_Device ) {
+
+            if( !m_Device->containerIsImportedSignatureKey( a_ucIndex ) ) {
+
+                o->_local = CK_TRUE;
+            }
+        }    
+    }
+
+    o->m_pPublicExponent.reset( new Marshaller::u1Array( a_pPublicKeyExponent->GetLength( ) ) );
+
+    o->m_pPublicExponent->SetBuffer( a_pPublicKeyExponent->GetBuffer( ) );
+
+    o->m_pModulus.reset( new Marshaller::u1Array( a_pPublicKeyModulus->GetLength( ) ) );
+
+    o->m_pModulus->SetBuffer( a_pPublicKeyModulus->GetBuffer( ) );
+
+    o->m_ulModulusBits = a_pPublicKeyModulus->GetLength( ) * 8;
+
+    generateDefaultAttributesKeyPublic( o );
+
+    registerStorageObject( o );
+
+    t.stop( "Token::createPublicKeyFromMiniDriverFile" );
+    Log::end( "Token::createPublicKeyFromMiniDriverFile" );
+}
+
+
+/* Create the PKCS11 public key object associated to the PKCS11 public key file stored into the smart card
+*/
+void Token::createPrivateKeyFromPKCS11ObjectFile( const std::string& a_PKCS11PrivateKeyFile ) {
+
+    Log::begin( "Token::createPrivateKeyFromPKCS11ObjectFile" );
+    Timer t;
+    t.start( );
+
+    if( !m_Device ) {
+
+        throw PKCS11Exception( CKR_TOKEN_NOT_PRESENT );
+    }
+
+    try {
+
+        // Read the file
+        Marshaller::u1Array* f = m_Device->readFile( g_stPathPKCS11, a_PKCS11PrivateKeyFile );
+
+        // Construct the PKCS11 object attributes from the file
+        std::vector< unsigned char > attributes;
+
+        unsigned int l = f->GetLength( );
+
+        for( unsigned int u = 0 ; u < l ; ++u ) {
+
+            attributes.push_back( f->GetBuffer( )[ u ] );
+        }
+
+        // Create the PKCS11 object
+        RSAPrivateKeyObject* o = new RSAPrivateKeyObject( );
+
+        // Put the file content into the object
+        CK_ULONG idx = 0;
+        o->deserialize( attributes, &idx );
+
+        // Save the fileName in the object 
+        o->m_stFileName = a_PKCS11PrivateKeyFile;
+
+        if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == o->m_ucContainerIndex ) {
+
+            searchContainerIndex( o->m_pModulus, o->m_ucContainerIndex, o->m_ucKeySpec );
+        }
+
+        // Compatibility with old P11
+        o->_checkValue = Util::MakeCheckValue( o->m_pModulus->GetBuffer( ), o->m_pModulus->GetLength( ) );
+
+        setContainerIndexToCertificate( o->m_pModulus, o->m_ucContainerIndex, o->m_ucKeySpec );
+
+        setContainerIndexToKeyPublic( o->m_pModulus, o->m_ucContainerIndex, o->m_ucKeySpec );
+
+        registerStorageObject( o );
+
+    } catch( MiniDriverException& x ) {
+
+        Log::error( "Token::createPrivateKeyFromPKCS11ObjectFile", "MiniDriverException" );
+        throw PKCS11Exception( checkException( x ) );
+    }
+
+    t.stop( "Token::createPrivateKeyFromPKCS11ObjectFile" );
+    Log::end( "Token::createPrivateKeyFromPKCS11ObjectFile" );
+}
+
+
+/* Create the PKCS11 public key object associated to the MiniDriver container
+*/
+void Token::createPrivateKeyFromMiniDriverFile( const std::string& a_stKeyFileName, const unsigned char& a_ucIndex, const unsigned int& a_ucKeySpec, Marshaller::u1Array* a_pPublicKeyExponent, Marshaller::u1Array* a_pPublicKeyModulus ) {
+
+    Log::begin( "Token::createPrivateKeyFromMiniDriverFile" );
+    Timer t;
+    t.start( );
+
+    // Create the PKCS11 object
+    RSAPrivateKeyObject* o = new RSAPrivateKeyObject( );
+
+    o->m_stFileName = ""; // No PKCS#11 key file into the smart card. This object is build for a off card usage using the information given by the container
+
+    o->m_Token = CK_TRUE;
+
+    o->m_Private = CK_TRUE;
+
+    o->m_Modifiable = CK_TRUE;
+
+    o->m_bOffCardObject = true;
+
+    o->m_ucKeySpec = (unsigned char)a_ucKeySpec;
+
+    o->_sensitive = CK_TRUE;
+
+    o->_signRecover = false;
+
+    o->_unwrap = CK_FALSE;
+
+    o->_extractable = false;
+
+    o->_alwaysSensitive = CK_TRUE;
+
+    o->_neverExtractable = CK_TRUE;
+
+    o->_wrapWithTrusted = false;
+
+    o->_alwaysAuthenticate = false;
+
+    o->_derive = false;
+
+    o->_local = CK_FALSE;
+
+    if( MiniDriverContainer::KEYSPEC_EXCHANGE == a_ucKeySpec ) {
+
+        o->_decrypt = true;
+
+        o->_sign = true;
+
+    } else {
+
+        o->_decrypt = false;
+
+        o->_sign = true;
+    }
+
+    o->m_ucContainerIndex = a_ucIndex;
+
+    o->m_pPublicExponent.reset( new Marshaller::u1Array( a_pPublicKeyExponent->GetLength( ) ) );
+    o->m_pPublicExponent->SetBuffer( a_pPublicKeyExponent->GetBuffer( ) );
+
+    o->m_pModulus.reset( new Marshaller::u1Array( a_pPublicKeyModulus->GetLength( ) ) );
+    o->m_pModulus->SetBuffer( a_pPublicKeyModulus->GetBuffer( ) );
+
+    //setDefaultAttributes( o, true );
+    generateDefaultAttributesKeyPrivate( o );
+
+    // Add the object into the cache
+    registerStorageObject( o );
+
+    t.stop( "Token::createPrivateKeyFromMiniDriverFile" );
+    Log::end( "Token::createPrivateKeyFromMiniDriverFile" );
+}
+
+
+/*
+*/
+CK_RV Token::checkException( MiniDriverException& x ) {
+
+    CK_RV rv = CKR_GENERAL_ERROR;
+
+    switch( x.getError( ) ) {
+
+    case SCARD_E_INVALID_PARAMETER:
+        rv = CKR_ARGUMENTS_BAD;
+        break;
+
+    case SCARD_E_UNEXPECTED:
+    case SCARD_F_INTERNAL_ERROR:
+        rv = CKR_FUNCTION_FAILED;
+        break;
+#ifdef WIN32
+    case SCARD_E_UNSUPPORTED_FEATURE:
+        rv = CKR_FUNCTION_NOT_SUPPORTED;
+        break;
+#endif
+    case SCARD_W_CARD_NOT_AUTHENTICATED:
+        rv = CKR_USER_NOT_LOGGED_IN;
+        break;
+
+    case SCARD_W_CHV_BLOCKED:
+        rv = CKR_PIN_LOCKED;
+        break;
+
+    case SCARD_W_WRONG_CHV:
+        rv = CKR_PIN_INCORRECT;
+        break;
+
+    case SCARD_E_INVALID_CHV:
+        rv = CKR_PIN_INVALID;
+        break;
+
+    case SCARD_E_NO_SMARTCARD:
+        rv = CKR_DEVICE_REMOVED;
+        break;
+
+    case SCARD_E_TIMEOUT:
+    case SCARD_W_CANCELLED_BY_USER:
+    case SCARD_E_CANCELLED:
+        rv = CKR_FUNCTION_CANCELED;
+        break;
+
+    case SCARD_E_NO_MEMORY:
+    case SCARD_E_DIR_NOT_FOUND:
+    case SCARD_E_FILE_NOT_FOUND:
+    case SCARD_E_CERTIFICATE_UNAVAILABLE:
+    case SCARD_E_NO_ACCESS:
+        rv = CKR_DEVICE_MEMORY;
+        break;
+
+    default:
+        rv = CKR_GENERAL_ERROR;
+        break;
+    }
+
+    return rv;
+}
+
+
+/*
+*/
+Marshaller::u1Array* Token::computeSHA1( const unsigned char* a_pData, const size_t& a_uiLength ) {
+
+    CSHA1 sha1;
+
+    Marshaller::u1Array* pHash = new Marshaller::u1Array( SHA1_HASH_LENGTH );
+
+    sha1.hashCore( (unsigned char*)a_pData, 0, a_uiLength );
+
+    sha1.hashFinal( pHash->GetBuffer( ) );
+
+    return pHash;
+}
+
+
+/*
+*/
+unsigned char Token::computeIndex( const std::string& a_stFileName ) {
+
+    if( a_stFileName.length( ) < 2 ) {
+     
+        return 0xFF;
+    }
+
+    // Get the container index set into the file name
+    unsigned char h1 = a_stFileName[ a_stFileName.length( ) - 2 ];
+    unsigned char h2 = a_stFileName[ a_stFileName.length( ) - 1 ];
+
+    unsigned char a = ( ( h1 >= 0x41 ) ? ( h1 - 0x41 + 10 ) : ( h1 - 0x30 ) ) * 16;
+    unsigned char b = ( h2 >= 0x41 ) ? ( h2 - 0x41 + 10 ) : ( h2 - 0x30 );
+
+    unsigned char ucKeyContainerIndexInFileName = a + b;
+
+    return ucKeyContainerIndexInFileName;
+}
+
+
+/*
+*/
+void Token::generateDefaultAttributesCertificate( X509PubKeyCertObject* a_pObject ) {
+
+    Log::begin( "Token::setDefaultAttributesCertificate" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject && !a_pObject->m_pValue ) {
+
+        return;
+    }
+
+    // Parse the certifcate value to extract the PKCS11 attribute values not already set
+    try {
+
+        // Generate the root and smart card logon flags
+        generateRootAndSmartCardLogonFlags( a_pObject->m_pValue, a_pObject->m_bIsRoot, a_pObject->_certCategory, a_pObject->m_bIsSmartCardLogon );
+
+        // Generate the serial number
+        generateSerialNumber( a_pObject->m_pValue, a_pObject->m_pSerialNumber );
+
+        // Generate the issuer
+        generateIssuer( a_pObject->m_pValue, a_pObject->m_pIssuer );
+
+        // Get the certificate public key modulus
+        generatePublicKeyModulus( a_pObject->m_pValue, a_pObject->m_pModulus, a_pObject->_checkValue );
+
+        // Generate the certicate label
+        generateLabel( a_pObject->m_pModulus, a_pObject->m_pLabel );
+
+        // Generate the ID
+        generateID( a_pObject->m_pModulus, a_pObject->m_pID );
+
+        // Generate the subject
+        generateSubject( a_pObject->m_pValue, a_pObject->m_pSubject );
+    
+    } catch( ... ) {
+
+        // If a parsing error occurs then these attributes can't be set.
+    }
+}
+
+
+/*
+*/
+void Token::generateDefaultAttributesKeyPublic( Pkcs11ObjectKeyPublicRSA* a_pObject ) {
+
+    Log::begin( "Token::generateDefaultAttributesKeyPublic" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject && !a_pObject->m_pModulus ) {
+
+        return;
+    }
+
+    int l = a_pObject->m_pModulus->GetLength( );
+
+    unsigned char* p = a_pObject->m_pModulus->GetBuffer( );
+
+    // Search for a private key using the same public key exponent to set the same container index
+    if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_pObject->m_ucContainerIndex ) {
+
+        BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+            if( CKO_PRIVATE_KEY == obj->second->getClass( ) ) {
+
+                RSAPrivateKeyObject* objPrivateKey = (RSAPrivateKeyObject*) obj->second;
+
+                if( 0 == memcmp( objPrivateKey->m_pModulus->GetBuffer( ), p, l ) ) {
+
+                    // Set the same CKA_ID
+                    if( objPrivateKey->m_pID.get( ) ) {
+
+                        a_pObject->m_pID.reset( new Marshaller::u1Array( *( objPrivateKey->m_pID.get( ) ) ) );
+                    }
+
+                    // Set the same CKA_LABEL
+                    if( objPrivateKey->m_pLabel.get( ) ) {
+
+                        a_pObject->m_pLabel.reset( new Marshaller::u1Array( *( objPrivateKey->m_pLabel.get( ) ) ) );
+                    }
+
+                    // Set the same CKA_SUBJECT
+                    if( objPrivateKey->m_pSubject.get( ) ) {
+
+                        a_pObject->m_pSubject.reset( new Marshaller::u1Array( *( objPrivateKey->m_pSubject.get( ) ) ) );
+                    }
+
+                    a_pObject->m_ucContainerIndex = objPrivateKey->m_ucContainerIndex;
+
+                    a_pObject->m_ucKeySpec = objPrivateKey->m_ucKeySpec;
+
+                    break;
+                }
+            }
+        }
+    }
+
+    // If no private key has been found then generate the attributes
+
+    // Get the certificate subject if it is still empty
+    if( !a_pObject->m_pSubject.get( ) ) {
+
+        BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+            if( CKO_CERTIFICATE == obj->second->getClass( ) ) {
+
+                X509PubKeyCertObject* objCertificate = (X509PubKeyCertObject*) obj->second;
+
+                if( !objCertificate && !objCertificate->m_pValue ) {
+
+                    continue;
+                }
+
+                X509Cert x509cert( objCertificate->m_pValue->GetBuffer( ), objCertificate->m_pValue->GetLength( ) );
+
+                // Get the certificate public key modulus
+                BEROctet::Blob modulus = x509cert.Modulus( );
+
+                Marshaller::u1Array m( modulus.size( ) );
+
+                m.SetBuffer( modulus.data( ) );
+
+                // Check if the both certificate and public key share the same modulus
+                if( 0 == memcmp( m.GetBuffer( ), p, l ) ) {
+
+                    if( objCertificate->m_pSubject.get( ) ) {
+
+                        // Copyt the certificate subject
+                        a_pObject->m_pSubject.reset( new Marshaller::u1Array( *( objCertificate->m_pSubject.get( ) ) ) );
+
+                    } else {
+
+                        // Generate the subject
+                        BEROctet::Blob sb( x509cert.Subject( ) );
+
+                        a_pObject->m_pSubject.reset( new Marshaller::u1Array( static_cast< s4 >( sb.size( ) ) ) );
+
+                        a_pObject->m_pSubject->SetBuffer( const_cast< unsigned char* >( sb.data( ) ) );
+                    }
+
+                    // By the way copy the certificate ID
+                    if( objCertificate->m_pID.get( ) && !a_pObject->m_pID.get( ) ) {
+
+                        a_pObject->m_pID.reset( new Marshaller::u1Array( *( objCertificate->m_pID.get( ) ) ) );
+                    }
+
+                    if( objCertificate->m_pLabel.get( ) && !a_pObject->m_pLabel.get( ) ) {
+
+                        a_pObject->m_pLabel.reset( new Marshaller::u1Array( *( objCertificate->m_pLabel.get( ) ) ) );
+                    }
+
+                    break;
+                }
+            }
+        }
+    }
+
+    // Generate the id 
+    if( !a_pObject->m_pID.get( ) ) {
+
+        generateID( a_pObject->m_pModulus, a_pObject->m_pID );
+    }
+
+    // Generate the label from the public key modulus
+    if( !a_pObject->m_pLabel.get( ) ) {
+
+        generateLabel( a_pObject->m_pModulus, a_pObject->m_pLabel );
+    }
+
+    t.stop( "Token::generateDefaultAttributesKeyPublic" );
+    Log::end( "Token::generateDefaultAttributesKeyPublic" );
+}
+
+
+/*
+*/
+void Token::generateDefaultAttributesKeyPrivate( RSAPrivateKeyObject* a_pObject ) {
+
+    Log::begin( "Token::generateDefaultAttributesKeyPublic" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject && !a_pObject->m_pModulus ) {
+
+        return;
+    }
+
+    unsigned int l = a_pObject->m_pModulus->GetLength( );
+
+    unsigned char* p = a_pObject->m_pModulus->GetBuffer( );
+
+    // Compatibility with old P11
+    a_pObject->_checkValue = Util::MakeCheckValue( p, l );
+
+    // Generate a default id from the public key modulus if not found in previous certificate or public key search
+    generateID( a_pObject->m_pModulus, a_pObject->m_pID );
+
+    // Generate a default label from the public key modulus if not found in previous certificate or public key search
+    generateLabel( a_pObject->m_pModulus, a_pObject->m_pLabel );
+
+    // Give the same container index of the private key to the associated certificate
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+        if( CKO_CERTIFICATE == obj->second->getClass( ) ) {
+
+            X509PubKeyCertObject* objCertificate = (X509PubKeyCertObject*) obj->second;
+
+            if( objCertificate->m_pValue.get( ) ) {
+
+                X509Cert x509cert( objCertificate->m_pValue->GetBuffer( ), objCertificate->m_pValue->GetLength( ) );
+
+                // Get the certificate public key modulus
+                BEROctet::Blob modulus = x509cert.Modulus( );
+
+                Marshaller::u1Array m( modulus.size( ) );
+
+                m.SetBuffer( modulus.data( ) );
+
+                if( 0 == memcmp( m.GetBuffer( ), p, l ) ) {
+
+                    // Give the same container index of the private key to the certificate
+                    objCertificate->m_ucContainerIndex = a_pObject->m_ucContainerIndex;
+
+                    objCertificate->m_ucKeySpec = a_pObject->m_ucKeySpec;
+
+                    if( objCertificate->m_pSubject.get( ) ) {
+
+                        a_pObject->m_pSubject.reset( new Marshaller::u1Array( objCertificate->m_pSubject->GetLength( ) ) );
+
+                        a_pObject->m_pSubject->SetBuffer( objCertificate->m_pSubject->GetBuffer( ) );
+
+                    } else {
+
+                        // Get the certificate subject
+                        BEROctet::Blob sb( x509cert.Subject( ) );
+
+                        a_pObject->m_pSubject.reset( new Marshaller::u1Array( static_cast< s4 >( sb.size( ) ) ) );
+
+                        a_pObject->m_pSubject->SetBuffer( const_cast< unsigned char* >( sb.data( ) ) );
+                    }
+
+                    break;
+                }
+            }
+        }
+    }
+
+    //// Give the same container index of the private key to the associated public key
+    //BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+    //    if( CKO_PUBLIC_KEY == obj->second->getClass( ) ) {
+
+    //        Pkcs11ObjectKeyPublicRSA* objPublicKey = (Pkcs11ObjectKeyPublicRSA*) obj->second;
+
+    //        if( 0 == memcmp( objPublicKey->m_pModulus->GetBuffer( ), p, l ) ) {
+
+    //            // Give the same container index of the private key to the certificate
+    //            objPublicKey->m_ucContainerIndex = o->m_ucContainerIndex;
+
+    //            objPublicKey->m_ucKeySpec = o->m_ucKeySpec;
+
+    //            // By the way, if the previous search for a certificate failed
+    //            // try to get the same CKA_ID, CKA_LABEL and CKA_SUBJECT as the associated public key
+    //            //if( /*o->m_bOffCardObject &&*/ objPublicKey->m_pSubject.get( ) && !o->m_pSubject.get( ) ) {
+
+    //            //    o->m_pSubject.reset( new Marshaller::u1Array( objPublicKey->m_pSubject->GetLength( ) ) );
+
+    //            //    o->m_pSubject->SetBuffer( objPublicKey->m_pSubject->GetBuffer( ) );
+    //            //}
+
+    //            if( /*o->m_bOffCardObject &&*/ objPublicKey->m_pID.get( ) && !o->m_pID.get( ) ) {
+
+    //                o->m_pID.reset( new Marshaller::u1Array( objPublicKey->m_pID->GetLength( ) ) );
+
+    //                o->m_pID->SetBuffer( objPublicKey->m_pID->GetBuffer( ) );
+    //            }
+
+    //            if( /*o->m_bOffCardObject &&*/ objPublicKey->m_pLabel.get( ) && !o->m_pLabel.get( ) ) {
+
+    //                o->m_pLabel.reset( new Marshaller::u1Array( objPublicKey->m_pLabel->GetLength( ) ) );
+
+    //                o->m_pLabel->SetBuffer( objPublicKey->m_pLabel->GetBuffer( ) );
+    //            }
+
+    //            break;
+    //        }
+    //    }
+    //}
+
+    t.stop( "Token::generateDefaultAttributesKeyPublic" );
+    Log::end( "Token::generateDefaultAttributesKeyPublic" );
+}
+
+
+/* Generate a default label from the public key modulus
+*/
+void Token::generateLabel( boost::shared_ptr< Marshaller::u1Array>& a_pModulus, boost::shared_ptr< Marshaller::u1Array>& a_pLabel ) {
+
+    if( !a_pModulus ) {
+
+        return;
+    }
+
+    std::string stLabel = CAttributedCertificate::DerivedUniqueName( a_pModulus->GetBuffer( ), a_pModulus->GetLength( ) );
+
+    a_pLabel.reset( new Marshaller::u1Array( stLabel.size( ) ) );
+
+    a_pLabel->SetBuffer( reinterpret_cast< const unsigned char* >( stLabel.c_str( ) ) );
+
+    // Generate the certificate label from the certificate value
+    //std::string stLabel;
+    //std::vector<std::string> vs = x509cert.UTF8SubjectCommonName( );
+    //BOOST_FOREACH( const std::string& s, vs ) {
+    //    if( !stLabel.empty( ) ) {
+    //        stLabel += " ";
+    //    }
+    //    stLabel += s;
+    //}
+    //a_pObject->m_pLabel.reset( new Marshaller::u1Array( stLabel.size( ) ) );
+    //a_pObject->m_pLabel->SetBuffer( reinterpret_cast< const unsigned char* >( stLabel.c_str( ) ) );
+}
+
+
+/* Generate a default id from the public key modulus
+*/
+void Token::generateID( boost::shared_ptr< Marshaller::u1Array>& a_pModulus, boost::shared_ptr< Marshaller::u1Array>& a_pID ) {
+
+    if( !a_pModulus ) {
+
+        return;
+    }
+
+    a_pID.reset( computeSHA1( a_pModulus->GetBuffer( ), a_pModulus->GetLength( ) ) );
+}
+
+
+/* Get the certificate serial number
+*/
+void Token::generateSerialNumber( boost::shared_ptr< Marshaller::u1Array>& a_pCertificateValue, boost::shared_ptr< Marshaller::u1Array>& a_pSerialNumber ) {
+
+    X509Cert x509cert( a_pCertificateValue->GetBuffer( ), a_pCertificateValue->GetLength( ) );
+
+    BEROctet::Blob b( x509cert.SerialNumber( ) );
+
+    a_pSerialNumber.reset( new Marshaller::u1Array( static_cast< s4 >( b.size( ) ) ) );
+
+    a_pSerialNumber->SetBuffer( const_cast< unsigned char* >( b.data( ) ) );
+}
+
+
+/* Get the certificate issuer from the certifcate value
+*/
+void Token::generateIssuer( boost::shared_ptr< Marshaller::u1Array>& a_pCertificateValue, boost::shared_ptr< Marshaller::u1Array>& a_pIssuer ) {
+
+    X509Cert x509cert( a_pCertificateValue->GetBuffer( ), a_pCertificateValue->GetLength( ) );
+
+    BEROctet::Blob b( x509cert.Issuer( ) );
+
+    a_pIssuer.reset( new Marshaller::u1Array( static_cast< s4 >( b.size( ) ) ) );
+
+    a_pIssuer->SetBuffer( const_cast< unsigned char* >( b.data( ) ) );
+}
+
+
+/* Get the certificate subject from the certifcate value
+*/
+void Token::generateSubject( boost::shared_ptr< Marshaller::u1Array>& a_pCertificateValue, boost::shared_ptr< Marshaller::u1Array>& a_pSubject ) {
+
+    X509Cert x509cert( a_pCertificateValue->GetBuffer( ), a_pCertificateValue->GetLength( ) );
+
+    BEROctet::Blob b( x509cert.Subject( ) );
+
+    a_pSubject.reset( new Marshaller::u1Array( static_cast< s4 >( b.size( ) ) ) );
+
+    a_pSubject->SetBuffer( const_cast< unsigned char* >( b.data( ) ) );
+}
+
+
+/* Get the public key modulus
+*/
+void Token::generatePublicKeyModulus( boost::shared_ptr< Marshaller::u1Array>& a_pCertificateValue, boost::shared_ptr< Marshaller::u1Array>& a_pModulus, u8& a_u8CheckValue ) {
+
+    X509Cert x509cert( a_pCertificateValue->GetBuffer( ), a_pCertificateValue->GetLength( ) );
+
+    BEROctet::Blob modulus = x509cert.Modulus( );
+
+    a_pModulus.reset( new Marshaller::u1Array( modulus.size( ) ) );
+
+    a_pModulus->SetBuffer( modulus.data( ) );
+
+    // Compatibility with old P11
+    a_u8CheckValue = Util::MakeCheckValue( modulus.data( ), static_cast< unsigned int >( modulus.size( ) ) );
+}
+
+
+/* Get the public key modulus
+*/
+void Token::generateRootAndSmartCardLogonFlags( boost::shared_ptr< Marshaller::u1Array>& a_pCertificateValue, bool& a_bIsRoot, unsigned long& a_ulCertificateCategory, bool& a_bIsSmartCardLogon ) {
+
+    X509Cert x509cert( a_pCertificateValue->GetBuffer( ), a_pCertificateValue->GetLength( ) );
+
+    a_bIsRoot = ( x509cert.IsCACert( ) || x509cert.IsRootCert( ) );
+
+    // CKA_CERTIFICATE_CATEGORY attribute set to "authority" (2) is the certificate is a root or CA one
+    a_ulCertificateCategory = a_bIsRoot ? 2 : 1; 
+
+    // Look for the Windows Smart Card Logon OID
+    a_bIsSmartCardLogon = x509cert.isSmartCardLogon( );
+    //Log::log( "SmartCardLogon <%d>", a_pObject->m_bIsSmartCardLogon );
+}
+
+
+/* Search for a private key using the same public key exponent to set the same container index
+*/
+void Token::searchContainerIndex( boost::shared_ptr< Marshaller::u1Array>& a_pModulus, unsigned char& a_ucContainerIndex, unsigned char& a_ucKeySpec ) {
+
+    if( !a_pModulus ) {
+
+        return;
+    }
+
+    int l = a_pModulus->GetLength( );
+
+    unsigned char* p = a_pModulus->GetBuffer( );
+
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+        if( CKO_PRIVATE_KEY == obj->second->getClass( ) ) {
+
+            RSAPrivateKeyObject* objPrivateKey = (RSAPrivateKeyObject*) obj->second;
+
+            if( 0 == memcmp( objPrivateKey->m_pModulus->GetBuffer( ), p, l ) ) {
+
+                a_ucContainerIndex = objPrivateKey->m_ucContainerIndex;
+
+                a_ucKeySpec = objPrivateKey->m_ucKeySpec;
+            }
+
+            break;
+        }
+    }
+}
+
+
+/*
+*/
+void Token::setDefaultAttributesCertificate( X509PubKeyCertObject* a_pObject ) {
+
+    Log::begin( "Token::setDefaultAttributesCertificate" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject ) {
+
+        return;
+    }
+
+    if( !a_pObject->m_pValue ) {
+
+        return;
+    }
+
+    // Parse the certifcate value to extract the PKCS11 attribute values not already set
+    try {
+
+        generateRootAndSmartCardLogonFlags( a_pObject->m_pValue, a_pObject->m_bIsRoot, a_pObject->_certCategory, a_pObject->m_bIsSmartCardLogon );
+
+        generatePublicKeyModulus( a_pObject->m_pValue, a_pObject->m_pModulus, a_pObject->_checkValue );
+
+        if( a_pObject->m_pModulus ) {
+
+            if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_pObject->m_ucContainerIndex ) {
+
+                searchContainerIndex( a_pObject->m_pModulus, a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec );
+            }
+
+            if( !a_pObject->m_pLabel ) {
+
+                generateLabel( a_pObject->m_pModulus, a_pObject->m_pLabel );
+            }
+
+            if( !a_pObject->m_pID ) {
+
+                generateID( a_pObject->m_pModulus, a_pObject->m_pID );
+            }
+
+            if( !a_pObject->m_pSubject ) {
+
+                generateSubject( a_pObject->m_pValue, a_pObject->m_pSubject );
+            }
+
+            if( !a_pObject->m_pIssuer ) {
+
+                generateIssuer( a_pObject->m_pValue, a_pObject->m_pIssuer );
+            }
+
+            if( !a_pObject->m_pSerialNumber ) {
+
+                generateSerialNumber( a_pObject->m_pValue, a_pObject->m_pSerialNumber );
+            }
+        }
+
+    } catch( ... ) {
+
+    }
+
+    t.stop( "Token::setDefaultAttributesCertificate" );
+    Log::end( "Token::setDefaultAttributesCertificate" );
+}
+
+
+/*
+*/
+void Token::setDefaultAttributesKeyPublic( Pkcs11ObjectKeyPublicRSA* a_pObject ) {
+
+    Log::begin( "Token::setDefaultAttributesKeyPublic" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject ) {
+
+        return;
+    }
+
+    if( !a_pObject->m_pModulus ) {
+
+        return;
+    }
+
+    try {
+
+        if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_pObject->m_ucContainerIndex ) {
+
+            searchContainerIndex( a_pObject->m_pModulus, a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec );
+        }
+
+        if( !a_pObject->m_pLabel ) {
+
+            generateLabel( a_pObject->m_pModulus, a_pObject->m_pLabel );
+        }
+
+        if( !a_pObject->m_pID ) {
+
+            generateID( a_pObject->m_pModulus, a_pObject->m_pID );
+        }
+
+    } catch( ... ) {
+
+    }
+
+    t.stop( "Token::setDefaultAttributesKeyPublic" );
+    Log::end( "Token::setDefaultAttributesKeyPublic" );
+}
+
+
+/*
+*/
+void Token::setDefaultAttributesKeyPrivate( RSAPrivateKeyObject* a_pObject ) {
+
+    Log::begin( "Token::setDefaultAttributesKeyPrivate" );
+    Timer t;
+    t.start( );
+
+    if( !a_pObject ) {
+
+        return;
+    }
+
+    if( !a_pObject->m_pModulus ) {
+
+        return;
+    }
+
+    try {
+
+        if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == a_pObject->m_ucContainerIndex ) {
+
+            searchContainerIndex( a_pObject->m_pModulus, a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec );
+        }
+
+        // Compatibility with old P11
+        unsigned char* p = a_pObject->m_pModulus->GetBuffer( );
+        unsigned int l = a_pObject->m_pModulus->GetLength( );
+
+        a_pObject->_checkValue = Util::MakeCheckValue( p, l );
+
+        setContainerIndexToCertificate( a_pObject->m_pModulus, a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec );
+
+        setContainerIndexToKeyPublic( a_pObject->m_pModulus, a_pObject->m_ucContainerIndex, a_pObject->m_ucKeySpec );
+
+        if( !a_pObject->m_pLabel ) {
+
+            generateLabel( a_pObject->m_pModulus, a_pObject->m_pLabel );
+        }
+
+        if( !a_pObject->m_pID ) {
+
+            generateID( a_pObject->m_pModulus, a_pObject->m_pID );
+        }
+
+    } catch( ... ) {
+
+    }
+
+    t.stop( "Token::setDefaultAttributesKeyPrivate" );
+    Log::end( "Token::setDefaultAttributesKeyPrivate" );
+}
+
+
+/*
+*/
+void Token::setContainerIndexToCertificate( boost::shared_ptr< Marshaller::u1Array>& a_pModulus, const unsigned char& a_ucContainerIndex, const unsigned char& a_ucKeySpec ) {
+
+    Log::begin( "Token::setContainerIndexToCertificate" );
+    Timer t;
+    t.start( );
+
+    if( !a_pModulus ) {
+
+        return;
+    }
+
+    unsigned char* p = a_pModulus->GetBuffer( );
+
+    unsigned int l = a_pModulus->GetLength( );
+
+    // Give the same container index of the private key to the associated certificate
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+        if( CKO_CERTIFICATE == obj->second->getClass( ) ) {
+
+            X509PubKeyCertObject* objCertificate = (X509PubKeyCertObject*) obj->second;
+
+            if( objCertificate->m_pValue.get( ) ) {
+
+                X509Cert x509cert( objCertificate->m_pValue->GetBuffer( ), objCertificate->m_pValue->GetLength( ) );
+
+                // Get the certificate public key modulus
+                BEROctet::Blob modulus = x509cert.Modulus( );
+
+                Marshaller::u1Array m( modulus.size( ) );
+
+                m.SetBuffer( modulus.data( ) );
+
+                if( 0 == memcmp( m.GetBuffer( ), p, l ) ) {
+
+                    // Give the same container index of the private key to the certificate
+                    objCertificate->m_ucContainerIndex = a_ucContainerIndex;
+
+                    objCertificate->m_ucKeySpec = a_ucKeySpec;
+
+                    break;
+                }
+            }
+        }
+    }
+
+    t.stop( "Token::setContainerIndexToCertificate" );
+    Log::begin( "Token::setContainerIndexToCertificate" );
+}
+
+
+/* Search for an associated public key created before the private key to rename it properly using the index of the created container
+*/
+void Token::setContainerIndexToKeyPublic( boost::shared_ptr< Marshaller::u1Array>& a_pModulus, const unsigned char& a_ucContainerIndex, const unsigned char& a_ucKeySpec ) {
+
+    Log::begin( "Token::setContainerIndexToKeyPublic" );
+    Timer t;
+    t.start( );
+
+    if( !a_pModulus ) {
+
+        return;
+    }
+
+    unsigned char* p = a_pModulus->GetBuffer( );
+
+    unsigned int l = a_pModulus->GetLength( );
+
+    // Give the same container index of the private key to the associated public key
+    BOOST_FOREACH( const TOKEN_OBJECTS::value_type& obj, m_Objects ) {
+
+        // Search for a PKCS11 public key object
+        if( CKO_PUBLIC_KEY == obj->second->getClass( ) ) {
+
+            Pkcs11ObjectKeyPublicRSA* objPublicKey = (Pkcs11ObjectKeyPublicRSA*) obj->second;
+
+           // When the public key is created first the index is not set
+            if( MiniDriverContainerMapFile::CONTAINER_INDEX_INVALID == objPublicKey->m_ucContainerIndex ) {
+
+                // Search for the same modulus as the private key
+                if( 0 == memcmp( objPublicKey->m_pModulus->GetBuffer( ), p, l ) ) {
+
+                    // Delete the old object
+                    deleteObjectFromCard( objPublicKey );
+
+                    // Compute a new name regardiong the new index for the public key
+                    std::string stNewName = objPublicKey->m_stFileName.substr( 0, objPublicKey->m_stFileName.length( ) - 2 );
+                    Util::toStringHex( a_ucContainerIndex, stNewName );
+                    
+                    // Update the inner object's properties
+                    objPublicKey->m_stFileName = stNewName;
+
+                    objPublicKey->m_ucContainerIndex = a_ucContainerIndex;
+
+                    // Save the new object
+                    writeObject( objPublicKey );
+
+                    break;
+                }
+            }
+        }
+    }
+
+    t.stop( "Token::setContainerIndexToKeyPublic" );
+    Log::end( "Token::setContainerIndexToKeyPublic" );
+}

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/Token.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Token.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Token.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,309 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_TOKEN__
+#define __GEMALTO_TOKEN__
+
+
+#include <boost/foreach.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/ptr_container/ptr_set.hpp>
+#include <boost/ptr_container/ptr_map.hpp>
+#include <boost/random.hpp>
+#include <string>
+#include <vector>
+#include "MiniDriver.hpp"
+#include "Device.hpp"
+#include "Session.hpp"
+#include "Pkcs11ObjectStorage.hpp"
+#include "Pkcs11ObjectKeyPrivateRSA.hpp"
+#include "Pkcs11ObjectCertificateX509PublicKey.hpp"
+#include "MiniDriverException.hpp"
+#include "Pkcs11ObjectKeyPublicRSA.hpp"
+
+class Slot;
+
+
+/*
+*/
+class Token {
+
+public:
+
+    typedef boost::ptr_map< CK_OBJECT_HANDLE, StorageObject > TOKEN_OBJECTS;
+
+    static const unsigned long FLAG_OBJECT_TOKEN = 0x00000000;
+
+    static const unsigned long MASK_OBJECT_TOKEN = 0x00FF0000;
+
+    Token( Slot*, Device* );
+
+    inline virtual ~Token( ) { clear( ); }
+
+
+    void login( const CK_ULONG&, Marshaller::u1Array* );
+
+    void logout( void );
+
+    void generateRandom( CK_BYTE_PTR, const CK_ULONG& );
+
+    void addObject( StorageObject*, CK_OBJECT_HANDLE_PTR, const bool& a_bRegisterObject = true );
+
+    void addObjectPrivateKey( RSAPrivateKeyObject*, CK_OBJECT_HANDLE_PTR );
+
+    void addObjectCertificate( X509PubKeyCertObject*, CK_OBJECT_HANDLE_PTR );
+
+    void addObjectPublicKey( Pkcs11ObjectKeyPublicRSA*, CK_OBJECT_HANDLE_PTR );
+
+    void deleteObject( const CK_OBJECT_HANDLE& );
+
+    // === TEST
+    //inline void findObjectsInit( void ) { m_TokenObjectsReturnedInSearch.clear( ); synchronizeIfSmartCardContentHasChanged( ); }
+    inline void findObjectsInit( void ) { m_TokenObjectsReturnedInSearch.clear( ); try{ synchronizeIfSmartCardContentHasChanged( ); } catch( ... ){} }
+
+    void findObjects( Session*, CK_OBJECT_HANDLE_PTR, const CK_ULONG&, CK_ULONG_PTR );
+
+    void getAttributeValue( const CK_OBJECT_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+    void setAttributeValue( const CK_OBJECT_HANDLE&, CK_ATTRIBUTE_PTR, const CK_ULONG& );
+
+    void generateKeyPair( Pkcs11ObjectKeyPublicRSA*, RSAPrivateKeyObject*, CK_OBJECT_HANDLE_PTR , CK_OBJECT_HANDLE_PTR );
+
+    StorageObject* getObject( const CK_OBJECT_HANDLE& );
+
+    void sign( const RSAPrivateKeyObject*, Marshaller::u1Array*, const CK_ULONG&, CK_BYTE_PTR );
+
+    void decrypt( const StorageObject*, Marshaller::u1Array*, const CK_ULONG&, CK_BYTE_PTR , CK_ULONG_PTR );
+
+    void verify( const StorageObject*, Marshaller::u1Array*, const CK_ULONG&, Marshaller::u1Array* );
+
+    void encrypt( const StorageObject*, Marshaller::u1Array*, const CK_ULONG&,CK_BYTE_PTR );
+
+    void initToken( Marshaller::u1Array*, Marshaller::u1Array* );
+
+    void initPIN( Marshaller::u1Array*, Marshaller::u1Array* );
+
+    void setPIN( Marshaller::u1Array*, Marshaller::u1Array* );
+
+    inline const CK_ULONG& getLoggedRole( void ) { return m_RoleLogged; }
+
+    inline void setLoggedRole( const CK_ULONG& r ) { m_RoleLogged = r; }
+
+    inline CK_TOKEN_INFO& getTokenInfo( void ) { return m_TokenInfo; }
+
+    inline bool isToken( const CK_OBJECT_HANDLE& a_hObject ) { return ( ( a_hObject & MASK_OBJECT_TOKEN ) == FLAG_OBJECT_TOKEN ); }
+
+    bool synchronizeIfSmartCardContentHasChanged( void );
+        
+    static CK_RV checkException( MiniDriverException& );
+
+
+private:
+
+    typedef std::vector< StorageObject* > OBJECTS;
+
+    std::string g_stPathPKCS11;
+
+    std::string g_stPathTokenInfo;
+
+    std::string g_stPrefixData;
+
+    std::string g_stPrefixKeyPublic;
+
+    std::string g_stPrefixKeyPrivate;
+
+    std::string g_stPrefixPublicObject;
+
+    std::string g_stPrefixPrivateObject;
+
+    std::string g_stPrefixRootCertificate;
+
+    bool checkSmartCardContent( void );
+    bool m_bCheckSmartCardContentDone;
+
+    void initializeObjectIndex( void );
+
+    void checkTokenInfo( void );
+
+    void setTokenInfo( void );
+
+    void writeTokenInfo( void );
+
+    void readTokenInfo( void );
+
+    void createTokenInfo( void );
+
+    //void initializeTokenInfo( void );
+
+    CK_OBJECT_HANDLE computeObjectHandle( const CK_OBJECT_CLASS&, const bool& );
+
+    inline void clear( void ) { m_Objects.clear( ); }
+
+    void authenticateUser( Marshaller::u1Array* );
+
+    void authenticateAdmin( Marshaller::u1Array* );
+
+    Marshaller::u1Array* PadRSAPKCS1v15( Marshaller::u1Array*, const CK_ULONG& );
+
+    Marshaller::u1Array* PadRSAX509( Marshaller::u1Array*, const CK_ULONG& );
+
+    Marshaller::u1Array* EncodeHashForSigning( Marshaller::u1Array*, const CK_ULONG&, const CK_ULONG& );
+
+    void verifyRSAPKCS1v15( Marshaller::u1Array*, Marshaller::u1Array*, const unsigned int& );
+
+    void verifyRSAX509( Marshaller::u1Array*, Marshaller::u1Array*, const unsigned int& );
+
+    void verifyHash( Marshaller::u1Array*, Marshaller::u1Array*, const unsigned int&, const CK_ULONG& );
+
+    void deleteObjectFromCard( StorageObject* );
+
+    void computeObjectFileName( StorageObject*, std::string& );
+
+    void writeObject( StorageObject* );
+
+    CK_OBJECT_HANDLE registerStorageObject( StorageObject* );
+
+    void unregisterStorageObject( const CK_OBJECT_HANDLE& );
+
+    CK_OBJECT_HANDLE computeObjectHandle( void );
+
+    void synchronizeObjects( void );
+
+    void synchronizePublicObjects( void );
+
+    void synchronizePrivateObjects( void );
+
+    void synchronizePIN( void );
+
+    void synchronizePublicCertificateAndKeyObjects( void );
+
+    void synchronizePrivateCertificateAndKeyObjects( void );
+
+    void synchronizePublicDataObjects( void );
+
+    void synchronizePrivateDataObjects( void );
+
+    void synchronizePrivateKeyObjects( void );
+
+    void synchronizeRootCertificateObjects( void );
+
+    void synchronizeEmptyContainers( void );
+
+    void createCertificateFromMiniDriverFile( const std::string&, const unsigned char&, const unsigned char& );
+
+    void createCertificateFromPKCS11ObjectFile( const std::string&, const std::string& );
+
+    void createPublicKeyFromPKCS11ObjectFile( const std::string& );
+
+    void createPublicKeyFromMiniDriverFile( const std::string&, const unsigned char& a_ucIndex, const unsigned int& a_ucKeySpec, Marshaller::u1Array*, Marshaller::u1Array* );
+
+    void createPrivateKeyFromPKCS11ObjectFile( const std::string& );
+
+    void createPrivateKeyFromMiniDriverFile( const std::string&, const unsigned char&, const unsigned int&, Marshaller::u1Array*, Marshaller::u1Array* );
+
+    bool isPrivate( const CK_OBJECT_HANDLE& a_ObjectHandle ) { return ( ( ( a_ObjectHandle >> 8 ) & 0x000000FF ) >= 0x00000010 ); }
+
+    void checkAuthenticationStatus( CK_ULONG, MiniDriverException& );
+
+    void printObject( StorageObject* );
+
+    Marshaller::u1Array* computeSHA1( const unsigned char* a_pData, const size_t& a_uiLength );
+
+    boost::mt19937 m_RandomNumberGenerator;
+
+    Device* m_Device;
+
+    TOKEN_OBJECTS m_Objects;
+
+    std::vector< StorageObject* > m_ObjectsToCreate;
+
+    //std::vector< std::string > m_ObjectsToDelete;
+
+    CK_TOKEN_INFO m_TokenInfo;
+
+    CK_ULONG m_RoleLogged;
+
+    unsigned char m_uiObjectIndex;
+
+    bool m_bCreateDirectoryP11;
+
+    bool m_bCreateTokenInfoFile;
+
+    bool m_bWriteTokenInfoFile;
+
+    bool m_bSynchronizeObjectsPublic;
+
+    bool m_bSynchronizeObjectsPrivate;
+
+    std::set< CK_OBJECT_HANDLE > m_TokenObjectsReturnedInSearch;
+
+    Slot* m_pSlot;
+
+    unsigned char computeIndex( const std::string& );
+
+    void generateDefaultAttributesCertificate( X509PubKeyCertObject* );
+
+    void generateDefaultAttributesKeyPublic( Pkcs11ObjectKeyPublicRSA* );
+
+    void generateDefaultAttributesKeyPrivate( RSAPrivateKeyObject* );
+
+    void generateLabel( boost::shared_ptr< Marshaller::u1Array>&, boost::shared_ptr< Marshaller::u1Array>& );
+
+    void generateID(boost::shared_ptr< Marshaller::u1Array>&, boost::shared_ptr< Marshaller::u1Array>& );
+
+    void generateSubject( boost::shared_ptr< Marshaller::u1Array>&, boost::shared_ptr< Marshaller::u1Array>& );
+
+    void generateSerialNumber( boost::shared_ptr< Marshaller::u1Array>&, boost::shared_ptr< Marshaller::u1Array>& );
+
+    void generateIssuer( boost::shared_ptr< Marshaller::u1Array>&, boost::shared_ptr< Marshaller::u1Array>& );
+
+    void generatePublicKeyModulus( boost::shared_ptr< Marshaller::u1Array>&, boost::shared_ptr< Marshaller::u1Array>&, u8& );
+
+    void generateRootAndSmartCardLogonFlags( boost::shared_ptr< Marshaller::u1Array>&, bool&, unsigned long&, bool& );
+
+    void searchContainerIndex( boost::shared_ptr< Marshaller::u1Array>&, unsigned char&, unsigned char& );
+
+    void setDefaultAttributesCertificate( X509PubKeyCertObject* );
+
+    void setDefaultAttributesKeyPublic( Pkcs11ObjectKeyPublicRSA* );
+
+    void setDefaultAttributesKeyPrivate( RSAPrivateKeyObject* );
+
+    void setContainerIndexToCertificate( boost::shared_ptr< Marshaller::u1Array>&, const unsigned char&, const unsigned char& );
+
+    void setContainerIndexToKeyPublic( boost::shared_ptr< Marshaller::u1Array>&, const unsigned char&, const unsigned char& );
+
+    void computeObjectNameData( std::string&, /*const*/ StorageObject* );
+
+    void computeObjectNamePublicKey( std::string&, /*const*/ StorageObject* );
+    
+    void computeObjectNamePrivateKey( std::string&, /*const*/ StorageObject* );
+
+    void computeObjectNameCertificate( std::string&, /*const*/ StorageObject* );
+
+    void incrementObjectIndex( void );
+
+    bool isObjectNameValid( const std::string&, const MiniDriverFiles::FILES_NAME& );
+
+};
+
+
+#endif // __GEMALTO_TOKEN__

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/acx_pthread.m4
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/acx_pthread.m4	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/acx_pthread.m4	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,190 +0,0 @@
-dnl Available from the GNU Autoconf Macro Archive at:
-dnl http://www.gnu.org/software/ac-archive/htmldoc/acx_pthread.html
-dnl
-AC_DEFUN([ACX_PTHREAD], [
-AC_REQUIRE([AC_CANONICAL_HOST])
-AC_LANG_SAVE
-AC_LANG_C
-acx_pthread_ok=no
-
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
-
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test x"$acx_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-fi
-
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread pthread -pthread -pthreads -mthreads --thread-safe -mt"
-
-# The ordering *is* (sometimes) important.  Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-#       other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-
-case "${host_cpu}-${host_os}" in
-        *solaris*)
-
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthread or
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
-
-        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
-        ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
-        case $flag in
-                none)
-                AC_MSG_CHECKING([whether pthreads work without any flags])
-                ;;
-
-                -*)
-                AC_MSG_CHECKING([whether pthreads work with $flag])
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-                *)
-                AC_MSG_CHECKING([for the pthreads library -l$flag])
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Check for various functions.  We must include pthread.h,
-        # since some functions may be macros.  (On the Sequent, we
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        AC_TRY_LINK([#include <pthread.h>],
-                    [pthread_t th; pthread_join(th, 0);
-                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
-                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
-                    [acx_pthread_ok=yes])
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        AC_MSG_RESULT($acx_pthread_ok)
-        if test "x$acx_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
-done
-fi
-
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Detect AIX lossage: threads are created detached by default
-        # and the JOINABLE attribute has a nonstandard name (UNDETACHED).
-        AC_MSG_CHECKING([for joinable pthread attribute])
-        AC_TRY_LINK([#include <pthread.h>],
-                    [int attr=PTHREAD_CREATE_JOINABLE;],
-                    ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
-        if test x"$ok" = xunknown; then
-                AC_TRY_LINK([#include <pthread.h>],
-                            [int attr=PTHREAD_CREATE_UNDETACHED;],
-                            ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
-        fi
-        if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
-                AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
-                          [Define to the necessary symbol if this constant
-                           uses a non-standard name on your system.])
-        fi
-        AC_MSG_RESULT(${ok})
-        if test x"$ok" = xunknown; then
-                AC_MSG_WARN([we do not know how to create joinable pthreads])
-        fi
-
-        AC_MSG_CHECKING([if more special flags are required for pthreads])
-        flag=no
-        case "${host_cpu}-${host_os}" in
-                *-aix* | *-freebsd*)     flag="-D_THREAD_SAFE";;
-                *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
-        esac
-        AC_MSG_RESULT(${flag})
-        if test "x$flag" != xno; then
-                PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-        fi
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        # More AIX lossage: must compile with cc_r
-        AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
-else
-        PTHREAD_CC="$CC"
-fi
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-AC_SUBST(PTHREAD_CC)
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
-        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
-        :
-else
-        acx_pthread_ok=no
-        $2
-fi
-AC_LANG_RESTORE
-])dnl ACX_PTHREAD

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,7 +18,7 @@
  *
  */
 
-#include "stdafx.h"
+//#include "stdafx.h"
 #include "MarshallerCfg.h"
 #include "algo_des.h"
 

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,11 +18,12 @@
  *
  */
 
-#ifndef _include_algo_des_h
-#define _include_algo_des_h
+#ifndef __GEMALTO_ALGO_DES__
+#define __GEMALTO_ALGO_DES__
 
-extern void algo_DES_DESProcess(u1* key, u1* input, u1* output, u1 mode);
-extern void algo_DES_3DESProcess(u1 keyLength, u1* key, u1* input, u1* output, u1 mode);
 
-#endif
+extern void algo_DES_DESProcess( unsigned char* key, unsigned char* input, unsigned char* output, unsigned char mode );
 
+extern void algo_DES_3DESProcess( unsigned char keyLength, unsigned char* key, unsigned char* input, unsigned char* output, unsigned char mode );
+
+#endif // __GEMALTO_ALGO_DES__

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,11 +18,15 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstring>
+
 #include "MarshallerCfg.h"
 #include "algo_utils.h"
 #include "algo_md5.h"
 
+extern bool IS_LITTLE_ENDIAN;
+extern bool IS_BIG_ENDIAN;
+
 const u1 md5_padding[64] = {
     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -21,6 +21,8 @@
 #ifndef _include_algo_md5_h
 #define _include_algo_md5_h
 
+#include "MarshallerCfg.h"
+
 typedef struct algo_md5_context{
     u4 total[2];
     u4* digest;

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,11 +18,14 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstring>
+
 #include "MarshallerCfg.h"
 #include "algo_utils.h"
 #include "algo_sha1.h"
 
+extern bool IS_LITTLE_ENDIAN;
+
 const u1 sha1_padding[64] = {
     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,22 +18,32 @@
  *
  */
 
+
 #ifndef _include_algo_sha1_h
 #define _include_algo_sha1_h
 
-typedef struct algo_sha1_context
-{
-    u4 total[2];
-    u4* digest;
-    u1* input;
+
+typedef struct algo_sha1_context {
+
+    unsigned int total[ 2 ];
+    
+    unsigned int* digest;
+
+    unsigned char* input;
+
 } algo_sha1_context;
 
+
 #define SHA1_HASH_LENGTH  20
+
 #define SHA1_BLOCK_LENGTH 64
 
-extern void algo_sha1_starts(algo_sha1_context* ctx);
-extern void algo_sha1_update(algo_sha1_context* ctx, u1* input, u4 length);
-extern void algo_sha1_finish(algo_sha1_context* ctx);
 
+extern void algo_sha1_starts( algo_sha1_context* ctx );
+
+extern void algo_sha1_update( algo_sha1_context* ctx, unsigned char* input, unsigned int length );
+
+extern void algo_sha1_finish( algo_sha1_context* ctx );
+
+
 #endif
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,11 +18,14 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstring>
+
 #include "MarshallerCfg.h"
 #include "algo_utils.h"
 #include "algo_sha256.h"
 
+extern bool IS_LITTLE_ENDIAN;
+
 const u1 sha256_padding[64] =
 {
     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,7 +18,7 @@
  *
  */
 
-#include "stdafx.h"
+//#include "stdafx.h"
 #include "MarshallerCfg.h"
 #include "algo_utils.h"
 

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,744 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include "cardmoduleservice.h"
-
-#include <string>
-
-#include <assert.h>
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "thread.h"
-#include "event.h"
-#include "session.h"
-#include "slot.h"
-#include "application.h"
-#include "log.h"
-
-#ifdef _XCL_
-#include <xcl_utils.h>
-#endif // _XCL_
-
-#ifdef __sun
-typedef LPSTR LPTSTR;
-#endif
-
-// Initialization of Static fields
-SCARDCONTEXT Application::_hContext = 0;
-
-Slot* Application::_slotCache[CONFIG_MAX_SLOT] = {
-   NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,
-   NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR,NULL_PTR
-};
-
-CK_ULONG Application::_numSlots = 0;
-
-#ifdef _XCL_
-xCL_DeviceHandle Application::_deviceHandle = 0; // asadali
-#endif // _XCL_
-
-
-/*
-*/
-#ifndef _XCL_
-CK_RV Application::InitApplication( )
-{
-   //Log::begin( "Application::InitApplication" );
-
-   // do the enumeration of slots
-   CK_ULONG hResult = SCardEstablishContext( SCARD_SCOPE_USER, NULL, NULL, &Application::_hContext );
-
-   //Log::log( "Application::InitApplication - SCardEstablishContext <%#02x>", hResult );
-   //Log::log( "Application::InitApplication - Application::_hContext <%#02x>", Application::_hContext );
-
-   if( SCARD_S_SUCCESS != hResult )
-   {
-      return CKR_GENERAL_ERROR;
-   }
-
-#ifdef __APPLE__
-   /* Apple bug 5256035 */
-   {
-      SCARDHANDLE h;
-      DWORD p;
-      SCardConnect(Application::_hContext, "fake reader", SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &h, &p);
-   }
-#endif
-
-   //Log::end( "Application::InitApplication" );
-
-   return CKR_OK;
-}
-
-#else // _XCL_
-
-CK_RV Application::InitApplication( )
-{
-    //Log::begin( "Application::InitApplication" );
-    u4 deviceID;
-    u4 rv;
-    xCL_DevicePtr deviceList;
-    xCL_DevicePtr device;
-    u4 numberOfDevices;
-    u4 i;
-
-    PRINT_MSG("IN Application::Init");
-
-    rv = xCL_InterfaceInit();
-
-    rv = xCL_DiscoverDevices(&deviceList, &numberOfDevices);
-    if (rv == 0 && numberOfDevices != 0)
-    {
-        // Pick the first device, with ID=0
-        device = deviceList + 0;
-        deviceID = device->deviceID ;
-        PRINT_DATA(NULL, 0, (char*)device->uniqueName);
-
-        // Create device handle
-        rv = xCL_CreateHandleFromDeviceID(deviceID, &Application::_deviceHandle);
-        if (rv == 0)
-        {
-            PRINT_MSG("IN Application::Init , device handle created");
-        }
-
-        // Free memory for all devices
-        for (i=0; i<numberOfDevices; i++)
-        {
-            rv = xCL_FreeDeviceMemory(deviceList + i);
-        }
-    }
-    return CKR_OK;
-}
-
-#endif // _XCL_
-
-
-/*
-*/
-
-#ifndef _XCL_
-
-CK_RV Application::Enumerate( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount )
-{
-   //Log::begin( "Application::Enumerate" );
-
-   CK_ULONG   slotNb              = 0;
-   LPTSTR     pReader             = NULL;
-   CK_LONG    hResult             = 0;
-   CK_SLOT_ID sid                 = 0;
-
-   if( NULL_PTR == pulCount )
-   {
-      //Log::error( "Application::Enumerate", "CKR_ARGUMENTS_BAD" );
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   // Get the supported readers from the current cache
-   std::string currentCache[ CONFIG_MAX_SLOT ];
-   for( CK_SLOT_ID i = 0; i < CONFIG_MAX_SLOT; i++ )
-   {
-      currentCache[ i ] = "";
-      if( NULL_PTR != Application::_slotCache[ i ] )
-      {
-         currentCache[ i ] = *(Application::_slotCache[ i ]->_readerName);
-         //Log::log( "Application::Enumerate - currentCache[ %d ] <%s>", i, currentCache[ i ].c_str( ) );
-      }
-   }
-
-   // Get the readers from the PCSC layer
-   DWORD readerListCharLength = 0;
-   hResult = SCardListReaders( Application::_hContext, NULL, NULL, &readerListCharLength );
-   //Log::log( "Application::Enumerate - readerListCharLength <%#02x>", readerListCharLength );
-   //Log::log( "Application::Enumerate - SCardListReaders <%#02x>", hResult );
-   if( SCARD_S_SUCCESS != hResult )
-   {
-      //Log::error( "Application::Enumerate", "CKR_GENERAL_ERROR" );
-      return CKR_GENERAL_ERROR;
-   }
-
-   LPTSTR pReaderList = (lpCharPtr)malloc( sizeof(char) * readerListCharLength );
-   if( NULL == pReaderList )
-   {
-      //Log::error( "Application::Enumerate", "CKR_HOST_MEMORY" );
-      return CKR_HOST_MEMORY;
-   }
-   memset( pReaderList, 0, sizeof(char) * readerListCharLength );
-
-   hResult = SCardListReaders( Application::_hContext, NULL, pReaderList, &readerListCharLength);
-   //Log::log( "Application::Enumerate - SCardListReaders 2 <%#02x>", hResult );
-   if( SCARD_S_SUCCESS != hResult )
-   {
-      free( pReaderList );
-      //Log::error( "Application::Enumerate", "CKR_GENERAL_ERROR" );
-      return CKR_GENERAL_ERROR;
-   }
-
-   // Construct the PCSC reader list
-   std::string currentPcscList[ CONFIG_MAX_SLOT ];
-   for( CK_SLOT_ID i = 0; i < CONFIG_MAX_SLOT; i++ )
-   {
-      currentPcscList[ i ] = "";
-   }
-   pReader = pReaderList; //readers;
-   int i = 0;
-   while( pReader && ( '\0' != *pReader ) )
-   {
-      currentPcscList[ i ] = pReader;
-      //Log::log( "Application::Enumerate - PCSC List[ %d ] <%s>", i, currentPcscList[ i ].c_str( ) );
-      i++;
-      if( i > CONFIG_MAX_SLOT )
-      {
-         /*
-         free( pReaderList );
-         //Log::error( "Application::Enumerate", "CKR_HOST_MEMORY" );
-         return CKR_HOST_MEMORY;
-         */
-         break;
-      }
-
-      // Advance to the next value.
-      size_t readerNameLen = strlen( (const char*)pReader );
-      pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
-   }
-   free( pReaderList );
-
-   // Does a reader desappeared ?
-   for( CK_SLOT_ID i = 0; i < CONFIG_MAX_SLOT; i++ )
-   {
-      if( NULL_PTR != Application::_slotCache[ i ] )
-      {
-         //printf( "Application::_slotCache[ %lu ]->_readerName <%s>\n", i, Application::_slotCache[ i ]->_readerName->c_str( ) );
-
-         bool bFound = false;
-         for( int j = 0 ; j < CONFIG_MAX_SLOT; j++ )
-         {
-            //printf( "currentPcscList[ %d ] <%s>\n", j, currentPcscList[ j ].c_str( ) );
-
-            if( 0 == (Application::_slotCache[ i ]->_readerName)->compare( currentPcscList[ j ] ) )
-            {
-               bFound = true;
-               //printf( "!! Found !!\n" );
-               break;
-            }
-         }
-         if( false == bFound )
-         {
-            // Not found into the PCSC reader list
-            deleteSlot( i );
-            //printf( "!! Not Found -> delete !!\n" );
-         }
-      }
-   }
-
-   // Does a new reader appears ?
-   //printf( "\n\nDoes a new reader appears ?\n" );
-   for( int i = 0; i < CONFIG_MAX_SLOT; i++ )
-   {
-      if( false == currentPcscList[ i ].empty( ) )
-      {
-         //printf( "currentPcscList[ %d ] <%s>\n", i, currentPcscList[ i ].c_str( ) );
-
-         bool bFound = false;
-         for( int j = 0 ; j < CONFIG_MAX_SLOT; j++ )
-         {
-            if( 0 != Application::_slotCache[ j ] )
-            {
-               //printf( "   Application::_slotCache[ %d ] <%s>\n", j, Application::_slotCache[ j ]->_readerName->c_str( ) );
-               if( 0 == ( currentPcscList[ i ].compare( *(Application::_slotCache[ j ]->_readerName) ) ) )
-               {
-                  bFound = true;
-                  //printf( "   !! Found !!\n" );
-                  break;
-               }
-            }
-         }
-         if( false == bFound )
-         {
-            //printf( "!! Not Found -> add !!\n" );
-
-            CK_RV rv = addSlot( currentPcscList[ i ] );
-            if( CKR_OK != rv )
-            {
-               //Log::error( "Application::Enumerate", "addSlot failed" );
-               return rv;
-            }
-         }
-      }
-   }
-
-
-   // Scan Reader List
-   slotNb = 0;
-   Application::_numSlots = 0;
-   for (int i = 0; i < CONFIG_MAX_SLOT; i++)
-   {
-      // Existing Slots only are scanned
-      if (Application::_slotCache[i] != NULL_PTR)
-      {
-         //Log::log( "Application::Enumerate - New Cache[ %d ] <%s>", i, Application::_slotCache[ i ]->_readerName->c_str( ) );
-         Application::_numSlots++;
-
-         SCARD_READERSTATE readerStates;
-         memset( &readerStates, 0, sizeof( SCARD_READERSTATE ) );
-         readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-         readerStates.szReader = Application::_slotCache[i]->_readerName->c_str();
-
-         // Lets check if token is present or not
-         if (SCardGetStatusChange(Application::_hContext, 100, &readerStates, 1) == SCARD_S_SUCCESS)
-         {
-            if ((readerStates.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT)
-            {
-               // We found a card in this reader
-               Application::_slotCache[i]->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-               //Log::log( "Application::Enumerate - New Cache[ %d ] - Name <%s> - Token present", i, Application::_slotCache[ i ]->_readerName->c_str( ) );
-            }
-            else
-            {
-               // No card in this reader
-               Application::_slotCache[i]->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-               //Log::log( "Application::Enumerate - New Cache[ %d ] - Name <%s> - Token NOT present", i, Application::_slotCache[ i ]->_readerName->c_str( ) );
-            }
-         }
-
-         // Slots with Token Present
-         if((tokenPresent == TRUE) &&
-            (Application::_slotCache[i]->_slotInfo.flags & CKF_TOKEN_PRESENT))
-         {
-            slotNb++;
-         }
-         // All slots
-         else if (tokenPresent == FALSE)
-         {
-            slotNb++;
-         }
-      }
-   }
-
-   // If pSlotList is not NULL then *pulCount contains the buffer size of pSlotList
-   // so we need to check if size passed is valid or not.
-   if((pSlotList != NULL_PTR)&&(*pulCount < slotNb))
-   {
-      *pulCount = slotNb;
-      //Log::error( "Application::Enumerate", "CKR_BUFFER_TOO_SMALL" );
-      return CKR_BUFFER_TOO_SMALL;
-   }
-
-   *pulCount = slotNb;
-
-   // Fill slot list if not NULL
-   if (pSlotList != NULL_PTR)
-   {
-      for (int i = 0; i < CONFIG_MAX_SLOT; i++)
-      {
-         // Existing Slots only are scanned
-         if (Application::_slotCache[i] != NULL_PTR)
-         {
-            CK_BBOOL IsFound = FALSE;
-
-            // Slots with Token Present
-            if((tokenPresent == TRUE) &&
-               (Application::_slotCache[i]->_slotInfo.flags & CKF_TOKEN_PRESENT))
-            {
-               IsFound = TRUE;
-            }
-
-            // All slots
-            else if (tokenPresent == FALSE)
-            {
-               IsFound = TRUE;
-            }
-
-            // Fill Slot List
-            if(IsFound == TRUE)
-            {
-               pSlotList[sid++] = Application::_slotCache[i]->_slotId;
-            }
-         }
-      }
-   }
-
-   //Log::end( "Application::Enumerate" );
-
-   return CKR_OK;
-}
-
-#else // _XCL_
-
-CK_RV Application::Enumerate( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount )
-{
-    PRINT_MSG("IN Application::Enumerate");
-
-    LPTSTR     pReaderList         = NULL;
-    CK_SLOT_ID slotIdx             = 0;
-    CK_ULONG   slotNb              = 0;
-    LPTSTR     pReader             = NULL;
-    CK_LONG    hResult             = 0;
-    CK_SLOT_ID sid                 = 0;
-
-    if(pulCount == NULL_PTR){
-        return CKR_ARGUMENTS_BAD;
-    }
-
-    DWORD readerListCharLength = SCARD_AUTOALLOCATE;
-
-    // asadali
-    // Get reader list, For now only ONE SEG-Lite token ...
-    pReaderList = (char *) malloc(64);
-    strcpy(pReaderList, "xCL_Token");
-    readerListCharLength = strlen(pReaderList);
-    *(pReaderList + readerListCharLength) = '\0';
-    *(pReaderList + readerListCharLength + 1) = '\0';
-
-    // Get Reader List if not already Get
-    if (Application::_numSlots == 0)
-    {
-        // clear the slot cache
-        //CSlot::ClearCache();
-
-        pReader = pReaderList;
-
-        while ('\0' != *pReader )
-        {
-            size_t readerNameLen = strlen((const char*)pReader);
-            size_t sd;
-
-            Slot* slot         = new Slot();
-            slot->_slotId      = slotIdx++;
-
-            // fill in the slot description
-            for(sd = 0; sd < readerNameLen; sd++)
-            {
-                slot->_slotInfo.slotDescription[sd] = pReader[sd];
-            }
-
-            if(slotIdx > CONFIG_MAX_SLOT){
-                return CKR_HOST_MEMORY;
-            }
-
-            slotNb++;
-
-            slot->_readerName  = new std::string(pReader);
-
-// GD            Application::AddSlotToCache(slot);
-                Application::addSlot (slot);
-
-            // Advance to the next value.
-            pReader = (lpTCharPtr)((lpTCharPtr)pReader + readerNameLen + 1);
-        }
-
-        free(pReaderList);
-        Application::_numSlots = slotNb;
-    }
-
-    // Scan Reader List
-    slotNb = 0;
-
-    for (int i = 0; i < CONFIG_MAX_SLOT; i++)
-    {
-        // Existing Slots only are scanned
-        if (Application::_slotCache[i] != NULL_PTR)
-        {
-            SCARD_READERSTATE readerStates;
-
-            readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-            readerStates.szReader = Application::_slotCache[i]->_readerName->c_str();
-
-            // Lets check if token is present or not
-
-            // asadali
-            if (xCL_IsTokenPresent())
-            {
-                // We found a card in this reader
-                Application::_slotCache[i]->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-            }
-            else
-            {
-                // No card in reader
-                Application::_slotCache[i]->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-            }
-
-            // Slots with Token Present
-            if((tokenPresent == TRUE) &&
-               (Application::_slotCache[i]->_slotInfo.flags & CKF_TOKEN_PRESENT))
-            {
-                slotNb++;
-            }
-            // All slots
-            else if (tokenPresent == FALSE)
-            {
-                slotNb++;
-            }
-        }
-    }
-
-    // If pSlotList is not NULL then *pulCount contains the buffer size of pSlotList
-    // so we need to check if size passed is valid or not.
-    if((pSlotList != NULL_PTR)&&(*pulCount < slotNb))
-    {
-        *pulCount = slotNb;
-        return CKR_BUFFER_TOO_SMALL;
-    }
-
-    *pulCount = slotNb;
-
-    // Fill slot list if not NULL
-    if (pSlotList != NULL_PTR)
-    {
-        for (int i = 0; i < CONFIG_MAX_SLOT; i++)
-        {
-            // Existing Slots only are scanned
-            if (Application::_slotCache[i] != NULL_PTR)
-            {
-                CK_BBOOL IsFound = FALSE;
-
-                // Slots with Token Present
-                if((tokenPresent == TRUE) &&
-                   (Application::_slotCache[i]->_slotInfo.flags & CKF_TOKEN_PRESENT))
-                {
-                    IsFound = TRUE;
-                }
-
-                // All slots
-                else if (tokenPresent == FALSE)
-                {
-                    IsFound = TRUE;
-                }
-
-                // Fill Slot List
-                if(IsFound == TRUE)
-                {
-                    pSlotList[sid++] = Application::_slotCache[i]->_slotId;
-                }
-            }
-        }
-    }
-
-    return CKR_OK;
-}
-
-#endif // _XCL_
-
-/*
-*/
-CK_RV Application::GetSlotFromSlotId( CK_SLOT_ID slotId, Slot** slot )
-{
-   if(((int)slotId < 0) || (slotId >= CONFIG_MAX_SLOT))
-   {
-      return CKR_SLOT_ID_INVALID;
-   }
-
-   if (Application::_slotCache[slotId] != NULL_PTR)
-   {
-      *slot = Application::_slotCache[slotId];
-      return CKR_OK;
-   }
-
-   return CKR_SLOT_ID_INVALID;
-}
-
-
-/*
-*/
-void Application::ClearCache(void)
-{
-   Log::begin( "Application::ClearCache" );
-
-   // initialize the slot cache
-   for( int sid = 0 ; sid < CONFIG_MAX_SLOT ; sid++ )
-   {
-      Slot* slot = Application::_slotCache[ sid ];
-      if( NULL_PTR != slot )
-      {
-#ifdef INCLUDE_EVENTING
-         if(slot->_tracker != NULL_PTR)
-         {
-            slot->_tracker->stop( );
-         }
-#endif
-         delete slot;
-         Application::_slotCache[sid] = NULL_PTR;
-      }
-   }
-
-   // set the number of actual slots present to zero
-   Application::_numSlots = 0;
-
-#ifdef INCLUDE_EVENTING
-   // we should just signal all the events
-   CryptokiEvent.Signal();
-#endif
-
-   Log::end( "Application::ClearCache" );
-}
-
-
-/*
-*/
-void Application::Release( void )
-{
-   if( 0 != Application::_hContext )
-   {
-#ifndef _XCL_
-      SCardReleaseContext( Application::_hContext );
-#endif // _XCL_
-      Application::_hContext = 0;
-   }
-}
-
-
-/*
-*/
-void Application::End( void )
-{
-   Application::ClearCache( );
-   Application::Release( );
-}
-
-
-/*
-*/
-void Application::deleteSlot( int i )
-{
-   if( NULL_PTR != Application::_slotCache[ i ] )
-   {
-#ifdef INCLUDE_EVENTING
-      if( NULL_PTR != (Application::_slotCache[ i ]->_tracker) )
-      {
-         (Application::_slotCache[ i ])->_tracker->stop( );
-      }
-#endif
-      delete (Application::_slotCache[ i ]);
-      Application::_slotCache[ i ] = NULL_PTR;
-
-#ifdef INCLUDE_EVENTING
-      // we should just signal all the events
-      CryptokiEvent.Signal( );
-#endif
-
-   }
-}
-
-
-/*
-*/
-
-#ifndef _XCL_
-
-CK_RV Application::addSlot( std::string& a_readerName )
-{
-   int iSlotID = -1;
-   for( int j = 0 ; j < CONFIG_MAX_SLOT ; j++ )
-   {
-      if( NULL_PTR == Application::_slotCache[ j ] )
-      {
-         iSlotID = j;
-         break;
-      }
-   }
-   if( -1 == iSlotID )
-   {
-      return CKR_HOST_MEMORY;
-   }
-
-   Slot* slot = new Slot( );
-   slot->_readerName  = new std::string( a_readerName );
-
-   // Fill in the slot description
-   size_t l = ( a_readerName.length( ) > sizeof( slot->_slotInfo.slotDescription ) ) ? sizeof( slot->_slotInfo.slotDescription ) : a_readerName.length( );
-   for( size_t i = 0 ; i < l ; i++ )
-   {
-      slot->_slotInfo.slotDescription[ i ] = a_readerName[ i ];
-   }
-
-   // Add Slot in Cache
-   slot->_slotId = iSlotID;
-   Application::_slotCache[ iSlotID ] = slot;
-
-#ifdef INCLUDE_EVENTING
-   SCARD_READERSTATE readerStates;
-
-   readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-   readerStates.szReader = slot->_readerName->c_str();
-
-   if (SCardGetStatusChange(Application::_hContext, 0, &readerStates, 1) == SCARD_S_SUCCESS)
-   {
-      if ((readerStates.dwEventState & SCARD_STATE_PRESENT) != SCARD_STATE_PRESENT)
-      {
-         // we not found a card in this reader
-         slot->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-      }
-      else
-      {
-         // we found a card in this reader
-         slot->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-      }
-   }
-
-   // Start the monitoring also
-   slot->_tracker = new CardMonitoringThread(slot->_readerName->c_str());
-   slot->_tracker->SetSlot(slot);
-   slot->_tracker->start();
-
-#endif
-
-   return CKR_OK;
-}
-
-#else // _XCL_
-
-void Application::addSlot( Slot* slot )
-{
-    PRINT_MSG("IN Application::AddslotToCache");
-
-    // Add Slot in Cache
-    Application::_slotCache[slot->_slotId] = slot;
-
-#ifdef INCLUDE_EVENTING
-    SCARD_READERSTATE readerStates;
-
-    readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-    readerStates.szReader = slot->_readerName->c_str();
-
-    // asadali
-    if (xCL_IsTokenPresent())
-    {
-        // we found a card in this reader
-        slot->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-    }
-    else
-    {
-        // No card in reader
-        slot->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-    }
-
-    // Start the monitoring also
-    slot->_tracker = new CardMonitoringThread(slot->_readerName->c_str());
-    slot->_tracker->SetSlot(slot);
-    slot->_tracker->start();
-#endif
-}
-
-#endif // _XCL_

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/application.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/application.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/application.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,66 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_application_h
-#define _include_application_h
-
-#include <vector>
-#include <list>
-
-#ifdef _XCL_
-#include <xcl_utils.h>
-#endif // _XCL_
-
-using namespace std;
-
-class Application {
-
-public:
-   static CK_ULONG _numSlots;
-   static Slot* _slotCache[CONFIG_MAX_SLOT];
-   static SCARDCONTEXT _hContext;
-
-#ifdef _XCL_
-    static xCL_DeviceHandle _deviceHandle;
-#endif // _XCL_
-
-public:
-   static CK_RV InitApplication(void);
-
-   static CK_RV Enumerate(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount);
-
-   static CK_RV GetSlotFromSlotId(CK_SLOT_ID slotId, Slot** slot);
-
-//   static void AddSlotToCache(Slot* slot);
-	static void addSlot( Slot* slot );
-
-   static void ClearCache();
-
-   static void Release( void );
-   static void End( void );
-   //static void ReleaseThreads( void );
-
-   static void deleteSlot( int i );
-   static CK_RV addSlot( std::string& a_readerName );
-
-};
-
-#endif
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -22,26 +22,20 @@
 
 //#pragma warning(disable : 4251)
 
-#include "stdafx.h"
-#include "platconfig.h"
-//#include "config.h"
-//#include "dbg.h"
-
-
-
+#include <cstdio>
+#include "cryptoki.h"
 #include <numeric>
 #include <functional>
 #include "attrcert.h"
 #include "digest.h"
 #include "sha1.h"
 
-using namespace std;
 
 namespace
 {
 
     class JoinWith
-        : public binary_function<string, string, string>
+        : public std::binary_function<std::string, std::string, std::string>
     {
     public:
 
@@ -52,8 +46,8 @@
 
 
         result_type
-        operator()(string const &rFirst,
-                   string const &rSecond) const
+        operator()(std::string const &rFirst,
+                   std::string const &rSecond) const
         {
             return rFirst + m_Glue + rSecond;
         }
@@ -63,17 +57,17 @@
         second_argument_type const m_Glue;
     };
 
-    string
-    Combine(vector<string> const &rvsNames)
+    std::string
+    Combine(std::vector<std::string> const &rvsNames)
     {
-        static string::value_type const cBlank = ' ';
-        static string const sBlank(1, cBlank);
+        static std::string::value_type const cBlank = ' ';
+        static std::string const sBlank(1, cBlank);
 
         if(!rvsNames.empty())
             return accumulate(rvsNames.begin() + 1, rvsNames.end(),
                               *rvsNames.begin(), JoinWith(sBlank));
         else
-            return string();
+            return std::string();
     }
 
 } // namespace
@@ -121,16 +115,16 @@
     return m_x509cert.SerialNumber();
 }
 
-string
+std::string
 CAttributedCertificate::DerivedName() const
 {
-    string sDerivedName(Combine(m_x509cert.UTF8SubjectCommonName()));
+    std::string sDerivedName(Combine(m_x509cert.UTF8SubjectCommonName()));
     if(sDerivedName.empty())
         sDerivedName.assign("Smart Card User");
     return sDerivedName;
 }
 
-string
+std::string
 CAttributedCertificate::DerivedLabel() const
 {
     return Combine(m_x509cert.SubjectCommonName());
@@ -152,38 +146,38 @@
 CAttributedCertificate::DerivedId(unsigned char const * data, size_t length)
 {
     CSHA1 sha1;
-    u1 hash[20];
-    sha1.HashCore(const_cast<CK_BYTE_PTR>(data), 0, static_cast<CK_LONG>(length));
-    sha1.HashFinal(hash);
+    unsigned char hash[20];
+    sha1.hashCore(const_cast<CK_BYTE_PTR>(data), 0, static_cast<CK_LONG>(length));
+    sha1.hashFinal(hash);
 
     return BEROctet::Blob(hash, 20);
 }
 
-string
+std::string
 CAttributedCertificate::DerivedUniqueName() const
 {
     return DerivedUniqueName(m_x509cert.Modulus());
 }
 
-string
+std::string
 CAttributedCertificate::DerivedUniqueName(BEROctet::Blob const & data)
 {
     return DerivedUniqueName(data.c_str(), data.size());
 }
 
-string
+std::string
 CAttributedCertificate::DerivedUniqueName(unsigned char const * data, size_t length)
 {
     CSHA1 sha1;
-    u1 hash[20];
-    sha1.HashCore(const_cast<CK_BYTE_PTR>(data), 0, static_cast<CK_LONG>(length));
-    sha1.HashFinal(hash);
+    unsigned char hash[20];
+    sha1.hashCore(const_cast<CK_BYTE_PTR>(data), 0, static_cast<CK_LONG>(length));
+    sha1.hashFinal(hash);
 
     // Format as a GUID
 
     char name[40];
 
-    u1 *id = hash;
+    unsigned char *id = hash;
 
     int i, n = 0;
     char *c = name;
@@ -217,5 +211,5 @@
         n++; c+=2;
     }
 
-    return string(name);
+    return std::string(name);
 }

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/autogen.sh
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/autogen.sh	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/autogen.sh	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,5 +1,9 @@
 set -x
 
+# create symlinks for external directories
+[ -e config ] || ln -s ../../_BIN/config
+[ -e docs ] || ln -s ../docs
+
 rm -f configure Makefile.in Makefile config.h.in
 
 aclocal -I .

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,20 +18,17 @@
  *
  */
 
-// This implementation is based on X.690 specification. Access to this
-// specification is a pre-requisite to understand the logic. The spec
-// can be purchased from International Telecommunication Union (ITU)
-// at http://www.itu.int
 
-// This code is based on class in ACS baseline.
+// This implementation is based on X.690 specification. Access to this specification is a pre-requisite to understand the logic. 
+// The spec can be purchased from International Telecommunication Union (ITU) at http://www.itu.int
 
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
 
+#include <cstring>
+#include <cstdlib>
+#include <cstdio>
+
 #include "beroctet.h"
 
-using namespace std;
 
 BEROctet::BEROctet() : m_tcClass(tcUniversal),
                        m_fConstructed(fBerPcPrimitive),
@@ -59,21 +56,28 @@
                                                                        m_fModified(true)
 {
     if(!m_fDefinite && !m_fConstructed)
-        throw runtime_error("BERPrimitiveIndefiniteLength");
+        throw std::runtime_error("BERPrimitiveIndefiniteLength");
 }
 
 BEROctet::~BEROctet(void)
 {
-    for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
-        delete m_SubOctetList[i];
+    size_t l = m_SubOctetList.size( );
+    for( std::vector< BEROctet const* >::size_type i = 0 ; i < l ; ++i ) {
+        
+        delete m_SubOctetList[ i ];
+    }
 }
 
 BEROctet& BEROctet::operator=(BEROctet const &Oct)
 {
-
-    for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
+    size_t l = m_SubOctetList.size( );
+    for( std::vector< BEROctet const* >::size_type i = 0 ; i < l ; ++i ) {
+        
+        delete m_SubOctetList[ i ];
+    }
+    /*for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
         delete m_SubOctetList[i];
-
+*/
     m_SubOctetList.resize(0);
     m_blbData.resize(0);
 
@@ -88,8 +92,11 @@
 
     if(m_fConstructed)
     {
-        for(std::vector<BEROctet const*>::size_type i=0; i<Oct.m_SubOctetList.size(); i++)
+        size_t l = Oct.m_SubOctetList.size( );
+        for( std::vector< BEROctet const*>::size_type i = 0 ; i < l; ++i ) {
+
             m_SubOctetList.push_back(new BEROctet(*Oct.m_SubOctetList[i]));
+        }
     }
     else
         m_blbData = Oct.m_blbData;
@@ -109,8 +116,11 @@
 
         Blob data;
 
-        for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
-            data += m_SubOctetList[i]->Octet();
+        size_t l = m_SubOctetList.size( );
+        for( std::vector< BEROctet const* >::size_type i = 0 ; i < l; ++i ) {
+         
+            data += m_SubOctetList[ i ]->Octet( );
+        }
 
         return data;
     }
@@ -125,7 +135,7 @@
 {
 
     if(m_fConstructed)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     m_blbData = blb;
     m_fModified = true;
@@ -134,10 +144,10 @@
 
 // If the octet is a constructed type, this returns list of sub-octets
 
-vector<BEROctet*> BEROctet::SubOctetList() const
+std::vector<BEROctet*> BEROctet::SubOctetList() const
 {
     if(!m_fConstructed)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     return m_SubOctetList;
 }
@@ -147,7 +157,7 @@
 void BEROctet::Insert(BEROctet const &oct)
 {
     if(!m_fConstructed)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     BEROctet *pOct = new BEROctet(oct);
     m_SubOctetList.push_back(pOct);
@@ -211,16 +221,16 @@
 
 // Decode the contents of an OID
 
-string BEROctet::ObjectID() const
+std::string BEROctet::ObjectID() const
 {
 
     if(m_tcClass!=tcUniversal || m_dwTag!=dwBerUnivObjectIdent)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     if(!m_blbData.size())
-        throw runtime_error("BEREmptyOctet");
+        throw std::runtime_error("BEREmptyOctet");
 
-    string OID;
+    std::string OID;
 
     // The scratch buffer "text" below needs to be large enough to hold
     // the decimal encoding of two 32 bit integers, including a space
@@ -240,9 +250,9 @@
         {
             c++;
             if(c>=Last)
-                throw runtime_error("BERUnexpectedEndOfOctet");
+                throw std::runtime_error("BERUnexpectedEndOfOctet");
             if(subid>0x01FFFFFF)
-                throw runtime_error("BEROIDSubIdentifierOverflow");
+                throw std::runtime_error("BEROIDSubIdentifierOverflow");
             subid = (subid<<7) | ((*c)&0x7F);
         }
         if(First)
@@ -272,17 +282,17 @@
 
 // Encode an OID
 
-void BEROctet::ObjectID(string const &str)
+void BEROctet::ObjectID(std::string const &str)
 {
 
     if(m_tcClass!=tcUniversal)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     if(m_dwTag==dwBerUnivZero)
         m_dwTag = dwBerUnivObjectIdent;
 
     if(m_dwTag!=dwBerUnivObjectIdent)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     char *oid = 0;
 
@@ -296,28 +306,28 @@
         char *s;
 
         if(0==(s = strtok(oid," ")))
-            throw runtime_error("BERIllegalObjectIdentifier");
+            throw std::runtime_error("BERIllegalObjectIdentifier");
 
         unsigned int X,Y,dwSubOID;
 
         if(sscanf(s,"%u",&X)!=1)
-            throw runtime_error("BERIllegalObjectIdentifier");
+            throw std::runtime_error("BERIllegalObjectIdentifier");
 
         if(X>2)
-            throw runtime_error("BERIllegalObjectIdentifier");
+            throw std::runtime_error("BERIllegalObjectIdentifier");
 
         if(0==(s = strtok(0," ")))
-            throw runtime_error("BERIllegalObjectIdentifier");
+            throw std::runtime_error("BERIllegalObjectIdentifier");
 
         if(sscanf(s,"%u",&Y)!=1)
-            throw runtime_error("BERIllegalObjectIdentifier");
+            throw std::runtime_error("BERIllegalObjectIdentifier");
 
         if(X<2 && Y>39)
-            throw runtime_error("BERIllegalObjectIdentifier");
+            throw std::runtime_error("BERIllegalObjectIdentifier");
 
         dwSubOID = X*40;
         if(Y>0xFFFFFFFF-dwSubOID)
-            throw runtime_error("BERDataOverflow");
+            throw std::runtime_error("BERDataOverflow");
 
         dwSubOID += Y;
 
@@ -370,47 +380,47 @@
 // We here apply the convention from RFC 2459 that the 2 digit year
 // encoded in UTCTime is in the range 1950-2049.
 
-string BEROctet::Time() const
+std::string BEROctet::Time() const
 {
 
     static const Blob::size_type UnivUTCTimeSize = 13;
     static const Blob::size_type UnivGenTimeSize = 15;
 
     if(m_tcClass!=tcUniversal)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     if(m_dwTag==dwBerUnivUTCTime)
     {
         // UTCTime
 
         if(m_blbData.size()!=UnivUTCTimeSize)
-            throw runtime_error("BERInconsistentDataLength");
+            throw std::runtime_error("BERInconsistentDataLength");
 
-        string strCentury, strYear((char*)m_blbData.data(),2);
+        std::string strCentury, strYear((char*)m_blbData.data(),2);
         int iYear;
         if(sscanf(strYear.c_str(),"%d",&iYear)!=1)
-            throw runtime_error("FormatDecodingError");
+            throw std::runtime_error("FormatDecodingError");
 
         if(iYear>=50) strCentury = "19";
         else strCentury = "20";
 
         // Add century and strip off the 'Z'
 
-        return strCentury + string((char*)m_blbData.data(),UnivUTCTimeSize-1);
+        return strCentury + std::string((char*)m_blbData.data(),UnivUTCTimeSize-1);
     }
     else if(m_dwTag==dwBerUnivGenTime)
     {
         // GeneralizedTime
 
         if(m_blbData.size()!=UnivGenTimeSize)
-            throw runtime_error("BERInconsistentDataLength");
+            throw std::runtime_error("BERInconsistentDataLength");
 
         // Return the string as is, stripping off the 'Z'
 
-        return string((char*)m_blbData.data(),UnivGenTimeSize-1);
+        return std::string((char*)m_blbData.data(),UnivGenTimeSize-1);
     }
     else
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
 }
 
@@ -421,26 +431,26 @@
 // 1950-2049 are encoded as UTC Time and years later are encoded as
 // Generalized time. In this case, years < 1950 are not allowed.
 
-void BEROctet::Time(string const &str)
+void BEROctet::Time(std::string const &str)
 {
     static const Blob::size_type ExpectedSize = 14;
 
     if(m_tcClass!=tcUniversal)
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     if(str.size()!=ExpectedSize)
-        throw runtime_error("IllegalParameter");
+        throw std::runtime_error("IllegalParameter");
 
     // If m_dwTag is zero, chose appropriate tag according to year
 
     int iYear;
     if(sscanf(str.substr(0,4).c_str(),"%d",&iYear)!=1)
-        throw runtime_error("IllegalParameter");
+        throw std::runtime_error("IllegalParameter");
 
     if(m_dwTag==dwBerUnivZero)
     {
         if(iYear<1950)
-            throw runtime_error("IllegalParameter");
+            throw std::runtime_error("IllegalParameter");
         else if(iYear<2050)
             m_dwTag = dwBerUnivUTCTime;
         else
@@ -456,7 +466,7 @@
         blbData.assign((unsigned char*)str.data(),str.size());
 
     else
-        throw runtime_error("BERInconsistentOperation");
+        throw std::runtime_error("BERInconsistentOperation");
 
     blbData += 'Z';
 
@@ -466,12 +476,11 @@
 
 // SearchOID returns all the constructed octets that contain a particular OID
 
-void BEROctet::SearchOID(string const &OID, vector<BEROctet const*> &result) const
+void BEROctet::SearchOID(std::string const &OID, std::vector<BEROctet const*> &result) const
 {
+    size_t l = m_SubOctetList.size( );
+    for( std::vector< BEROctet const* >::size_type i = 0; i < l ; ++i ) {
 
-    for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
-    {
-
         if(m_SubOctetList[i]->Class()==tcUniversal &&
            m_SubOctetList[i]->Tag()==dwBerUnivObjectIdent)
         {
@@ -488,10 +497,11 @@
 
 // SearchOIDNext returns all the octets following a particular OID
 
-void BEROctet::SearchOIDNext(string const &OID, vector<BEROctet const*> &result) const
+void BEROctet::SearchOIDNext(std::string const &OID, std::vector<BEROctet const*> &result) const
 {
-    for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
-    {
+    size_t l = m_SubOctetList.size( );
+    for( std::vector< BEROctet const* >::size_type i = 0; i < l ; ++i ) {
+
         if(m_SubOctetList[i]->Class()==tcUniversal &&
            m_SubOctetList[i]->Tag()==dwBerUnivObjectIdent)
         {
@@ -535,7 +545,7 @@
         break;
 
     default:
-        throw runtime_error("BERIllegalClass");
+        throw std::runtime_error("BERIllegalClass");
     }
 
     if(fConstructed)
@@ -560,7 +570,7 @@
 
     Blob IdentOcts(&bLeadingOct,1);
 
-    for(int i=0; i<n; i++)
+    for(int i=0; i<n; ++i)
         IdentOcts +=buf[n-i-1];
 
     return IdentOcts;
@@ -591,7 +601,7 @@
     }
 
     Blob LengthOcts(&bLeadingOct,1);
-    for(int i=0; i<n; i++)
+    for(int i=0; i<n; ++i)
         LengthOcts +=buf[n-i-1];
 
     return LengthOcts;
@@ -604,7 +614,7 @@
 {
 
     if(!blb.size())
-        throw runtime_error("BEREmptyOctet");
+        throw std::runtime_error("BEREmptyOctet");
 
     size_t BufferSize = blb.size();
 
@@ -630,7 +640,7 @@
         break;
 
     default:
-        throw runtime_error("BERIllegalClass");
+        throw std::runtime_error("BERIllegalClass");
     }
 
     const unsigned char *c = blb.data();
@@ -643,18 +653,18 @@
 
         c++;
         if(c>Last)
-            throw runtime_error("BERUnexpectedEndOfOctet");
+            throw std::runtime_error("BERUnexpectedEndOfOctet");
 
         while (*c & 0x80)
         {
             m_dwTag = (m_dwTag << 7) | ((*c) & 0x7F);
             c++;
             if(c>Last)
-                throw runtime_error("BERUnexpectedEndOfOctet");
+                throw std::runtime_error("BERUnexpectedEndOfOctet");
         }
 
         if(m_dwTag > 0x01FFFFFF)
-            throw runtime_error("BERTagValueOverflow");
+            throw std::runtime_error("BERTagValueOverflow");
 
         m_dwTag = (m_dwTag << 7) | ((*c) & 0x7F);
 
@@ -662,7 +672,7 @@
 
     c++;
     if(c>Last)
-        throw runtime_error("BERUnexpectedEndOfOctet");
+        throw std::runtime_error("BERUnexpectedEndOfOctet");
 
     size_t DataSize;
 
@@ -672,17 +682,17 @@
         if(n)
         {
             DataSize = 0;
-            for(int i=0; i<n; i++)
+            for(int i=0; i<n; ++i)
             {
                 c++; if(c>Last)
-                    throw runtime_error("BERUnexpectedEndOfOctet");
+                    throw std::runtime_error("BERUnexpectedEndOfOctet");
                 if(DataSize>0x007FFFFF)
-                    throw runtime_error("BERDataOverflow");
+                    throw std::runtime_error("BERDataOverflow");
                 DataSize = (DataSize<<8) | (*c);
             }
         }
         else
-            throw runtime_error("BERUnexpectedIndefiniteLength");
+            throw std::runtime_error("BERUnexpectedIndefiniteLength");
     }
     else DataSize = *c;
 
@@ -696,10 +706,13 @@
     m_fModified = false;
 
     if(OctetSize>static_cast<unsigned int>(BufferSize))
-        throw runtime_error("BERInconsistentDataLength");
+        throw std::runtime_error("BERInconsistentDataLength");
 
-    for(std::vector<BEROctet const*>::size_type  i=0; i<m_SubOctetList.size(); i++)
+    size_t l = m_SubOctetList.size( );
+    for( std::vector< BEROctet const* >::size_type i = 0; i < l; ++i ) {
+     
         delete m_SubOctetList[i];
+    }
 
     m_SubOctetList.resize(0);
     m_blbData = Blob();
@@ -732,10 +745,17 @@
     if(m_fModified)
         return true;
 
-    if(m_fConstructed)
-        for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
-            if(m_SubOctetList[i]->Modified()) return true;
+    if(m_fConstructed) {
+        std::vector< BEROctet const* >::size_type l = m_SubOctetList.size( );
+        for( std::vector< BEROctet const* >::size_type i = 0; i < l; ++i ) {
 
+            if(m_SubOctetList[i]->Modified()) {
+                
+                return true;
+            }
+        }
+    }
+
     return false;
 
 }

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,7 +18,6 @@
  *
  */
 
-// This code is based on class in ACS baseline.
 
 #ifndef _include_beroctet_h
 #define _include_beroctet_h

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/c-mac.sh
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/c-mac.sh	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/c-mac.sh	2012-02-20 14:26:10 UTC (rev 141)
@@ -19,6 +19,12 @@
 LDFLAGS="-arch i386 -arch x86_64"
 CONFIGURE_ARGS="--disable-dependency-tracking"
 
+# boost
+#CFLAGS="$CFLAGS -I../boost1_45"
+
+# For Mac OS X Leopard 10.5
+#CFLAGS="$CFLAGS -DMACOSX_LEOPARD"
+
 # install in /usr
 CONFIGURE_ARGS="$CONFIGURE_ARGS --prefix=/usr"
 

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,312 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <memory>
-#include "stdafx.h"
-#include "cardcache.h"
-#include "error.h"
-#include "log.h"
-
-
-#define KEYSPEC_KEYEXCHANGE  0x01
-#define KEYSPEC_SIGNATURE    0x02
-#define MAX_RETRY 2
-#define LOW_MEMORY_LIMIT 25000
-
-
-/* Constructor
-*/
-CardCache::CardCache( CardModuleService * mscm ) : _mscm( mscm )
-{
-   if( !mscm )
-   {
-      throw CkError( CKR_FUNCTION_FAILED );
-   }
-}
-
-/*
-*/
-void CardCache::ManageGC( void )
-{
-   try
-   {
-      if( NULL != _mscm )
-      {
-         s4 freeMemory = _mscm->GetMemory( );
-
-         if ( freeMemory < LOW_MEMORY_LIMIT )
-         {
-             //printf( "\nCardCache::ManageGC - ForceGarbageCollector\n" );
-             Log::error( "CardCache::ManageGC", "ForceGarbageCollector" );
-            _mscm->ForceGarbageCollector( );
-         }
-      }
-   }
-   catch( ... )
-   {
-   }
-}
-
-
-/* WriteFile
-Write the incoming data into the incoming pointed path into the smartcard
-and then into the cache
-*/
-void CardCache::WriteFile( std::string const & path, u1Array const & data )
-{
-   int ntry = 0;
-   while( ntry < MAX_RETRY )
-   {
-      try
-      {
-         ntry++;
-         _mscm->WriteFile( const_cast< std::string* >( &path ), const_cast< u1Array* >( &data ) );
-         ManageGC( );
-         _fileCache[ path ] = data;
-         break;
-      }
-      catch( Marshaller::Exception & x )
-      {
-         CK_RV rv = CkError::CheckMarshallerException( x );
-         if( CKR_DEVICE_MEMORY == rv )
-         {
-            Log::error( "CardCache::WriteFile", "ForceGarbageCollector" );
-           _mscm->ForceGarbageCollector( );
-            if( ntry >= MAX_RETRY )
-            {
-               _fileCache.erase( path );
-               throw CkError( rv );
-            }
-         }
-         else
-         {
-            _fileCache.erase( path );
-            throw CkError( rv );
-         }
-      }
-      catch( ... )
-      {
-         _fileCache.erase( path );
-         throw CkError( CKR_FUNCTION_FAILED );
-      }
-   }
-}
-
-
-/* ReadFile
-*/
-const u1Array & CardCache::ReadFile( std::string const & path )
-{
-   //Log::log( "***** CardCache::ReadFile - path <%s>", path.c_str( ) );
-
-   // V2+ cards may throw OutOfMemoryException from ReadFile, however
-   // it may recover from this by forcing the garbage collection to
-   // occur. In fact as a result of a ReadFile command that throws
-   // OutOfMemoryException, GC has already occured, so the command may
-   // be re-tried with high chance of success.
-
-   map<string, u1Array>::const_iterator ifile = _fileCache.find( path );
-   if( ifile == _fileCache.end( ) )
-   {
-      //Log::log( "****** CardCache::ReadFile - read card" );
-
-      int ntry = 0;
-      while( ntry < MAX_RETRY )
-      {
-         try
-         {
-            ntry++;
-            auto_ptr< u1Array > data( _mscm->ReadFile( const_cast< std::string* >( &path ), 0 ) );
-            ManageGC( );
-            _fileCache[ path ] = *data;
-            break;
-         }
-         catch( Marshaller::Exception & x )
-         {
-            CK_RV rv = CkError::CheckMarshallerException( x );
-            if( CKR_DEVICE_MEMORY == rv )
-            {
-               Log::error( "CardCache::ReadFile", "ForceGarbageCollector" );
-               _mscm->ForceGarbageCollector( );
-               if( ntry >= MAX_RETRY )
-               {
-                  throw CkError( rv );
-               }
-            }
-            else
-            {
-               throw CkError( rv );
-            }
-         }
-         catch( ... )
-         {
-            throw CkError( CKR_FUNCTION_FAILED );
-         }
-      }
-   }
-
-   return _fileCache[ path ];
-}
-
-
-/* ClearFile
-Erase a file from the cache
-*/
-void CardCache::ClearFile( std::string const &path )
-{
-   _fileCache.erase( path );
-}
-
-
-/* ReadContainer
-Read the contained pointed by the incoming index from the smartcard
-and compute an instance into the cache
-*/
-const CardCache::Container& CardCache::ReadContainer( int const &ctrIndex ) const
-{
-   map< int, Container >::const_iterator icont = _contCache.find( ctrIndex );
-   if( icont == _contCache.end( ) )
-   {
-      try
-      {
-         Container cont;
-         auto_ptr< u1Array > cInfo( _mscm->GetCAPIContainer( ctrIndex ) );
-         u4 offset = 2;
-         for( int ikeySpec = 0; ikeySpec < 2 ; ++ikeySpec )
-         {
-            if( offset < cInfo->GetLength( ) )
-            {
-               u1 keySpec = cInfo->ReadU1At( offset );
-               offset += 2;
-               u1 expontLen = cInfo->ReadU1At( offset );
-               offset++;
-               u1Array publicExponent( expontLen );
-               memcpy( publicExponent.GetBuffer( ), cInfo->GetBuffer( ) + offset, expontLen );
-               offset += ( expontLen + 1 );
-               u4 modulusLen = cInfo->ReadU1At( offset ) << 4; // Modulus Len
-               offset++;
-               u1Array modulus( modulusLen );
-               memcpy( modulus.GetBuffer( ), cInfo->GetBuffer( ) + offset, modulusLen );
-
-               if( keySpec == KEYSPEC_KEYEXCHANGE )
-               {
-                  cont.exchModulus = modulus;
-                  cont.exchPublicExponent = publicExponent;
-               }
-               else if( keySpec == KEYSPEC_SIGNATURE )
-               {
-                  cont.signModulus = modulus;
-                  cont.signPublicExponent = publicExponent;
-               }
-               offset += modulusLen;
-               offset += 2;
-            }
-         }
-         _contCache[ ctrIndex ] = cont;
-      }
-      catch( ... )
-      {
-         _contCache[ ctrIndex ] = Container( ); // Empty
-      }
-   }
-   return _contCache[ ctrIndex ];
-}
-
-
-/* ClearContainer
-Erase the container pointed by the incoming index from the cache
-*/
-void CardCache::ClearContainer( int const &ctrIndex )
-{
-   _contCache.erase( ctrIndex );
-}
-
-
-/* FileList
-Retreive the list of the files contained into the incoming directory path
-and returns a string vectors
-*/
-const vector< std::string > & CardCache::FileList( std::string const &dir )
-{
-   map< std::string, vector< std::string > >::const_iterator idir = _fileList.find( dir );
-   if( idir == _fileList.end( ) )
-   {
-      vector< std::string > vfile;
-      int ntry = 0;
-      while( ntry < MAX_RETRY )
-      {
-         try
-         {
-            ntry++;
-            auto_ptr<StringArray> files( _mscm->GetFiles( const_cast<string*>( &dir ) ) );
-            ManageGC( );
-            for( u4 i = 0; i < files->GetLength( ) ; i++ )
-            {
-               vfile.push_back( *files->GetStringAt( i ) );
-            }
-            break;
-         }
-         catch( Marshaller::Exception & x )
-         {
-            CK_RV rv = CkError::CheckMarshallerException( x );
-            if( CKR_DEVICE_MEMORY == rv )
-            {
-               Log::error( "CardCache::FileList", "ForceGarbageCollector" );
-               _mscm->ForceGarbageCollector( );
-               if( ntry >= MAX_RETRY )
-               {
-                  throw CkError( rv );
-               }
-            }
-            else
-            {
-               throw CkError( rv );
-            }
-         }
-         catch( ... )
-         {
-            throw CkError( CKR_FUNCTION_FAILED );
-         }
-      }
-      _fileList[ dir ] = vfile;
-   }
-
-   return _fileList[ dir ];
-}
-
-
-/* ClearFileList
-Erase the dir from the cache
-*/
-void CardCache::ClearFileList( std::string const & dir )
-{
-   _fileList.erase( dir );
-}
-
-
-/* ClearAll
-Erase all cache
-*/
-void CardCache::ClearAll( )
-{
-   _fileCache.clear( );
-   _contCache.clear( );
-   _fileList.clear( );
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,65 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_cardcache_h
-#define _include_cardcache_h
-
-
-#include "cardmoduleservice.h"
-
-
-#include <map>
-#include <string>
-#include <vector>
-
-class CardCache
-{
-public:
-   struct Container
-   {
-      u1Array exchPublicExponent;
-      u1Array exchModulus;
-      u1Array signPublicExponent;
-      u1Array signModulus;
-   };
-
-   CardCache(CardModuleService *  mscm);
-   void WriteFile(std::string const & path, u1Array const & data);
-   const u1Array & ReadFile(std::string const & path);
-   void ClearFile(std::string const & path);
-
-   const Container & ReadContainer( int const &ctrIndex ) const;
-   void ClearContainer(int const &ctrIndex);
-
-   const std::vector<std::string> & FileList(std::string const & dir);
-   void ClearFileList(std::string const & dir);
-
-   void ClearAll();
-
-private:
-   void ManageGC( void );
-   CardModuleService * _mscm;
-   mutable std::map<std::string, u1Array> _fileCache;
-   mutable std::map<int, Container> _contCache;
-   mutable std::map<std::string, vector<string> > _fileList;
-
-};
-
-#endif // _include_cardcache_h

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/cardmod.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardmod.h	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardmod.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,1874 @@
+//==============================================================;
+//
+//  CARDMOD.H
+//
+//  Abstract:
+//      This is the header file commonly used for card modules.
+//
+//  This source code is only intended as a supplement to existing Microsoft
+//  documentation.
+//
+//  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
+//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
+//  PURPOSE.
+//
+//  Copyright (C) Microsoft Corporation.  All Rights Reserved.
+//
+//==============================================================;
+#ifndef __CARDMOD__H__
+#define __CARDMOD__H__
+
+#ifdef WIN32
+#include <windows.h>
+#include <wincrypt.h>
+#pragma warning(push)
+#pragma warning(disable:4201)
+// Disable error C4201 in public header
+//  nonstandard extension used : nameless struct/union
+#include <winscard.h>
+#pragma warning(pop)
+#include <specstrings.h>
+#include <bcrypt.h>
+#else
+#ifdef __APPLE__
+#include <PCSC/winscard.h>
+#include <PCSC/wintypes.h>
+#else
+#include <winscard.h>
+#include <stdint.h>
+typedef const wchar_t* LPCWSTR;
+#endif
+typedef ULONG * ULONG_PTR;
+typedef BYTE * PBYTE;
+typedef int ALG_ID;
+typedef void * PVOID;
+typedef size_t SIZE_T;
+typedef uint16_t WCHAR;
+typedef uint16_t* LPWSTR, *PWSTR;
+#define __deref_opt_out_bcount(x)
+#define __deref_out_bcount_opt(x)
+#define __deref_out_bcount(x)
+#define __deref_out_ecount(x)
+#define __in
+#define IN
+#define __in_bcount(x)
+#define __in_ecount(x)
+#define __in_opt
+#define __inout
+#define __out
+#define OUT
+#define __out_bcount_part_opt(x, y)
+#define __out_bcount(x)
+#define __out_opt
+#define WINAPI
+#endif
+
+// This value should be passed to
+//
+//  SCardSetCardTypeProviderName
+//  SCardGetCardTypeProviderName
+//
+// in order to query and set the Card Specific Module to be used
+// for a given card.
+#define SCARD_PROVIDER_CARD_MODULE 0x80000001
+
+typedef struct _CARD_DATA CARD_DATA, *PCARD_DATA;
+
+typedef ULONG_PTR CARD_KEY_HANDLE, *PCARD_KEY_HANDLE;
+
+//
+// This define can be used as a return value for queries involving
+// card data that may be impossible to determine on a given card
+// OS, such as the number of available card storage bytes.
+//
+#define CARD_DATA_VALUE_UNKNOWN                     ((DWORD) -1)
+
+//
+// Well Known Logical Names
+//
+
+//
+// Logical Directory Names
+//
+
+// Second-level logical directories
+
+#define szBASE_CSP_DIR                             "mscp"
+
+#define szINTERMEDIATE_CERTS_DIR                   "mscerts"
+
+//
+// Logical File Names
+//
+// When requesting (or otherwise referring to) any logical file, the full path
+// must be used, including when referring to well known files.  For example,
+// to request the wszCONTAINER_MAP_FILE, the provided name will be
+// "/mscp/cmapfile".
+//
+
+// Well known logical files under Microsoft
+#define szCACHE_FILE                               "cardcf"
+
+#define szCARD_IDENTIFIER_FILE                     "cardid"
+
+// Well known logical files under CSP
+#define szCONTAINER_MAP_FILE                       "cmapfile"
+#define szROOT_STORE_FILE                          "msroots"
+
+//
+// Well known logical files under User Certs
+//
+// The following prefixes are appended with the container index of the
+// associated key.  For example, the certificate associated with the
+// Key Exchange key in container index 2 will have the name:
+//  "/mscp/kxc2"
+//
+#define szUSER_SIGNATURE_CERT_PREFIX               "ksc"
+#define szUSER_KEYEXCHANGE_CERT_PREFIX             "kxc"
+#define szUSER_SIGNATURE_PRIVATE_KEY_PREFIX        "kss"
+#define szUSER_SIGNATURE_PUBLIC_KEY_PREFIX         "ksp"
+#define szUSER_KEYEXCHANGE_PRIVATE_KEY_PREFIX      "kxs"
+#define szUSER_KEYEXCHANGE_PUBLIC_KEY_PREFIX       "kxp"
+
+//
+// Logical Card User Names
+//
+#define wszCARD_USER_EVERYONE                       L"anonymous"
+#define wszCARD_USER_USER                           L"user"
+#define wszCARD_USER_ADMIN                          L"admin"
+
+// new ecc key specs
+
+#define AT_ECDSA_P256      3
+#define AT_ECDSA_P384      4
+#define AT_ECDSA_P521      5
+#define AT_ECDHE_P256      6
+#define AT_ECDHE_P384      7
+#define AT_ECDHE_P521      8
+        
+//
+// Type: CARD_CACHE_FILE_FORMAT
+//
+// This struct is used as the file format of the cache file,
+// as stored on the card.
+//
+
+#define CARD_CACHE_FILE_CURRENT_VERSION         1
+
+typedef struct _CARD_CACHE_FILE_FORMAT
+{
+    BYTE bVersion;
+    BYTE bPinsFreshness;
+
+    WORD wContainersFreshness;
+    WORD wFilesFreshness;
+} CARD_CACHE_FILE_FORMAT, *PCARD_CACHE_FILE_FORMAT;
+
+//
+// Type: CONTAINER_MAP_RECORD
+//
+// This structure describes the format of the Base CSP's container map file,
+// stored on the card.  This is well-known logical file wszCONTAINER_MAP_FILE.
+// The file consists of zero or more of these records.
+//
+#define MAX_CONTAINER_NAME_LEN                  39
+
+// This flag is set in the CONTAINER_MAP_RECORD bFlags member if the
+// corresponding container is valid and currently exists on the card.
+// If the container is deleted, its bFlags field must be cleared.
+#define CONTAINER_MAP_VALID_CONTAINER           1
+
+// This flag is set in the CONTAINER_MAP_RECORD bFlags
+// member if the corresponding container is the default container on the card.
+#define CONTAINER_MAP_DEFAULT_CONTAINER         2
+
+typedef struct _CONTAINER_MAP_RECORD
+{
+    WCHAR wszGuid [MAX_CONTAINER_NAME_LEN + 1];
+    BYTE bFlags;
+    BYTE bReserved;
+    WORD wSigKeySizeBits;
+    WORD wKeyExchangeKeySizeBits;
+} CONTAINER_MAP_RECORD, *PCONTAINER_MAP_RECORD;
+
+//
+// Converts a card filename string from unicode to ansi
+//
+DWORD 
+WINAPI 
+I_CardConvertFileNameToAnsi(
+    __in    PCARD_DATA pCardData,
+    __in    LPWSTR wszUnicodeName,
+    __out   LPSTR *ppszAnsiName);
+
+// Logical Directory Access Conditions
+typedef enum
+{
+    InvalidDirAc = 0,
+
+    // User Read, Write
+    UserCreateDeleteDirAc,
+
+    // Admin Write
+    AdminCreateDeleteDirAc
+
+} CARD_DIRECTORY_ACCESS_CONDITION;
+
+// Logical File Access Conditions
+typedef enum
+{
+    // Invalid value, chosed to cooincide with common initialization
+    // of memory
+    InvalidAc = 0,
+
+    // Everyone     Read
+    // User         Read, Write
+    //
+    // Example:  A user certificate file.
+    EveryoneReadUserWriteAc,
+
+    // Everyone     None
+    // User         Write, Execute
+    //
+    // Example:  A private key file.
+    UserWriteExecuteAc,
+
+    // Everyone     Read
+    // Admin        Read, Write
+    //
+    // Example:  The Card Identifier file.
+    EveryoneReadAdminWriteAc,
+
+    // Explicit value to set when it is desired to say that
+    // it is unknown
+    UnknownAc,
+
+    // Everyone No Access 
+    // User Read Write 
+    // 
+    // Example:  A password wallet file. 
+
+    UserReadWriteAc,
+    // Everyone/User No Access 
+    // Admin Read Write 
+    // 
+    // Example:  Administration data. 
+
+    AdminReadWriteAc
+} CARD_FILE_ACCESS_CONDITION;
+
+//
+// Function: CardAcquireContext
+//
+// Purpose: Initialize the CARD_DATA structure which will be used by
+//          the CSP to interact with a specific card.
+//
+typedef DWORD (WINAPI *PFN_CARD_ACQUIRE_CONTEXT)(
+    __inout     PCARD_DATA  pCardData,
+    __in        DWORD       dwFlags);
+
+DWORD
+WINAPI
+CardAcquireContext(
+    __inout     PCARD_DATA  pCardData,
+    __in        DWORD       dwFlags);
+
+//
+// Function: CardDeleteContext
+//
+// Purpose: Free resources consumed by the CARD_DATA structure.
+//
+typedef DWORD (WINAPI *PFN_CARD_DELETE_CONTEXT)(
+    __inout     PCARD_DATA  pCardData);
+
+DWORD
+WINAPI
+CardDeleteContext(
+    __inout     PCARD_DATA  pCardData);
+
+//
+// Function: CardQueryCapabilities
+//
+// Purpose: Query the card module for specific functionality
+//          provided by this card.
+//
+#define CARD_CAPABILITIES_CURRENT_VERSION 1
+
+typedef struct _CARD_CAPABILITIES
+{
+    DWORD   dwVersion;
+    BOOL    fCertificateCompression;
+    BOOL    fKeyGen;
+} CARD_CAPABILITIES, *PCARD_CAPABILITIES;
+
+typedef DWORD (WINAPI *PFN_CARD_QUERY_CAPABILITIES)(
+    __in      PCARD_DATA          pCardData,
+    __inout   PCARD_CAPABILITIES  pCardCapabilities);
+
+DWORD
+WINAPI
+CardQueryCapabilities(
+    __in      PCARD_DATA          pCardData,
+    __inout   PCARD_CAPABILITIES  pCardCapabilities);
+
+// ****************
+// PIN SUPPORT
+// ****************
+
+//
+// There are 8 PINs currently defined in version 6. PIN values 0, 1 and 2 are 
+// reserved for backwards compatibility, whereas PIN values 3-7 can be used 
+// as additional PINs to protect key containers.
+//
+
+typedef     DWORD                       PIN_ID, *PPIN_ID;
+typedef     DWORD                       PIN_SET, *PPIN_SET;
+
+#define     MAX_PINS                    8
+
+#define     ROLE_EVERYONE               0
+#define     ROLE_USER                   1
+#define     ROLE_ADMIN                  2
+
+#define     PIN_SET_NONE                0x00
+#define     PIN_SET_ALL_ROLES           0xFF
+#define     CREATE_PIN_SET(PinId)       (1 << PinId)
+#define     SET_PIN(PinSet, PinId)      PinSet |= CREATE_PIN_SET(PinId)
+#define     IS_PIN_SET(PinSet, PinId)   (0 != (PinSet & CREATE_PIN_SET(PinId)))
+#define     CLEAR_PIN(PinSet, PinId)    PinSet &= ~CREATE_PIN_SET(PinId)
+
+#define     PIN_CHANGE_FLAG_UNBLOCK     0x01
+#define     PIN_CHANGE_FLAG_CHANGEPIN   0x02
+
+#define     CP_CACHE_MODE_GLOBAL_CACHE  1
+#define     CP_CACHE_MODE_SESSION_ONLY  2
+#define     CP_CACHE_MODE_NO_CACHE      3
+
+#define     CARD_AUTHENTICATE_GENERATE_SESSION_PIN      0x10000000
+#define     CARD_AUTHENTICATE_SESSION_PIN               0x20000000
+
+#define     CARD_PIN_STRENGTH_PLAINTEXT                 0x1
+#define     CARD_PIN_STRENGTH_SESSION_PIN               0x2 
+
+#define     CARD_PIN_SILENT_CONTEXT                     0x00000040
+
+typedef enum
+{
+    AlphaNumericPinType = 0,            // Regular PIN
+    ExternalPinType,                    // Biometric PIN
+    ChallengeResponsePinType,           // Challenge/Response PIN
+    EmptyPinType                        // No PIN
+} SECRET_TYPE;
+
+typedef enum
+{
+    AuthenticationPin,                  // Authentication PIN
+    DigitalSignaturePin,                // Digital Signature PIN
+    EncryptionPin,                      // Encryption PIN
+    NonRepudiationPin,                  // Non Repudiation PIN
+    AdministratorPin,                   // Administrator PIN
+    PrimaryCardPin,                     // Primary Card PIN
+    UnblockOnlyPin                      // Unblock only PIN (PUK)
+} SECRET_PURPOSE;
+
+typedef enum
+{
+    PinCacheNormal = 0,
+    PinCacheTimed,
+    PinCacheNone,
+    PinCacheAlwaysPrompt
+} PIN_CACHE_POLICY_TYPE;
+
+#define      PIN_CACHE_POLICY_CURRENT_VERSION     6
+
+typedef struct _PIN_CACHE_POLICY
+{
+    DWORD                                 dwVersion;
+    PIN_CACHE_POLICY_TYPE                 PinCachePolicyType;
+    DWORD                                 dwPinCachePolicyInfo;
+} PIN_CACHE_POLICY, *PPIN_CACHE_POLICY;
+
+#define      PIN_INFO_CURRENT_VERSION             6
+
+#define      PIN_INFO_REQUIRE_SECURE_ENTRY        1
+
+typedef struct _PIN_INFO
+{
+    DWORD                                 dwVersion;
+    SECRET_TYPE                           PinType;
+    SECRET_PURPOSE                        PinPurpose;
+    PIN_SET                               dwChangePermission;
+    PIN_SET                               dwUnblockPermission;
+    PIN_CACHE_POLICY                      PinCachePolicy;
+    DWORD                                 dwFlags;
+} PIN_INFO, *PPIN_INFO;
+// Gemalto custom !
+typedef struct _PIN_INFO_EX
+{
+    IN OUT  DWORD                                 dwVersion;
+    OUT     SECRET_TYPE                           PinType;
+    OUT     SECRET_PURPOSE                        PinPurpose;
+    OUT     PIN_SET                               dwChangePermission;
+    OUT     PIN_SET                               dwUnblockPermission;
+    OUT     PIN_CACHE_POLICY                      PinCachePolicy;
+    OUT     DWORD                                 dwFlags;
+    OUT     DWORD                                 dwFlagsEx;
+} PIN_INFO_EX, *PPIN_INFO_EX;
+
+typedef DWORD (WINAPI *PFN_CARD_GET_CHALLENGE_EX)(
+    __in                                PCARD_DATA  pCardData,
+    __in                                PIN_ID      PinId,
+    __out_bcount(*pcbChallengeData)     PBYTE       *ppbChallengeData,
+    __out                               PDWORD      pcbChallengeData,
+    __in                                DWORD       dwFlags);
+
+DWORD
+WINAPI
+CardGetChallengeEx(
+    __in                                    PCARD_DATA  pCardData,
+    __in                                    PIN_ID      PinId,
+    __deref_out_bcount(*pcbChallengeData)   PBYTE       *ppbChallengeData,
+    __out                                   PDWORD      pcbChallengeData,
+    __in                                    DWORD       dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_AUTHENTICATE_EX)(
+    __in                                    PCARD_DATA  pCardData,
+    __in                                    PIN_ID      PinId,
+    __in                                    DWORD       dwFlags,
+    __in_bcount(cbPinData)                  PBYTE       pbPinData,
+    __in                                    DWORD       cbPinData,
+    __deref_opt_out_bcount(*pcbSessionPin)  PBYTE       *ppbSessionPin,
+    __out_opt                               PDWORD      pcbSessionPin,
+    __out_opt                               PDWORD      pcAttemptsRemaining);
+
+DWORD 
+WINAPI 
+CardAuthenticateEx(
+    __in                                    PCARD_DATA  pCardData,
+    __in                                    PIN_ID      PinId,
+    __in                                    DWORD       dwFlags,
+    __in_bcount(cbPinData)                  PBYTE       pbPinData,
+    __in                                    DWORD       cbPinData,
+    __deref_opt_out_bcount(*pcbSessionPin)  PBYTE       *ppbSessionPin,
+    __out_opt                               PDWORD      pcbSessionPin,
+    __out_opt                               PDWORD      pcAttemptsRemaining);
+
+typedef DWORD (WINAPI *PFN_CARD_CHANGE_AUTHENTICATOR_EX)(
+    __in                                    PCARD_DATA  pCardData,
+    __in                                    DWORD       dwFlags,
+    __in                                    PIN_ID      dwAuthenticatingPinId,
+    __in_bcount(cbAuthenticatingPinData)    PBYTE       pbAuthenticatingPinData,
+    __in                                    DWORD       cbAuthenticatingPinData,
+    __in                                    PIN_ID      dwTargetPinId,
+    __in_bcount(cbTargetData)               PBYTE       pbTargetData,
+    __in                                    DWORD       cbTargetData,
+    __in                                    DWORD       cRetryCount,
+    __out_opt                               PDWORD      pcAttemptsRemaining);
+
+DWORD 
+WINAPI 
+CardChangeAuthenticatorEx(
+    __in                                    PCARD_DATA  pCardData,
+    __in                                    DWORD       dwFlags,
+    __in                                    PIN_ID      dwAuthenticatingPinId,
+    __in_bcount(cbAuthenticatingPinData)    PBYTE       pbAuthenticatingPinData,
+    __in                                    DWORD       cbAuthenticatingPinData,
+    __in                                    PIN_ID      dwTargetPinId,
+    __in_bcount(cbTargetData)               PBYTE       pbTargetData,
+    __in                                    DWORD       cbTargetData,
+    __in                                    DWORD       cRetryCount,
+    __out_opt                               PDWORD      pcAttemptsRemaining);
+
+typedef DWORD (WINAPI *PFN_CARD_DEAUTHENTICATE_EX)(
+    __in    PCARD_DATA   pCardData,
+    __in    PIN_SET      PinId,
+    __in    DWORD        dwFlags);
+
+DWORD 
+WINAPI 
+CardDeauthenticateEx(
+    __in    PCARD_DATA   pCardData,
+    __in    PIN_SET      PinId,
+    __in    DWORD        dwFlags);
+
+//
+// Function: CardDeleteContainer
+//
+// Purpose: Delete the specified key container.
+//
+typedef DWORD (WINAPI *PFN_CARD_DELETE_CONTAINER)(
+    __in    PCARD_DATA  pCardData,
+    __in    BYTE        bContainerIndex,
+    __in    DWORD       dwReserved);
+
+DWORD
+WINAPI
+CardDeleteContainer(
+    __in    PCARD_DATA  pCardData,
+    __in    BYTE        bContainerIndex,
+    __in    DWORD       dwReserved);
+
+//
+// Function: CardCreateContainer
+//
+
+#define CARD_CREATE_CONTAINER_KEY_GEN           1
+#define CARD_CREATE_CONTAINER_KEY_IMPORT        2
+
+typedef DWORD (WINAPI *PFN_CARD_CREATE_CONTAINER)(
+    __in    PCARD_DATA  pCardData,
+    __in    BYTE        bContainerIndex,
+    __in    DWORD       dwFlags,
+    __in    DWORD       dwKeySpec,
+    __in    DWORD       dwKeySize,
+    __in    PBYTE       pbKeyData);
+
+DWORD
+WINAPI
+CardCreateContainer(
+    __in    PCARD_DATA  pCardData,
+    __in    BYTE        bContainerIndex,
+    __in    DWORD       dwFlags,
+    __in    DWORD       dwKeySpec,
+    __in    DWORD       dwKeySize,
+    __in    PBYTE       pbKeyData);
+
+//
+// Function: CardCreateContainerEx
+//
+
+typedef DWORD (WINAPI *PFN_CARD_CREATE_CONTAINER_EX)(
+    __in    PCARD_DATA  pCardData,
+    __in    BYTE        bContainerIndex,
+    __in    DWORD       dwFlags,
+    __in    DWORD       dwKeySpec,
+    __in    DWORD       dwKeySize,
+    __in    PBYTE       pbKeyData,
+    __in    PIN_ID      PinId);
+
+DWORD
+WINAPI
+CardCreateContainerEx(
+    __in    PCARD_DATA  pCardData,
+    __in    BYTE        bContainerIndex,
+    __in    DWORD       dwFlags,
+    __in    DWORD       dwKeySpec,
+    __in    DWORD       dwKeySize,
+    __in    PBYTE       pbKeyData,
+    __in    PIN_ID      PinId);
+
+//
+// Function: CardGetContainerInfo
+//
+// Purpose: Query for all public information available about
+//          the named key container.  This includes the Signature
+//          and Key Exchange type public keys, if they exist.
+//
+//          The pbSigPublicKey and pbKeyExPublicKey buffers contain the
+//          Signature and Key Exchange public keys, respectively, if they
+//          exist.  The format of these buffers is a Crypto
+//          API PUBLICKEYBLOB -
+//
+//              BLOBHEADER
+//              RSAPUBKEY
+//              modulus
+//          
+//          In the case of ECC public keys, the pbSigPublicKey will contain
+//          the ECDSA key and pbKeyExPublicKey will contain the ECDH key if
+//          they exist. ECC key structure -
+//
+//              BCRYPT_ECCKEY_BLOB
+//              X coord (big endian)
+//              Y coord (big endian)
+//
+#define CONTAINER_INFO_CURRENT_VERSION 1
+
+typedef struct _CONTAINER_INFO
+{
+    DWORD dwVersion;
+    DWORD dwReserved;
+
+    DWORD cbSigPublicKey;
+    PBYTE pbSigPublicKey;
+
+    DWORD cbKeyExPublicKey;
+    PBYTE pbKeyExPublicKey;
+} CONTAINER_INFO, *PCONTAINER_INFO;
+
+typedef DWORD (WINAPI *PFN_CARD_GET_CONTAINER_INFO)(
+    __in    PCARD_DATA      pCardData,
+    __in    BYTE            bContainerIndex,
+    __in    DWORD           dwFlags,
+    __inout PCONTAINER_INFO pContainerInfo);
+
+DWORD
+WINAPI
+CardGetContainerInfo(
+    __in    PCARD_DATA      pCardData,
+    __in    BYTE            bContainerIndex,
+    __in    DWORD           dwFlags,
+    __inout PCONTAINER_INFO pContainerInfo);
+
+//
+// Function: CardAuthenticatePin
+//
+typedef DWORD (WINAPI *PFN_CARD_AUTHENTICATE_PIN)(
+    __in                   PCARD_DATA   pCardData,
+    __in                   LPWSTR       pwszUserId,
+    __in_bcount(cbPin)     PBYTE        pbPin,
+    __in                   DWORD        cbPin,
+    __out_opt              PDWORD       pcAttemptsRemaining);
+
+
+DWORD
+WINAPI
+CardAuthenticatePin(
+    __in                   PCARD_DATA   pCardData,
+    __in                   LPWSTR       pwszUserId,
+    __in_bcount(cbPin)     PBYTE        pbPin,
+    __in                   DWORD        cbPin,
+    __out_opt              PDWORD       pcAttemptsRemaining);
+
+//
+// Function: CardGetChallenge
+//
+typedef DWORD (WINAPI *PFN_CARD_GET_CHALLENGE)(
+    __in                                    PCARD_DATA  pCardData,
+    __deref_out_bcount(*pcbChallengeData)   PBYTE       *ppbChallengeData,
+    __out                                   PDWORD      pcbChallengeData);
+
+DWORD
+WINAPI
+CardGetChallenge(
+    __in                                    PCARD_DATA  pCardData,
+    __deref_out_bcount(*pcbChallengeData)   PBYTE       *ppbChallengeData,
+    __out                                   PDWORD      pcbChallengeData);
+
+//
+// Function: CardAuthenticateChallenge
+//
+typedef DWORD (WINAPI *PFN_CARD_AUTHENTICATE_CHALLENGE)(
+    __in                             PCARD_DATA pCardData,
+    __in_bcount(cbResponseData)      PBYTE      pbResponseData,
+    __in                             DWORD      cbResponseData,
+    __out_opt                        PDWORD     pcAttemptsRemaining);
+
+DWORD
+WINAPI
+CardAuthenticateChallenge(
+    __in                             PCARD_DATA pCardData,
+    __in_bcount(cbResponseData)      PBYTE      pbResponseData,
+    __in                             DWORD      cbResponseData,
+    __out_opt                        PDWORD     pcAttemptsRemaining);
+
+//
+// Function: CardUnblockPin
+//
+#define CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE                 1
+#define CARD_AUTHENTICATE_PIN_PIN                                2
+
+typedef DWORD (WINAPI *PFN_CARD_UNBLOCK_PIN)(
+    __in                               PCARD_DATA  pCardData,
+    __in                               LPWSTR      pwszUserId,
+    __in_bcount(cbAuthenticationData)  PBYTE       pbAuthenticationData,
+    __in                               DWORD       cbAuthenticationData,
+    __in_bcount(cbNewPinData)          PBYTE       pbNewPinData,
+    __in                               DWORD       cbNewPinData,
+    __in                               DWORD       cRetryCount,
+    __in                               DWORD       dwFlags);
+
+DWORD
+WINAPI
+CardUnblockPin(
+    __in                               PCARD_DATA  pCardData,
+    __in                               LPWSTR      pwszUserId,
+    __in_bcount(cbAuthenticationData)  PBYTE       pbAuthenticationData,
+    __in                               DWORD       cbAuthenticationData,
+    __in_bcount(cbNewPinData)          PBYTE       pbNewPinData,
+    __in                               DWORD       cbNewPinData,
+    __in                               DWORD       cRetryCount,
+    __in                               DWORD       dwFlags);
+
+//
+// Function: CardChangeAuthenticator
+//
+typedef DWORD (WINAPI *PFN_CARD_CHANGE_AUTHENTICATOR)(
+    __in                                 PCARD_DATA  pCardData,
+    __in                                 LPWSTR      pwszUserId,
+    __in_bcount(cbCurrentAuthenticator)  PBYTE       pbCurrentAuthenticator,
+    __in                                 DWORD       cbCurrentAuthenticator,
+    __in_bcount(cbNewAuthenticator)      PBYTE       pbNewAuthenticator,
+    __in                                 DWORD       cbNewAuthenticator,
+    __in                                 DWORD       cRetryCount,
+    __in                                 DWORD       dwFlags,
+    __out_opt                            PDWORD      pcAttemptsRemaining);
+
+DWORD
+WINAPI
+CardChangeAuthenticator(
+    __in                                 PCARD_DATA  pCardData,
+    __in                                 LPWSTR      pwszUserId,
+    __in_bcount(cbCurrentAuthenticator)  PBYTE       pbCurrentAuthenticator,
+    __in                                 DWORD       cbCurrentAuthenticator,
+    __in_bcount(cbNewAuthenticator)      PBYTE       pbNewAuthenticator,
+    __in                                 DWORD       cbNewAuthenticator,
+    __in                                 DWORD       cRetryCount,
+    __in                                 DWORD       dwFlags,
+    __out_opt                            PDWORD      pcAttemptsRemaining);
+
+//
+// Function: CardDeauthenticate
+//
+// Purpose: De-authenticate the specified logical user name on the card.
+//
+// This is an optional API.  If implemented, this API is used instead
+// of SCARD_RESET_CARD by the Base CSP.  An example scenario is leaving
+// a transaction in which the card has been authenticated (a Pin has been
+// successfully presented).
+//
+// The pwszUserId parameter will point to a valid well-known User Name (see
+// above).
+//
+// The dwFlags parameter is currently unused and will always be zero.
+//
+// Card modules that choose to not implement this API must set the CARD_DATA
+// pfnCardDeauthenticate pointer to NULL.
+//
+typedef DWORD (WINAPI *PFN_CARD_DEAUTHENTICATE)(
+    __in      PCARD_DATA  pCardData,
+    __in      LPWSTR      pwszUserId,
+    __in      DWORD       dwFlags);
+
+DWORD
+WINAPI
+CardDeauthenticate(
+    __in    PCARD_DATA  pCardData,
+    __in    LPWSTR      pwszUserId,
+    __in    DWORD       dwFlags);
+
+// Directory Control Group
+
+//
+// Function: CardCreateDirectory
+//
+// Purpose: Register the specified application name on the card, and apply the
+//          provided access condition.
+//
+// Return Value:
+//          ERROR_FILE_EXISTS - directory already exists
+//
+typedef DWORD (WINAPI *PFN_CARD_CREATE_DIRECTORY)(
+    __in    PCARD_DATA                      pCardData,
+    __in    LPSTR                           pszDirectoryName,
+    __in    CARD_DIRECTORY_ACCESS_CONDITION AccessCondition);
+
+DWORD
+WINAPI
+CardCreateDirectory(
+    __in    PCARD_DATA                      pCardData,
+    __in    LPSTR                           pszDirectoryName,
+    __in    CARD_DIRECTORY_ACCESS_CONDITION AccessCondition);
+
+//
+// Function: CardDeleteDirectory
+//
+// Purpose: Unregister the specified application from the card.
+//
+// Return Value:
+//          SCARD_E_DIR_NOT_FOUND - directory does not exist
+//          ERROR_DIR_NOT_EMPTY - the directory is not empty
+//
+typedef DWORD (WINAPI *PFN_CARD_DELETE_DIRECTORY)(
+    __in    PCARD_DATA  pCardData,
+    __in    LPSTR       pszDirectoryName);
+
+DWORD
+WINAPI
+CardDeleteDirectory(
+    __in    PCARD_DATA  pCardData,
+    __in    LPSTR       pszDirectoryName);
+
+// File Control Group
+
+//
+// Function: CardCreateFile
+//
+typedef DWORD (WINAPI *PFN_CARD_CREATE_FILE)(
+    __in        PCARD_DATA                  pCardData,
+    __in_opt    LPSTR                       pszDirectoryName,
+    __in        LPSTR                       pszFileName,
+    __in        DWORD                       cbInitialCreationSize,
+    __in        CARD_FILE_ACCESS_CONDITION  AccessCondition);
+
+DWORD
+WINAPI
+CardCreateFile(
+    __in        PCARD_DATA                  pCardData,
+    __in_opt    LPSTR                       pszDirectoryName,
+    __in        LPSTR                       pszFileName,
+    __in        DWORD                       cbInitialCreationSize,
+    __in        CARD_FILE_ACCESS_CONDITION  AccessCondition);
+
+//
+// Function: CardReadFile
+//
+// Purpose: Read the specified file from the card.
+//
+//          The pbData parameter should be allocated
+//          by the card module and freed by the CSP.  The card module
+//          must set the cbData parameter to the size of the returned buffer.
+//
+typedef DWORD (WINAPI *PFN_CARD_READ_FILE)(
+    __in                            PCARD_DATA  pCardData,
+    __in_opt                        LPSTR       pszDirectoryName,
+    __in                            LPSTR       pszFileName,
+    __in                            DWORD       dwFlags,
+    __deref_out_bcount_opt(*pcbData)    PBYTE       *ppbData,
+    __out                           PDWORD      pcbData);
+
+DWORD
+WINAPI
+CardReadFile(
+    __in                            PCARD_DATA  pCardData,
+    __in_opt                        LPSTR       pszDirectoryName,
+    __in                            LPSTR       pszFileName,
+    __in                            DWORD       dwFlags,
+    __deref_out_bcount_opt(*pcbData)    PBYTE       *ppbData,
+    __out                           PDWORD      pcbData);
+
+//
+// Function: CardWriteFile
+//
+typedef DWORD (WINAPI *PFN_CARD_WRITE_FILE)(
+    __in                     PCARD_DATA  pCardData,
+    __in_opt                 LPSTR       pszDirectoryName,
+    __in                     LPSTR       pszFileName,
+    __in                     DWORD       dwFlags,
+    __in_bcount(cbData)      PBYTE       pbData,
+    __in                     DWORD       cbData);
+
+DWORD
+WINAPI
+CardWriteFile(
+    __in                     PCARD_DATA  pCardData,
+    __in_opt                 LPSTR       pszDirectoryName,
+    __in                     LPSTR       pszFileName,
+    __in                     DWORD       dwFlags,
+    __in_bcount(cbData)      PBYTE       pbData,
+    __in                     DWORD       cbData);
+
+//
+// Function: CardDeleteFile
+//
+typedef DWORD (WINAPI *PFN_CARD_DELETE_FILE)(
+    __in        PCARD_DATA  pCardData,
+    __in_opt    LPSTR       pszDirectoryName,
+    __in        LPSTR       pszFileName,
+    __in        DWORD       dwFlags);
+
+DWORD
+WINAPI
+CardDeleteFile(
+    __in        PCARD_DATA  pCardData,
+    __in_opt    LPSTR       pszDirectoryName,
+    __in        LPSTR       pszFileName,
+    __in        DWORD       dwFlags);
+
+//
+// Function: CardEnumFiles
+//
+// Purpose: Return a multi-string list of the general files
+//          present on this card.  The multi-string is allocated
+//          by the card module and must be freed by the CSP.
+//
+//  The caller must provide a logical file directory name in the
+//  pmwszFileNames parameter (see Logical Directory Names, above).
+//  The logical directory name indicates which group of files will be
+//  enumerated.
+//
+//  The logical directory name is expected to be a static string, so the
+//  the card module will not free it.  The card module
+//  will allocate a new buffer in *pmwszFileNames to store the multi-string
+//  list of enumerated files using pCardData->pfnCspAlloc.
+//
+//  If the function fails for any reason, *pmwszFileNames is set to NULL.
+//
+typedef DWORD (WINAPI *PFN_CARD_ENUM_FILES)(
+    __in                                PCARD_DATA  pCardData,
+    __in_opt                            LPSTR       pszDirectoryName,
+    __deref_out_ecount(*pdwcbFileName)  LPSTR       *pmszFileNames,
+    __out                               LPDWORD     pdwcbFileName,
+    __in                                DWORD       dwFlags);
+
+DWORD
+WINAPI
+CardEnumFiles(
+    __in                                PCARD_DATA  pCardData,
+    __in_opt                            LPSTR       pszDirectoryName,
+    __deref_out_ecount(*pdwcbFileName)  LPSTR      *pmszFileNames,
+    __out                               LPDWORD     pdwcbFileName,
+    __in                                DWORD       dwFlags);
+
+//
+// Function: CardGetFileInfo
+//
+#define CARD_FILE_INFO_CURRENT_VERSION 1
+
+typedef struct _CARD_FILE_INFO
+{
+    DWORD                       dwVersion;
+    DWORD                       cbFileSize;
+    CARD_FILE_ACCESS_CONDITION  AccessCondition;
+} CARD_FILE_INFO, *PCARD_FILE_INFO;
+
+typedef DWORD (WINAPI *PFN_CARD_GET_FILE_INFO)(
+    __in        PCARD_DATA      pCardData,
+    __in_opt    LPSTR           pszDirectoryName,
+    __in        LPSTR           pszFileName,
+    __inout     PCARD_FILE_INFO pCardFileInfo);
+
+DWORD
+WINAPI
+CardGetFileInfo(
+    __in        PCARD_DATA      pCardData,
+    __in_opt    LPSTR           pszDirectoryName,
+    __in        LPSTR           pszFileName,
+    __inout     PCARD_FILE_INFO pCardFileInfo);
+
+//
+// Function: CardQueryFreeSpace
+//
+#define CARD_FREE_SPACE_INFO_CURRENT_VERSION 1
+
+typedef struct _CARD_FREE_SPACE_INFO
+{
+    DWORD dwVersion;
+    DWORD dwBytesAvailable;
+    DWORD dwKeyContainersAvailable;
+    DWORD dwMaxKeyContainers;
+
+} CARD_FREE_SPACE_INFO, *PCARD_FREE_SPACE_INFO;
+
+typedef DWORD (WINAPI *PFN_CARD_QUERY_FREE_SPACE)(
+    __in    PCARD_DATA              pCardData,
+    __in    DWORD                   dwFlags,
+    __inout PCARD_FREE_SPACE_INFO   pCardFreeSpaceInfo);
+
+DWORD
+WINAPI
+CardQueryFreeSpace(
+    __in    PCARD_DATA              pCardData,
+    __in    DWORD                   dwFlags,
+    __inout PCARD_FREE_SPACE_INFO   pCardFreeSpaceInfo);
+
+//
+// Function: CardQueryKeySizes
+//
+#define CARD_KEY_SIZES_CURRENT_VERSION 1
+
+typedef struct _CARD_KEY_SIZES
+{
+    DWORD dwVersion;
+    DWORD dwMinimumBitlen;
+    DWORD dwDefaultBitlen;
+    DWORD dwMaximumBitlen;
+    DWORD dwIncrementalBitlen;
+
+} CARD_KEY_SIZES, *PCARD_KEY_SIZES;
+
+typedef DWORD (WINAPI *PFN_CARD_QUERY_KEY_SIZES)(
+    __in    PCARD_DATA      pCardData,
+    __in    DWORD           dwKeySpec,
+    __in    DWORD           dwFlags,
+    __inout PCARD_KEY_SIZES pKeySizes);
+
+DWORD
+WINAPI
+CardQueryKeySizes(
+    __in    PCARD_DATA      pCardData,
+    __in    DWORD           dwKeySpec,
+    __in    DWORD           dwFlags,
+    __inout PCARD_KEY_SIZES pKeySizes);
+
+// CARD_RSA_DECRYPT_INFO_VERSION_ONE is provided for pre-v7 certified
+// mini-drivers that do not have logic for on-card padding removal.
+#define CARD_RSA_KEY_DECRYPT_INFO_VERSION_ONE   1
+
+#define CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO   2
+
+//
+// Function: CardRSADecrypt
+//
+// Purpose: Perform a private key decryption on the supplied data.  The
+//          card module should assume that pbData is the length of the
+//          key modulus.
+//
+#define CARD_RSA_KEY_DECRYPT_INFO_CURRENT_VERSION CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO
+
+typedef struct _CARD_RSA_DECRYPT_INFO
+{
+    DWORD dwVersion; 
+    BYTE bContainerIndex; 
+
+    // For RSA operations, this should be AT_SIGNATURE or AT_KEYEXCHANGE.
+    DWORD dwKeySpec;
+
+    // This is the buffer and length that the caller expects to be decrypted.
+    // For RSA operations, cbData is redundant since the length of the buffer
+    // should always be equal to the length of the key modulus.
+    PBYTE pbData; 
+    DWORD cbData;
+
+    // The following parameters are new in version 2 of the
+    // CARD_RSA_DECRYPT_INFO structure.
+    // Currently supported values for dwPaddingType are
+    // CARD_PADDING_PKCS1, CARD_PADDING_OAEP, and CARD_PADDING_NONE.
+    // If dwPaddingType is set to CARD_PADDING_OAEP, then pPaddingInfo
+    // will point to a BCRYPT_OAEP_PADDING_INFO structure.
+    LPVOID  pPaddingInfo;
+    DWORD   dwPaddingType;
+} CARD_RSA_DECRYPT_INFO, *PCARD_RSA_DECRYPT_INFO;
+
+typedef DWORD (WINAPI *PFN_CARD_RSA_DECRYPT)(
+    __in    PCARD_DATA              pCardData,
+    __inout PCARD_RSA_DECRYPT_INFO  pInfo);
+
+DWORD
+WINAPI
+CardRSADecrypt(
+    __in    PCARD_DATA              pCardData,
+    __inout PCARD_RSA_DECRYPT_INFO  pInfo);
+
+#define CARD_PADDING_INFO_PRESENT 0x40000000
+#define CARD_BUFFER_SIZE_ONLY     0x20000000
+#define CARD_PADDING_NONE         0x00000001
+#define CARD_PADDING_PKCS1        0x00000002
+#define CARD_PADDING_PSS          0x00000004
+#define CARD_PADDING_OAEP         0x00000008
+
+// CARD_SIGNING_INFO_BASIC_VERSION is provided for thos applications
+// do not intend to support passing in the pPaddingInfo structure
+#define CARD_SIGNING_INFO_BASIC_VERSION 1
+
+//
+// Function: CardSignData
+//
+// Purpose: Sign inupt data using a specified key
+//
+#define CARD_SIGNING_INFO_CURRENT_VERSION 2
+typedef struct _CARD_SIGNING_INFO
+{
+    DWORD  dwVersion;
+
+    BYTE   bContainerIndex;
+
+    // See dwKeySpec constants
+    DWORD  dwKeySpec;
+
+    // If CARD_BUFFER_SIZE_ONLY flag is present then the card 
+    // module should return only the size of the resulting 
+    // key in cbSignedData
+    DWORD  dwSigningFlags;
+
+    // If the aiHashAlg is non zero, then it specifies the algorithm
+    // to use when padding the data using PKCS
+    ALG_ID aiHashAlg;
+
+    // This is the buffer and length that the caller expects to be signed.
+    // Signed version is allocated a buffer and put in cb/pbSignedData.  That should
+    // be freed using PFN_CSP_FREE callback.
+    PBYTE  pbData;
+    DWORD  cbData;
+
+    PBYTE  pbSignedData;
+    DWORD  cbSignedData;
+
+    // The following parameters are new in version 2 of the 
+    // CARD_SIGNING_INFO structure.
+    // If CARD_PADDING_INFO_PRESENT is set in dwSigningFlags then
+    // pPaddingInfo will point to the BCRYPT_PADDING_INFO structure
+    // defined by dwPaddingType.  Currently supported values are
+    // CARD_PADDING_PKCS1, CARD_PADDING_PSS and CARD_PADDING_NONE
+    LPVOID pPaddingInfo;
+    DWORD  dwPaddingType;
+} CARD_SIGNING_INFO, *PCARD_SIGNING_INFO;
+
+typedef DWORD (WINAPI *PFN_CARD_SIGN_DATA)(
+    __in    PCARD_DATA          pCardData,
+    __inout PCARD_SIGNING_INFO  pInfo);
+
+DWORD
+WINAPI
+CardSignData(
+    __in    PCARD_DATA          pCardData,
+    __inout PCARD_SIGNING_INFO  pInfo);
+
+//
+// Type: CARD_DH_AGREEMENT_INFO
+//
+// CARD_DH_AGREEMENT_INFO version 1 is no longer supported and should
+// not be implemented
+//
+
+#define CARD_DH_AGREEMENT_INFO_VERSION 2
+
+typedef struct _CARD_DH_AGREEMENT_INFO
+{
+    DWORD dwVersion;
+    BYTE  bContainerIndex;
+    DWORD dwFlags;
+    DWORD dwPublicKey;
+    PBYTE pbPublicKey;
+    PBYTE pbReserved;
+    DWORD cbReserved;
+
+    OUT BYTE bSecretAgreementIndex;
+} CARD_DH_AGREEMENT_INFO, *PCARD_DH_AGREEMENT_INFO;
+
+//
+// Function:  CardConstructDHAgreement
+//
+// Purpose: compute a DH secret agreement from a ECDH key on the card
+// and the public portion of another ECDH key
+//
+
+typedef DWORD (WINAPI *PFN_CARD_CONSTRUCT_DH_AGREEMENT)(
+    __in    PCARD_DATA pCardData,
+    __inout PCARD_DH_AGREEMENT_INFO pAgreementInfo);
+
+DWORD 
+WINAPI 
+CardConstructDHAgreement(
+    __in    PCARD_DATA pCardData,
+    __inout PCARD_DH_AGREEMENT_INFO pAgreementInfo);
+
+//
+// Type: CARD_DERIVE_KEY_INFO
+//
+#define CARD_DERIVE_KEY_VERSION 1
+#define CARD_DERIVE_KEY_VERSION_TWO     2
+#define CARD_DERIVE_KEY_CURRENT_VERSION CARD_DERIVE_KEY_VERSION_TWO
+
+// If CARD_RETURN_KEY_HANDLE is passed then the card module should return a
+// key handle instead of the key derivation data
+#define CARD_RETURN_KEY_HANDLE          0x1000000
+
+typedef struct _CARD_DERIVE_KEY
+{
+    DWORD             dwVersion;
+   
+    // If CARD_BUFFER_SIZE_ONLY is passed then the card module
+    // should return only the size of the resulting key in
+    // cbDerivedKey 
+    DWORD             dwFlags;
+    LPWSTR            pwszKDF;
+    BYTE              bSecretAgreementIndex;     
+
+    PVOID             pParameterList;
+
+    PBYTE             pbDerivedKey;
+    DWORD             cbDerivedKey;
+
+    // The following parameter can be used by the card to determine 
+    // key derivation material and to pass back a symmetric key handle
+    // as a result of the key derivation algorithm
+    LPWSTR            pwszAlgId;
+    DWORD             dwKeyLen;
+    CARD_KEY_HANDLE   hKey;
+} CARD_DERIVE_KEY, *PCARD_DERIVE_KEY;
+
+//
+// Function:  CardDeriveKey
+//
+// Purpose: Generate a dervived session key using a generated agreed 
+// secret and various other parameters.
+//
+
+typedef DWORD (WINAPI *PFN_CARD_DERIVE_KEY)(
+    __in    PCARD_DATA pCardData,
+    __inout PCARD_DERIVE_KEY pAgreementInfo);
+
+DWORD 
+WINAPI 
+CardDeriveKey(
+    __in    PCARD_DATA pCardData,
+    __inout PCARD_DERIVE_KEY pAgreementInfo);
+
+//
+// Function:  CardDestroyAgreement
+//
+// Purpose: Force a deletion of the DH agreed secret.
+//
+
+typedef DWORD (WINAPI *PFN_CARD_DESTROY_DH_AGREEMENT)(
+    __in PCARD_DATA pCardData,
+    __in BYTE       bSecretAgreementIndex,
+    __in DWORD      dwFlags);
+
+DWORD 
+WINAPI 
+CardDestroyDHAgreement(
+    __in PCARD_DATA pCardData,
+    __in BYTE       bSecretAgreementIndex,
+    __in DWORD      dwFlags);
+
+//
+// Function:  CspGetDHAgreement
+//
+// Purpose: The CARD_DERIVE_KEY structure contains a list of parameters
+// (pParameterList) which might contain a reference to one or more addition
+// agreed secrets (KDF_NCRYPT_SECRET_HANDLE).  This callback is provided by
+// the caller of CardDeriveKey and will translate the parameter into the
+// on card agreed secret handle.
+//
+
+typedef DWORD (WINAPI *PFN_CSP_GET_DH_AGREEMENT)(
+    __in    PCARD_DATA  pCardData,
+    __in    PVOID       hSecretAgreement,
+    __out   BYTE*       pbSecretAgreementIndex,
+    __in    DWORD       dwFlags);
+
+DWORD 
+WINAPI 
+CspGetDHAgreement(
+    __in    PCARD_DATA  pCardData,
+    __in    PVOID       hSecretAgreement,
+    __out   BYTE*       pbSecretAgreementIndex,
+    __in    DWORD       dwFlags);
+
+//
+// Memory Management Routines
+//
+// These routines are supplied to the card module
+// by the calling CSP.
+//
+
+//
+// Function: PFN_CSP_ALLOC
+//
+typedef LPVOID (WINAPI *PFN_CSP_ALLOC)(
+    __in      SIZE_T      Size);
+
+//
+// Function: PFN_CSP_REALLOC
+//
+typedef LPVOID (WINAPI *PFN_CSP_REALLOC)(
+    __in      LPVOID      Address,
+    __in      SIZE_T      Size);
+
+//
+// Function: PFN_CSP_FREE
+//
+// Note: Data allocated for the CSP by the card module must
+//       be freed by the CSP.
+//
+typedef void (WINAPI *PFN_CSP_FREE)(
+    __in      LPVOID      Address);
+
+//
+// Function: PFN_CSP_CACHE_ADD_FILE
+//
+// A copy of the pbData parameter is added to the cache.
+//
+typedef DWORD (WINAPI *PFN_CSP_CACHE_ADD_FILE)(
+    __in                PVOID       pvCacheContext,
+    __in                LPWSTR      wszTag,
+    __in                DWORD       dwFlags,
+    __in_bcount(cbData) PBYTE       pbData,
+    __in                DWORD       cbData);
+
+//
+// Function: PFN_CSP_CACHE_LOOKUP_FILE
+//
+// If the cache lookup is successful,
+// the caller must free the *ppbData pointer with pfnCspFree.
+//
+typedef DWORD (WINAPI *PFN_CSP_CACHE_LOOKUP_FILE)(
+    __in                            PVOID       pvCacheContext,
+    __in                            LPWSTR      wszTag,
+    __in                            DWORD       dwFlags,
+    __deref_out_bcount(*pcbData)    PBYTE      *ppbData,
+    __out                           PDWORD      pcbData);
+
+//
+// Function: PFN_CSP_CACHE_DELETE_FILE
+//
+// Deletes the specified item from the cache.
+//
+typedef DWORD (WINAPI *PFN_CSP_CACHE_DELETE_FILE)(
+    __in      PVOID       pvCacheContext,
+    __in      LPWSTR      wszTag,
+    __in      DWORD       dwFlags);
+
+//
+// Function: PFN_CSP_PAD_DATA
+//
+// Callback to pad buffer for crypto operation.  Used when
+// the card does not provide this.
+//
+typedef DWORD (WINAPI *PFN_CSP_PAD_DATA)(
+    __in                                    PCARD_SIGNING_INFO  pSigningInfo,
+    __in                                    DWORD               cbMaxWidth,
+    __out                                   DWORD*              pcbPaddedBuffer,
+    __deref_out_bcount(*pcbPaddedBuffer)    PBYTE*              ppbPaddedBuffer);
+
+//
+// Function: PFN_CSP_UNPAD_DATA
+//
+// Callback to unpad buffer for crypto operation. Used when
+// the card does not provide this.
+//
+typedef DWORD (WINAPI *PFN_CSP_UNPAD_DATA)(
+    __in                                    PCARD_RSA_DECRYPT_INFO  pRSADecryptInfo,
+    __out                                   DWORD*                  pcbUnpaddedData,
+    __deref_out_bcount(*pcbUnpaddedData)    PBYTE*                  ppbUnpaddedData);
+
+// *******************
+// Container Porperties
+// *******************
+
+#define CCP_CONTAINER_INFO             L"Container Info"        // Read only
+#define CCP_PIN_IDENTIFIER             L"PIN Identifier"        // Read/Write
+#define CCP_ASSOCIATED_ECDH_KEY        L"Associated ECDH Key"   // ??
+
+// Gemalto Custom
+#define CCP_CONTAINER_OBKG             L"Container OBKG"        // Read only
+
+typedef DWORD (WINAPI *PFN_CARD_GET_CONTAINER_PROPERTY)(
+    __in                                        PCARD_DATA  pCardData,
+    __in                                        BYTE        bContainerIndex,
+    __in                                        LPCWSTR     wszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE       pbData,
+    __in                                        DWORD       cbData,
+    __out                                       PDWORD      pdwDataLen,
+    __in                                        DWORD       dwFlags);
+
+DWORD 
+WINAPI 
+CardGetContainerProperty(
+    __in                                        PCARD_DATA  pCardData,
+    __in                                        BYTE        bContainerIndex,
+    __in                                        LPCWSTR     wszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE       pbData,
+    __in                                        DWORD       cbData,
+    __out                                       PDWORD      pdwDataLen,
+    __in                                        DWORD       dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_SET_CONTAINER_PROPERTY)(
+    __in                    PCARD_DATA  pCardData,
+    __in                    BYTE        bContainerIndex,
+    __in                    LPCWSTR     wszProperty,
+    __in_bcount(cbDataLen)  PBYTE       pbData,
+    __in                    DWORD       cbDataLen,
+    __in                    DWORD       dwFlags);
+
+DWORD 
+WINAPI 
+CardSetContainerProperty(
+    __in                    PCARD_DATA  pCardData,
+    __in                    BYTE        bContainerIndex,
+    __in                    LPCWSTR     wszProperty,
+    __in_bcount(cbDataLen)  PBYTE       pbData,
+    __in                    DWORD       cbDataLen,
+    __in                    DWORD       dwFlags);
+
+// *******************
+// Card Properties
+// *******************
+
+#define CP_CARD_FREE_SPACE              L"Free Space"              // Read only
+#define CP_CARD_CAPABILITIES            L"Capabilities"            // Read only
+#define CP_CARD_KEYSIZES                L"Key Sizes"               // Read only
+
+#define CP_CARD_READ_ONLY               L"Read Only Mode"
+#define CP_CARD_CACHE_MODE              L"Cache Mode"
+#define CP_SUPPORTS_WIN_X509_ENROLLMENT L"Supports Windows x.509 Enrollment"
+
+#define CP_CARD_GUID                    L"Card Identifier"
+#define CP_CARD_SERIAL_NO               L"Card Serial Number"
+
+#define CP_CARD_PIN_INFO                L"PIN Information"
+#define CP_CARD_LIST_PINS               L"PIN List"                // Read only
+#define CP_CARD_AUTHENTICATED_STATE     L"Authenticated State"     // Read only
+
+#define CP_CARD_PIN_STRENGTH_VERIFY     L"PIN Strength Verify"     // Read only
+#define CP_CARD_PIN_STRENGTH_CHANGE     L"PIN Strength Change"     // Read only
+#define CP_CARD_PIN_STRENGTH_UNBLOCK    L"PIN Strength Unblock"    // Read only
+
+#define CP_PARENT_WINDOW                L"Parent Window"           // Write only
+#define CP_PIN_CONTEXT_STRING           L"PIN Context String"      // Write only
+
+//// Gemalto Custom
+//#define CP_CARD_PIN_INFO_EX             L"PIN Information Extended"// Read only
+//#define CP_CARD_PIN_POLICY              L"PIN Policy"              // Read/Write
+//#define CP_CARD_PIN_CHECK               L"PIN Check"               // Write only
+//#define CP_CARD_SERIALIZE               L"Card Serialization"      // Read/Write
+//#define CP_CARD_DESERIALIZE             L"Card Deserialization"    // Read/Write
+//#define CP_CARD_VERSION_INFO            L"Card Version"            // Read only
+//#define CP_CARD_CACHE                   L"Card Cache"              // Read/Write
+//#define CP_CARD_IMPORT_ALLOWED          L"Import Allowed"          // Read/Write
+//#define CP_CARD_IMPORT_CHANGE_ALLOWED   L"Import Change Allowed"   // Read/Write
+//#define CP_CARD_CHANGE_PIN_FIRST        L"Change PIN First"        // Read/Write
+
+
+typedef DWORD (WINAPI *PFN_CARD_GET_PROPERTY)(
+    __in                                        PCARD_DATA  pCardData,
+    __in                                        LPCWSTR     wszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE       pbData,
+    __in                                        DWORD       cbData,
+    __out                                       PDWORD      pdwDataLen,
+    __in                                        DWORD       dwFlags);
+
+DWORD 
+WINAPI 
+CardGetProperty(
+    __in                                        PCARD_DATA  pCardData,
+    __in                                        LPCWSTR     wszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE       pbData,
+    __in                                        DWORD       cbData,
+    __out                                       PDWORD      pdwDataLen,
+    __in                                        DWORD       dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_SET_PROPERTY)(
+    __in                    PCARD_DATA  pCardData,
+    __in                    LPCWSTR     wszProperty,
+    __in_bcount(cbDataLen)  PBYTE       pbData,
+    __in                    DWORD       cbDataLen,
+    __in                    DWORD       dwFlags);
+
+DWORD 
+WINAPI 
+CardSetProperty(
+    __in                    PCARD_DATA  pCardData,
+    __in                    LPCWSTR     wszProperty,
+    __in_bcount(cbDataLen)  PBYTE       pbData,
+    __in                    DWORD       cbDataLen,
+    __in                    DWORD       dwFlags);
+
+// **************************
+// Secure key injection flags
+// **************************
+
+#define    CARD_SECURE_KEY_INJECTION_NO_CARD_MODE 0x1 // No card operations
+
+#define    CARD_KEY_IMPORT_PLAIN_TEXT             0x1
+#define    CARD_KEY_IMPORT_RSA_KEYEST             0x2
+#define    CARD_KEY_IMPORT_ECC_KEYEST             0x4
+#define    CARD_KEY_IMPORT_SHARED_SYMMETRIC       0x8
+
+#define    CARD_CIPHER_OPERATION       0x1 // Symmetric operations
+#define    CARD_ASYMMETRIC_OPERATION   0x2 // Asymmetric operations
+
+#define    CARD_3DES_112_ALGORITHM     BCRYPT_3DES_112_ALGORITHM  // 3DES 2 key
+#define    CARD_3DES_ALGORITHM         BCRYPT_3DES_ALGORITHM      // 3DES 3 key
+#define    CARD_AES_ALGORITHM          BCRYPT_AES_ALGORITHM
+
+#define    CARD_BLOCK_PADDING          BCRYPT_BLOCK_PADDING
+
+#define    CARD_CHAIN_MODE_CBC         BCRYPT_CHAIN_MODE_CBC
+
+// *******************************
+// Secure key injection structures
+// *******************************
+
+#ifdef WIN32
+#pragma warning(push)
+#pragma warning(disable:4200) //nonstandard extension used : zero-sized array in struct/union
+#endif
+
+typedef struct _CARD_ENCRYPTED_DATA {
+    PBYTE   pbEncryptedData;
+    DWORD   cbEncryptedData;
+} CARD_ENCRYPTED_DATA, *PCARD_ENCRYPTED_DATA;
+
+#define     CARD_IMPORT_KEYPAIR_VERSION_SEVEN   7
+#define     CARD_IMPORT_KEYPAIR_CURRENT_VERSION CARD_IMPORT_KEYPAIR_VERSION_SEVEN
+
+typedef struct _CARD_IMPORT_KEYPAIR
+{
+    DWORD   dwVersion;
+    BYTE    bContainerIndex;
+    PIN_ID  PinId;
+    DWORD   dwKeySpec;
+    DWORD   dwKeySize;
+    DWORD   cbInput;
+#ifdef WIN32    
+    BYTE    pbInput[0];
+//#else
+//    BYTE   pbInput;
+#endif
+} CARD_IMPORT_KEYPAIR, *PCARD_IMPORT_KEYPAIR;
+
+#define     CARD_CHANGE_AUTHENTICATOR_VERSION_SEVEN   7
+#define     CARD_CHANGE_AUTHENTICATOR_CURRENT_VERSION CARD_CHANGE_AUTHENTICATOR_VERSION_SEVEN
+
+typedef struct _CARD_CHANGE_AUTHENTICATOR
+{
+    DWORD   dwVersion;
+    DWORD   dwFlags;
+    PIN_ID  dwAuthenticatingPinId;
+    DWORD   cbAuthenticatingPinData;
+    PIN_ID  dwTargetPinId;
+    DWORD   cbTargetData;
+    DWORD   cRetryCount;
+#ifdef WIN32    
+    BYTE    pbData[0];
+#endif    
+    /* pbAuthenticatingPinData = pbData */
+    /* pbTargetData = pbData + cbAuthenticatingPinData */
+} CARD_CHANGE_AUTHENTICATOR, *PCARD_CHANGE_AUTHENTICATOR;
+
+#define     CARD_CHANGE_AUTHENTICATOR_RESPONSE_VERSION_SEVEN   7
+#define     CARD_CHANGE_AUTHENTICATOR_RESPONSE_CURRENT_VERSION CARD_CHANGE_AUTHENTICATOR_RESPONSE_VERSION_SEVEN
+
+typedef struct _CARD_CHANGE_AUTHENTICATOR_RESPONSE
+{
+    DWORD   dwVersion;
+    DWORD   cAttemptsRemaining;
+} CARD_CHANGE_AUTHENTICATOR_RESPONSE, *PCARD_CHANGE_AUTHENTICATOR_RESPONSE;
+
+#define     CARD_AUTHENTICATE_VERSION_SEVEN   7
+#define     CARD_AUTHENTICATE_CURRENT_VERSION CARD_AUTHENTICATE_VERSION_SEVEN
+
+typedef struct _CARD_AUTHENTICATE
+{
+    DWORD   dwVersion;
+    DWORD   dwFlags;
+    PIN_ID  PinId;
+    DWORD   cbPinData;
+#ifdef WIN32    
+    BYTE    pbPinData[0];
+#endif    
+} CARD_AUTHENTICATE, *PCARD_AUTHENTICATE;
+
+#define     CARD_AUTHENTICATE_RESPONSE_VERSION_SEVEN   7
+#define     CARD_AUTHENTICATE_RESPONSE_CURRENT_VERSION CARD_AUTHENTICATE_RESPONSE_VERSION_SEVEN
+
+typedef struct _CARD_AUTHENTICATE_RESPONSE
+{
+    DWORD   dwVersion;
+    DWORD   cbSessionPin;
+    DWORD   cAttemptsRemaining;
+#ifdef WIN32    
+    BYTE    pbSessionPin[0];
+#endif
+} CARD_AUTHENTICATE_RESPONSE, *PCARD_AUTHENTICATE_RESPONSE;
+
+#ifdef WIN32
+#pragma warning(pop)
+#endif
+
+// *******************************************************
+// Secure key injection properties / secure function names
+// *******************************************************
+
+#define CP_KEY_IMPORT_SUPPORT           L"Key Import Support"    // Read only
+#define CP_ENUM_ALGORITHMS              L"Algorithms"            // Read only
+#define CP_PADDING_SCHEMES              L"Padding Schemes"       // Read only
+#define CP_CHAINING_MODES               L"Chaining Modes"        // Read only
+
+#define CSF_IMPORT_KEYPAIR              L"Import Key Pair"
+#define CSF_CHANGE_AUTHENTICATOR        L"Change Authenticator"
+#define CSF_AUTHENTICATE                L"Authenticate"
+
+#define CKP_CHAINING_MODE               L"ChainingMode"
+#define CKP_INITIALIZATION_VECTOR       L"IV"
+#define CKP_BLOCK_LENGTH                L"BlockLength"
+
+// ******************************
+// Secure key injection functions
+// ******************************
+
+typedef DWORD (WINAPI *PFN_MD_IMPORT_SESSION_KEY)(
+    __in                    PCARD_DATA          pCardData,
+    __in                    LPCWSTR             pwszBlobType,
+    __in                    LPCWSTR             pwszAlgId,
+    __out                   PCARD_KEY_HANDLE    phKey,
+    __in_bcount(cbInput)    PBYTE               pbInput,
+    __in                    DWORD               cbInput);
+
+DWORD 
+WINAPI 
+MDImportSessionKey(
+    __in                    PCARD_DATA          pCardData,
+    __in                    LPCWSTR             pwszBlobType,
+    __in                    LPCWSTR             pwszAlgId,
+    __out                   PCARD_KEY_HANDLE    phKey,
+    __in_bcount(cbInput)    PBYTE               pbInput,
+    __in                    DWORD               cbInput);
+
+typedef DWORD (WINAPI *PFN_MD_ENCRYPT_DATA)(
+    __in                                    PCARD_DATA              pCardData,
+    __in                                    CARD_KEY_HANDLE         hKey,
+    __in                                    LPCWSTR                 pwszSecureFunction,
+    __in_bcount(cbInput)                    PBYTE                   pbInput,
+    __in                                    DWORD                   cbInput,
+    __in                                    DWORD                   dwFlags,
+    __deref_out_ecount(*pcEncryptedData)    PCARD_ENCRYPTED_DATA    *ppEncryptedData,
+    __out                                   PDWORD                  pcEncryptedData);
+
+DWORD 
+WINAPI 
+MDEncryptData(
+    __in                                    PCARD_DATA              pCardData,
+    __in                                    CARD_KEY_HANDLE         hKey,
+    __in                                    LPCWSTR                 pwszSecureFunction,
+    __in_bcount(cbInput)                    PBYTE                   pbInput,
+    __in                                    DWORD                   cbInput,
+    __in                                    DWORD                   dwFlags,
+    __deref_out_ecount(*pcEncryptedData)    PCARD_ENCRYPTED_DATA    *ppEncryptedData,
+    __out                                   PDWORD                  pcEncryptedData);
+
+typedef DWORD (WINAPI *PFN_CARD_GET_SHARED_KEY_HANDLE)(
+    __in                                PCARD_DATA          pCardData,
+    __in_bcount(cbInput)                PBYTE               pbInput,
+    __in                                DWORD               cbInput,
+    __deref_opt_out_bcount(*pcbOutput)  PBYTE               *ppbOutput,
+    __out_opt                           PDWORD              pcbOutput,
+    __out                               PCARD_KEY_HANDLE    phKey);
+
+DWORD 
+WINAPI 
+CardGetSharedKeyHandle(
+    __in                                PCARD_DATA          pCardData,
+    __in_bcount(cbInput)                PBYTE               pbInput,
+    __in                                DWORD               cbInput,
+    __deref_opt_out_bcount(*pcbOutput)  PBYTE               *ppbOutput,
+    __out_opt                           PDWORD              pcbOutput,
+    __out                               PCARD_KEY_HANDLE    phKey);
+
+typedef DWORD (WINAPI *PFN_CARD_DESTROY_KEY)(
+    __in    PCARD_DATA      pCardData,
+    __in    CARD_KEY_HANDLE hKey);
+
+DWORD 
+WINAPI 
+CardDestroyKey(
+    __in    PCARD_DATA      pCardData,
+    __in    CARD_KEY_HANDLE hKey);
+
+typedef DWORD (WINAPI *PFN_CARD_GET_ALGORITHM_PROPERTY)(
+    __in                                        PCARD_DATA  pCardData,
+    __in                                        LPCWSTR     pwszAlgId,
+    __in                                        LPCWSTR     pwszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE       pbData,
+    __in                                        DWORD       cbData,
+    __out                                       PDWORD      pdwDataLen, 
+    __in                                        DWORD       dwFlags);
+
+DWORD 
+WINAPI 
+CardGetAlgorithmProperty(
+    __in                                        PCARD_DATA  pCardData,
+    __in                                        LPCWSTR     pwszAlgId,
+    __in                                        LPCWSTR     pwszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE       pbData,
+    __in                                        DWORD       cbData,
+    __out                                       PDWORD      pdwDataLen, 
+    __in                                        DWORD       dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_GET_KEY_PROPERTY)(
+    __in                                        PCARD_DATA      pCardData,
+    __in                                        CARD_KEY_HANDLE hKey,
+    __in                                        LPCWSTR         pwszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE           pbData,
+    __in                                        DWORD           cbData,
+    __out                                       PDWORD          pdwDataLen,
+    __in                                        DWORD           dwFlags);
+
+DWORD 
+WINAPI 
+CardGetKeyProperty(
+    __in                                        PCARD_DATA      pCardData,
+    __in                                        CARD_KEY_HANDLE hKey,
+    __in                                        LPCWSTR         pwszProperty,
+    __out_bcount_part_opt(cbData, *pdwDataLen)  PBYTE           pbData,
+    __in                                        DWORD           cbData,
+    __out                                       PDWORD          pdwDataLen,
+    __in                                        DWORD           dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_SET_KEY_PROPERTY)(
+    __in                    PCARD_DATA      pCardData,
+    __in                    CARD_KEY_HANDLE hKey,
+    __in                    LPCWSTR         pwszProperty,
+    __in_bcount(cbInput)    PBYTE           pbInput,
+    __in                    DWORD           cbInput,
+    __in                    DWORD           dwFlags);
+
+DWORD 
+WINAPI 
+CardSetKeyProperty(
+    __in                    PCARD_DATA      pCardData,
+    __in                    CARD_KEY_HANDLE hKey,
+    __in                    LPCWSTR         pwszProperty,
+    __in_bcount(cbInput)    PBYTE           pbInput,
+    __in                    DWORD           cbInput,
+    __in                    DWORD           dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_IMPORT_SESSION_KEY)(
+    __in                    PCARD_DATA          pCardData,
+    __in                    BYTE                bContainerIndex,
+    __in                    LPVOID              pPaddingInfo,
+    __in                    LPCWSTR             pwszBlobType,
+    __in                    LPCWSTR             pwszAlgId,
+    __out                   PCARD_KEY_HANDLE    phKey,
+    __in_bcount(cbInput)    PBYTE               pbInput,
+    __in                    DWORD               cbInput,
+    __in                    DWORD               dwFlags);
+
+DWORD 
+WINAPI 
+CardImportSessionKey(
+    __in                    PCARD_DATA          pCardData,
+    __in                    BYTE                bContainerIndex,
+    __in                    LPVOID              pPaddingInfo,
+    __in                    LPCWSTR             pwszBlobType,
+    __in                    LPCWSTR             pwszAlgId,
+    __out                   PCARD_KEY_HANDLE    phKey,
+    __in_bcount(cbInput)    PBYTE               pbInput,
+    __in                    DWORD               cbInput,
+    __in                    DWORD               dwFlags);
+
+typedef DWORD (WINAPI *PFN_CARD_PROCESS_ENCRYPTED_DATA)(
+    __in                                            PCARD_DATA              pCardData,
+    __in                                            CARD_KEY_HANDLE         hKey,
+    __in                                            LPCWSTR                 pwszSecureFunction,
+    __in_ecount(cEncryptedData)                     PCARD_ENCRYPTED_DATA    pEncryptedData,
+    __in                                            DWORD                   cEncryptedData,
+    __out_bcount_part_opt(cbOutput, *pdwOutputLen)  PBYTE                   pbOutput,
+    __in                                            DWORD                   cbOutput,
+    __out_opt                                       PDWORD                  pdwOutputLen,
+    __in                                            DWORD                   dwFlags);
+
+DWORD 
+WINAPI 
+CardProcessEncryptedData(
+    __in                                            PCARD_DATA              pCardData,
+    __in                                            CARD_KEY_HANDLE         hKey,
+    __in                                            LPCWSTR                 pwszSecureFunction,
+    __in_ecount(cEncryptedData)                     PCARD_ENCRYPTED_DATA    pEncryptedData,
+    __in                                            DWORD                   cEncryptedData,
+    __out_bcount_part_opt(cbOutput, *pdwOutputLen)  PBYTE                   pbOutput,
+    __in                                            DWORD                   cbOutput,
+    __out_opt                                       PDWORD                  pdwOutputLen,
+    __in                                            DWORD                   dwFlags);
+
+//
+// Type: CARD_DATA
+//
+
+#define CARD_DATA_VERSION_SEVEN 7
+
+// This verison supports new features suched as enhanced support
+// for PINs, support for read-only cards, a secure PIN channel
+// and external PIN support.
+#define CARD_DATA_VERSION_SIX   6
+
+// This version supports new features such as a designed
+// CardSecretAgreement and key derivation functions.  Also
+// added is the PKCS#1 2.1 (PSS) padding format.
+#define CARD_DATA_VERSION_FIVE  5
+
+// This is the minimum version currently supported.  Those
+// applications that require basic RSA crypto functionality
+// and file operations should use this version
+#define CARD_DATA_VERSION_FOUR  4
+
+// For those apps, that want the maximum version available, use
+// CARD_DATA_CURRENT_VERSION.  Otherwise applications should
+// target a specific version that includes the functionality
+// that they require.
+#define CARD_DATA_CURRENT_VERSION CARD_DATA_VERSION_SEVEN
+
+typedef struct _CARD_DATA
+{
+    // These members must be initialized by the CSP/KSP before
+    // calling CardAcquireContext.
+
+    DWORD                               dwVersion;
+
+    PBYTE                               pbAtr;
+    DWORD                               cbAtr;
+    LPWSTR                              pwszCardName;
+
+    PFN_CSP_ALLOC                       pfnCspAlloc;
+    PFN_CSP_REALLOC                     pfnCspReAlloc;
+    PFN_CSP_FREE                        pfnCspFree;
+
+    PFN_CSP_CACHE_ADD_FILE              pfnCspCacheAddFile;
+    PFN_CSP_CACHE_LOOKUP_FILE           pfnCspCacheLookupFile;
+    PFN_CSP_CACHE_DELETE_FILE           pfnCspCacheDeleteFile;
+    PVOID                               pvCacheContext;
+
+    PFN_CSP_PAD_DATA                    pfnCspPadData;
+
+    SCARDCONTEXT                        hSCardCtx;
+    SCARDHANDLE                         hScard;
+
+    // pointer to vendor specific information
+
+    PVOID                               pvVendorSpecific;
+
+    // These members are initialized by the card module
+
+    PFN_CARD_DELETE_CONTEXT             pfnCardDeleteContext;
+    PFN_CARD_QUERY_CAPABILITIES         pfnCardQueryCapabilities;
+    PFN_CARD_DELETE_CONTAINER           pfnCardDeleteContainer;
+    PFN_CARD_CREATE_CONTAINER           pfnCardCreateContainer;
+    PFN_CARD_GET_CONTAINER_INFO         pfnCardGetContainerInfo;
+    PFN_CARD_AUTHENTICATE_PIN           pfnCardAuthenticatePin;
+    PFN_CARD_GET_CHALLENGE              pfnCardGetChallenge;
+    PFN_CARD_AUTHENTICATE_CHALLENGE     pfnCardAuthenticateChallenge;
+    PFN_CARD_UNBLOCK_PIN                pfnCardUnblockPin;
+    PFN_CARD_CHANGE_AUTHENTICATOR       pfnCardChangeAuthenticator;
+    PFN_CARD_DEAUTHENTICATE             pfnCardDeauthenticate;
+    PFN_CARD_CREATE_DIRECTORY           pfnCardCreateDirectory;
+    PFN_CARD_DELETE_DIRECTORY           pfnCardDeleteDirectory;
+    LPVOID                              pvUnused3;
+    LPVOID                              pvUnused4;
+    PFN_CARD_CREATE_FILE                pfnCardCreateFile;
+    PFN_CARD_READ_FILE                  pfnCardReadFile;
+    PFN_CARD_WRITE_FILE                 pfnCardWriteFile;
+    PFN_CARD_DELETE_FILE                pfnCardDeleteFile;
+    PFN_CARD_ENUM_FILES                 pfnCardEnumFiles;
+    PFN_CARD_GET_FILE_INFO              pfnCardGetFileInfo;
+    PFN_CARD_QUERY_FREE_SPACE           pfnCardQueryFreeSpace;
+    PFN_CARD_QUERY_KEY_SIZES            pfnCardQueryKeySizes;
+
+    PFN_CARD_SIGN_DATA                  pfnCardSignData;
+    PFN_CARD_RSA_DECRYPT                pfnCardRSADecrypt;
+    PFN_CARD_CONSTRUCT_DH_AGREEMENT     pfnCardConstructDHAgreement;
+
+    // New functions in version five.
+    PFN_CARD_DERIVE_KEY                 pfnCardDeriveKey;
+    PFN_CARD_DESTROY_DH_AGREEMENT       pfnCardDestroyDHAgreement;
+    PFN_CSP_GET_DH_AGREEMENT            pfnCspGetDHAgreement;
+
+    // version 6 additions below here
+    PFN_CARD_GET_CHALLENGE_EX           pfnCardGetChallengeEx;
+    PFN_CARD_AUTHENTICATE_EX            pfnCardAuthenticateEx;
+    PFN_CARD_CHANGE_AUTHENTICATOR_EX    pfnCardChangeAuthenticatorEx;
+    PFN_CARD_DEAUTHENTICATE_EX          pfnCardDeauthenticateEx;
+    PFN_CARD_GET_CONTAINER_PROPERTY     pfnCardGetContainerProperty;
+    PFN_CARD_SET_CONTAINER_PROPERTY     pfnCardSetContainerProperty;
+    PFN_CARD_GET_PROPERTY               pfnCardGetProperty;
+    PFN_CARD_SET_PROPERTY               pfnCardSetProperty;
+
+    // version 7 additions below here
+    PFN_CSP_UNPAD_DATA                  pfnCspUnpadData;
+    PFN_MD_IMPORT_SESSION_KEY           pfnMDImportSessionKey;
+    PFN_MD_ENCRYPT_DATA                 pfnMDEncryptData;
+    PFN_CARD_IMPORT_SESSION_KEY         pfnCardImportSessionKey;
+    PFN_CARD_GET_SHARED_KEY_HANDLE      pfnCardGetSharedKeyHandle;
+    PFN_CARD_GET_ALGORITHM_PROPERTY     pfnCardGetAlgorithmProperty;
+    PFN_CARD_GET_KEY_PROPERTY           pfnCardGetKeyProperty;
+    PFN_CARD_SET_KEY_PROPERTY           pfnCardSetKeyProperty;
+    PFN_CARD_DESTROY_KEY                pfnCardDestroyKey;
+    PFN_CARD_PROCESS_ENCRYPTED_DATA     pfnCardProcessEncryptedData;
+    PFN_CARD_CREATE_CONTAINER_EX        pfnCardCreateContainerEx;
+
+} CARD_DATA, *PCARD_DATA;
+
+#endif
+

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,350 +0,0 @@
-// Machine generated C++ stub file (.cpp) for remote object CardModuleService
-// Created on : 06/05/2008 12:22:51
-
-#ifdef WIN32
-#include <windows.h>
-#endif
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include "cardmoduleservice.h"
-
-using namespace std;
-using namespace Marshaller;
-
-
-// Constructors
-CardModuleService::CardModuleService(string* uri) : SmartCardMarshaller(NULL, 0, uri, (u4)0xC04B4E, (u2)0x7FBD, 0) { return; }
-CardModuleService::CardModuleService(string* uri, u4 index) : SmartCardMarshaller(NULL, 0, uri, (u4)0xC04B4E, (u2)0x7FBD, index) { return; }
-CardModuleService::CardModuleService(u2 portNumber, string* uri) : SmartCardMarshaller(NULL, portNumber, uri, (u4)0xC04B4E, (u2)0x7FBD, 0) { return; }
-CardModuleService::CardModuleService(u2 portNumber, string* uri, u4 index) : SmartCardMarshaller(NULL, portNumber, uri, (u4)0xC04B4E, (u2)0x7FBD, index) { return; }
-CardModuleService::CardModuleService(string* readerName, string* uri) : SmartCardMarshaller(readerName, 0, uri, (u4)0xC04B4E, (u2)0x7FBD, 0) { return; }
-CardModuleService::CardModuleService(string* readerName, u2 portNumber, string* uri) : SmartCardMarshaller(readerName, portNumber, uri, (u4)0xC04B4E, (u2)0x7FBD, 0) { return; }
-CardModuleService::CardModuleService(SCARDHANDLE cardHandle, string* uri) : SmartCardMarshaller(cardHandle, 0, uri, (u4)0xC04B4E, (u2)0x7FBD) { return; }
-CardModuleService::CardModuleService(SCARDHANDLE cardHandle, u2 portNumber, string* uri) : SmartCardMarshaller(cardHandle, portNumber, uri, (u4)0xC04B4E, (u2)0x7FBD) { return; }
-
-// Extra method (Microsoft CardModule only)
-void CardModuleService::UpdateCardHandle(SCARDHANDLE cardHandle)
-{
-    UpdatePCSCCardHandle(cardHandle);
-}
-
-// Pre-defined methods
-std::string* CardModuleService::GetReader(void){return GetReaderName();}
-SCARDHANDLE CardModuleService::GetPcscCardHandle(void){return GetCardHandle();}
-void CardModuleService::DoSCardTransact(bool flag){DoTransact(flag);}
-
-// Exposed methods
-
-void CardModuleService::ChangeReferenceData(u1 mode,u1 role,u1Array* oldPin,u1Array* newPin,s4 maxTries){
-	Invoke(5, 0xE08A, MARSHALLER_TYPE_IN_U1, mode, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_IN_U1ARRAY, oldPin, MARSHALLER_TYPE_IN_U1ARRAY, newPin, MARSHALLER_TYPE_IN_S4, maxTries, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-s4 CardModuleService::GetTriesRemaining(u1 role){
-	s4 _s4 = 0;
-	Invoke(1, 0x6D08, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_RET_S4, &_s4);
-	return _s4;
-}
-
-
-void CardModuleService::CreateCAPIContainer(u1 ctrIndex,u1 keyImport,u1 keySpec,s4 keySize,u1Array* keyValue){
-	Invoke(5, 0x0234, MARSHALLER_TYPE_IN_U1, ctrIndex, MARSHALLER_TYPE_IN_BOOL, keyImport, MARSHALLER_TYPE_IN_U1, keySpec, MARSHALLER_TYPE_IN_S4, keySize, MARSHALLER_TYPE_IN_U1ARRAY, keyValue, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::DeleteCAPIContainer(u1 ctrIndex){
-	Invoke(1, 0xF152, MARSHALLER_TYPE_IN_U1, ctrIndex, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1Array* CardModuleService::GetCAPIContainer(u1 ctrIndex){
-	u1Array* _u1Array = NULL;
-	Invoke(1, 0x9B2E, MARSHALLER_TYPE_IN_U1, ctrIndex, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-u1Array* CardModuleService::PrivateKeyDecrypt(u1 ctrIndex,u1 keyType,u1Array* encryptedData){
-	u1Array* _u1Array = NULL;
-	Invoke(3, 0x6144, MARSHALLER_TYPE_IN_U1, ctrIndex, MARSHALLER_TYPE_IN_U1, keyType, MARSHALLER_TYPE_IN_U1ARRAY, encryptedData, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-void CardModuleService::CreateFile(string* path,u1Array* acls,s4 initialSize){
-	Invoke(3, 0xBEF1, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_IN_U1ARRAY, acls, MARSHALLER_TYPE_IN_S4, initialSize, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::CreateDirectory(string* path,u1Array* acls){
-	Invoke(2, 0xACE9, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_IN_U1ARRAY, acls, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::WriteFile(string* path,u1Array* data){
-	Invoke(2, 0xF20E, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_IN_U1ARRAY, data, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1Array* CardModuleService::ReadFile(string* path,s4 maxBytesToRead){
-	u1Array* _u1Array = NULL;
-	Invoke(2, 0x744C, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_IN_S4, maxBytesToRead, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-void CardModuleService::DeleteFile(string* path){
-	Invoke(1, 0x6E2B, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::DeleteDirectory(string* path){
-	Invoke(1, 0x9135, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-StringArray* CardModuleService::GetFiles(string* path){
-	StringArray* _StringArray = NULL;
-	Invoke(1, 0xE72B, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_RET_STRINGARRAY, &_StringArray);
-	return _StringArray;
-}
-
-
-u1Array* CardModuleService::GetFileProperties(string* path){
-	u1Array* _u1Array = NULL;
-	Invoke(1, 0xA01B, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-void CardModuleService::ChangeAuthenticatorEx(u1 mode,u1 oldRole,u1Array* oldPin,u1 newRole,u1Array* newPin,s4 maxTries){
-	Invoke(6, 0x9967, MARSHALLER_TYPE_IN_U1, mode, MARSHALLER_TYPE_IN_U1, oldRole, MARSHALLER_TYPE_IN_U1ARRAY, oldPin, MARSHALLER_TYPE_IN_U1, newRole, MARSHALLER_TYPE_IN_U1ARRAY, newPin, MARSHALLER_TYPE_IN_S4, maxTries, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1Array* CardModuleService::GetContainerProperty(u1 ctrIndex,u1 property,u1 flags){
-	u1Array* _u1Array = NULL;
-	Invoke(3, 0x279C, MARSHALLER_TYPE_IN_U1, ctrIndex, MARSHALLER_TYPE_IN_U1, property, MARSHALLER_TYPE_IN_U1, flags, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-void CardModuleService::SetContainerProperty(u1 ctrIndex,u1 property,u1Array* data,u1 flags){
-	Invoke(4, 0x98D1, MARSHALLER_TYPE_IN_U1, ctrIndex, MARSHALLER_TYPE_IN_U1, property, MARSHALLER_TYPE_IN_U1ARRAY, data, MARSHALLER_TYPE_IN_U1, flags, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::SetCardProperty(u1 property,u1Array* data,u1 flags){
-	Invoke(3, 0xB0E4, MARSHALLER_TYPE_IN_U1, property, MARSHALLER_TYPE_IN_U1ARRAY, data, MARSHALLER_TYPE_IN_U1, flags, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-s4 CardModuleService::GetMemory(){
-	s4 _s4 = 0;
-	Invoke(0, 0x1DB4, MARSHALLER_TYPE_RET_S4, &_s4);
-	return _s4;
-}
-
-
-void CardModuleService::ForceGarbageCollector(){
-	Invoke(0, 0x3D38, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::RecursiveDelete(string* path){
-	Invoke(1, 0xEDD5, MARSHALLER_TYPE_IN_STRING, path, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::Select(MemoryStream* AID){
-	Invoke(1, 0x32E1, MARSHALLER_TYPE_IN_MEMORYSTREAM, AID, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::Verify(u1 P1,u1 P2,u1Array* pin){
-	Invoke(3, 0xD845, MARSHALLER_TYPE_IN_U1, P1, MARSHALLER_TYPE_IN_U1, P2, MARSHALLER_TYPE_IN_U1ARRAY, pin, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-u1 CardModuleService::get_AdminPersonalized(){
-	u1 _u1 = 0;
-	Invoke(0, 0xCFBE, MARSHALLER_TYPE_RET_BOOL, &_u1);
-	return _u1;
-}
-
-
-u1 CardModuleService::get_UserPersonalized(){
-	u1 _u1 = 0;
-	Invoke(0, 0xE710, MARSHALLER_TYPE_RET_BOOL, &_u1);
-	return _u1;
-}
-
-
-u1Array* CardModuleService::GetChallenge(){
-	u1Array* _u1Array = NULL;
-	Invoke(0, 0xFA3B, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-s8 CardModuleService::get_AuthenticationDelay(){
-	s8 _s8 = 0;
-	Invoke(0, 0x5321, MARSHALLER_TYPE_RET_S8, &_s8);
-	return _s8;
-}
-
-void CardModuleService::ExternalAuthenticate(u1Array* response){
-	Invoke(1, 0x24FE, MARSHALLER_TYPE_IN_U1ARRAY, response, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::VerifyPin(u1 role,u1Array* pin){
-	Invoke(2, 0x506B, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_IN_U1ARRAY, pin, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1 CardModuleService::IsAuthenticated(u1 role){
-	u1 _u1 = 0;
-	Invoke(1, 0x9B0B, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_RET_BOOL, &_u1);
-	return _u1;
-}
-
-
-s4Array* CardModuleService::QueryFreeSpace(){
-	s4Array* _s4Array = NULL;
-	Invoke(0, 0x00E5, MARSHALLER_TYPE_RET_S4ARRAY, &_s4Array);
-	return _s4Array;
-}
-
-
-s4Array* CardModuleService::QueryKeySizes(){
-	s4Array* _s4Array = NULL;
-	Invoke(0, 0x5EE4, MARSHALLER_TYPE_RET_S4ARRAY, &_s4Array);
-	return _s4Array;
-}
-
-
-void CardModuleService::LogOut(u1 role){
-	Invoke(1, 0xC4E4, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-
-
-void CardModuleService::SerializeData(string* filename){
-	Invoke(1, 0x9AEA, MARSHALLER_TYPE_IN_STRING, filename, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-void CardModuleService::DeSerializeData(string* filename){
-	Invoke(1, 0xA373, MARSHALLER_TYPE_IN_STRING, filename, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1Array* CardModuleService::get_SerialNumber(){
-	u1Array* _u1Array = NULL;
-	Invoke(0, 0xD017, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-string* CardModuleService::get_Version(){
-	string* _string = NULL;
-	Invoke(0, 0xDEEC, MARSHALLER_TYPE_RET_STRING, &_string);
-	return _string;
-}
-
-
-void CardModuleService::SetHostVersion(u4 hostVersion){
-	Invoke(1, 0xD9B1, MARSHALLER_TYPE_IN_U4, hostVersion, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1Array* CardModuleService::GetChallengeEx(u1 role){
-	u1Array* _u1Array = NULL;
-	Invoke(1, 0x8F0B, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-u1Array* CardModuleService::AuthenticateEx(u1 mode,u1 role,u1Array* pin){
-	u1Array* _u1Array = NULL;
-	Invoke(3, 0x5177, MARSHALLER_TYPE_IN_U1, mode, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_IN_U1ARRAY, pin, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-void CardModuleService::DeauthenticateEx(u1 roles){
-	Invoke(1, 0xBD7B, MARSHALLER_TYPE_IN_U1, roles, MARSHALLER_TYPE_RET_VOID);
-}
-
-
-u1Array* CardModuleService::GetCardProperty(u1 property,u1 flags){
-	u1Array* _u1Array = NULL;
-	Invoke(2, 0x8187, MARSHALLER_TYPE_IN_U1, property, MARSHALLER_TYPE_IN_U1, flags, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-u1Array* CardModuleService::BM_GetBioHeader(u1 role){
-	u1Array* _u1Array = NULL;
-	Invoke(1, 0x4838, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-
-u1 CardModuleService::BM_BioMatch(u1 role,u1Array* verificationData){
-	u1 _u1 = 0;
-	Invoke(2, 0x2D3D, MARSHALLER_TYPE_IN_U1, role, MARSHALLER_TYPE_IN_U1ARRAY, verificationData, MARSHALLER_TYPE_RET_BOOL, &_u1);
-	return _u1;
-}
-
-u1Array* CardModuleService::BM_GetRoles(){
-	u1Array* _u1Array = NULL;
-	Invoke(0, 0xA77A, MARSHALLER_TYPE_RET_U1ARRAY, &_u1Array);
-	return _u1Array;
-}
-
-u1 CardModuleService::get_BM_DefaultRole(){
-	u1 _u1 = 0;
-	Invoke(0, 0x17FD, MARSHALLER_TYPE_RET_U1, &_u1);
-	return _u1;
-}
-
-
-void CardModuleService::set_BM_DefaultRole(u1 value){
-	Invoke(1, 0x4F1E, MARSHALLER_TYPE_IN_U1, value, MARSHALLER_TYPE_RET_VOID);
-}
-
-u1 CardModuleService::get_BM_AuthPinAllowed(){
-	u1 _u1 = 0;
-	Invoke(0, 0x9063, MARSHALLER_TYPE_RET_BOOL, &_u1);
-	return _u1;
-}
-
-string* CardModuleService::BM_GetVerifUIName(){
-	string* _string = NULL;
-	Invoke(0, 0x7BB7, MARSHALLER_TYPE_RET_STRING, &_string);
-	return _string;
-}
-
-
-string* CardModuleService::BM_GetEnrollUIName(){
-	string* _string = NULL;
-	Invoke(0, 0x0D17, MARSHALLER_TYPE_RET_STRING, &_string);
-	return _string;
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,98 +0,0 @@
-// Machine generated C++ stub file (.h) for remote object CardModuleService
-// Created on : 06/05/2008 12:22:51
-
-
-#ifndef _include_CardModuleService_h
-#define _include_CardModuleService_h
-
-#include <string>
-#include "MarshallerCfg.h"
-#include "Array.h"
-#include "PCSC.h"
-#include "Marshaller.h"
-
-#ifdef CardModuleService_EXPORTS
-#define CardModuleService_API __declspec(dllexport)
-#else
-#define CardModuleService_API
-#endif
-
-using namespace std;
-using namespace Marshaller;
-
-class CardModuleService_API CardModuleService : private SmartCardMarshaller {
-public:
-	// Constructors
-	CardModuleService(string* uri);
-	CardModuleService(string* uri, u4 index);
-	CardModuleService(u2 portNumber, string* uri);
-	CardModuleService(u2 portNumber, string* uri, u4 index);
-	CardModuleService(string* readerName, string* uri);
-	CardModuleService(string* readerName, u2 portNumber, string* uri);
-	CardModuleService(SCARDHANDLE cardHandle, string* uri);
-	CardModuleService(SCARDHANDLE cardHandle, u2 portNumber, string* uri);
-
-    // Extra method (Microsoft CardModule only)
-    void UpdateCardHandle(SCARDHANDLE cardHandle);
-
-	// Pre-defined methods
-	string* GetReader(void);
-	SCARDHANDLE GetPcscCardHandle(void);
-    void DoSCardTransact(bool flag);
-
-	// Exposed methods
-	void ChangeReferenceData(u1 mode,u1 role,u1Array* oldPin,u1Array* newPin,s4 maxTries);
-	s4 GetTriesRemaining(u1 role);
-	void CreateCAPIContainer(u1 ctrIndex,u1 keyImport,u1 keySpec,s4 keySize,u1Array* keyValue);
-	void DeleteCAPIContainer(u1 ctrIndex);
-	u1Array* GetCAPIContainer(u1 ctrIndex);
-	u1Array* PrivateKeyDecrypt(u1 ctrIndex,u1 keyType,u1Array* encryptedData);
-	void CreateFile(string* path,u1Array* acls,s4 initialSize);
-	void CreateDirectory(string* path,u1Array* acls);
-	void WriteFile(string* path,u1Array* data);
-	u1Array* ReadFile(string* path,s4 maxBytesToRead);
-	void DeleteFile(string* path);
-	void DeleteDirectory(string* path);
-	StringArray* GetFiles(string* path);
-	u1Array* GetFileProperties(string* path);
-	void ChangeAuthenticatorEx(u1 mode,u1 oldRole,u1Array* oldPin,u1 newRole,u1Array* newPin,s4 maxTries);
-	u1Array* GetContainerProperty(u1 ctrIndex,u1 property,u1 flags);
-	void SetContainerProperty(u1 ctrIndex,u1 property,u1Array* data,u1 flags);
-	void SetCardProperty(u1 property,u1Array* data,u1 flags);
-	s4 GetMemory();
-	void ForceGarbageCollector();
-	void RecursiveDelete(string* path);
-	void Select(MemoryStream* AID);
-	void Verify(u1 P1,u1 P2,u1Array* pin);
-	u1 get_AdminPersonalized();
-	u1 get_UserPersonalized();
-	u1Array* GetChallenge();
-	s8 get_AuthenticationDelay();
-	void ExternalAuthenticate(u1Array* response);
-	void VerifyPin(u1 role,u1Array* pin);
-	u1 IsAuthenticated(u1 role);
-	s4Array* QueryFreeSpace();
-	s4Array* QueryKeySizes();
-	void LogOut(u1 role);
-	void SerializeData(string* filename);
-	void DeSerializeData(string* filename);
-	u1Array* get_SerialNumber();
-	string* get_Version();
-	void SetHostVersion(u4 hostVersion);
-	u1Array* GetChallengeEx(u1 role);
-	u1Array* AuthenticateEx(u1 mode,u1 role,u1Array* pin);
-	void DeauthenticateEx(u1 roles);
-	u1Array* GetCardProperty(u1 property,u1 flags);
-
-	u1Array* BM_GetBioHeader(u1 role);
-	u1 BM_BioMatch(u1 role,u1Array* verificationData);
-	u1Array* BM_GetRoles();
-	u1 get_BM_DefaultRole();
-	void set_BM_DefaultRole(u1 value);
-	u1 get_BM_AuthPinAllowed();
-	string* BM_GetVerifUIName();
-	string* BM_GetEnrollUIName();
-};
-
-
-#endif

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,7 +18,9 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstdio>
+#include <cstring>
+
 #include "cert_utils.h"
 
 
@@ -108,7 +110,7 @@
       pAsn1->Content.usLen = pData[1];
       pAsn1->Content.pData = &pData[2];
 
-      pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
+      pAsn1->Asn1.usLen = ( USHORT )( pAsn1->Content.usLen + 2 );
    }
    else
    {
@@ -119,11 +121,11 @@
       pAsn1->Content.usLen = 0;
       for (i = 0; i < NbBytes; i++)
       {
-          pAsn1->Content.usLen = (pAsn1->Content.usLen << 8) + pData[2+i];
+          pAsn1->Content.usLen = ( USHORT )( ( pAsn1->Content.usLen << 8 ) + pData[ 2 + i ] );
       }
       pAsn1->Content.pData = &pData[2+NbBytes];
 
-      pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2 + NbBytes;
+      pAsn1->Asn1.usLen = ( USHORT )( pAsn1->Content.usLen + 2 + NbBytes );
    }
 
    return(RV_SUCCESS);
@@ -154,8 +156,8 @@
 
    for(i=0; i < dwLen; i++)
    {
-      pOut[i*2] = tohex((pIn[i] >> 4) & 0xF);
-      pOut[i*2+1] =  tohex(pIn[i] & 0xF);
+      pOut[ i * 2 ] = ( BYTE )( tohex( ( pIn[ i ] >> 4)  & 0x0F ) );
+      pOut[ i * 2 + 1 ] =  ( BYTE )( tohex( pIn[ i ] & 0x0F ) );
    }
 }
 
@@ -172,7 +174,7 @@
 
    for(i=0; i < dwLen; i+=2)
    {
-      pOut[i/2] = (fromhex(pIn[i]) << 4) + fromhex(pIn[i+1]);
+      pOut[ i / 2 ] = ( BYTE )( ( fromhex( pIn[ i ] ) << 4 ) + fromhex( pIn[ i + 1 ] ) );
    }
 }
 
@@ -194,12 +196,12 @@
       return &content[2];
    }
 
-   NBBytesForLength = content[1] & 0x7F;
+   NBBytesForLength = ( DWORD )( content[ 1 ] & 0x7F );
 
    usLen = 0;
    for (i = 0; i < NBBytesForLength; i++)
    {
-       usLen = (usLen << 8) + content[2+i];
+       usLen = ( unsigned short )( ( usLen << 8 ) + content[ 2 + i ] );
    }
 
    *len = usLen;
@@ -567,7 +569,7 @@
                 3
                );
 
-           *pdwLabelLen = OrganizationName.usLen + CommonName.usLen + 6;
+           *pdwLabelLen = ( DWORD )( OrganizationName.usLen + CommonName.usLen + 6 );
         }
         else
         {
@@ -580,7 +582,7 @@
                 3
                );
 
-           *pdwLabelLen = OrganizationName.usLen + 3;
+           *pdwLabelLen = ( DWORD )( OrganizationName.usLen + 3 );
         }
     }
     else
@@ -591,7 +593,7 @@
         }
         else
         {
-           *pdwLabelLen = OrganizationName.usLen + 3;
+           *pdwLabelLen = ( DWORD )( OrganizationName.usLen + 3 );
         }
     }
 

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -20,6 +20,16 @@
 
 #pragma once
 
+#ifdef WIN32
+#include <Windows.h>
+#else
+#ifdef __APPLE__
+#include <PCSC/wintypes.h>
+#else
+#include <wintypes.h>
+#endif
+#endif
+
 #define CERT_TYPE_UNKNOWN     (0)
 #define CERT_TYPE_USER        (1)
 #define CERT_TYPE_CA_ROOT     (2)

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,258 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-//#include "dbg.h"
-#include "util.h"
-
-#include "certificateobject.h"
-
-CertificateObject::CertificateObject() : StorageObject()
-{
-   this->_trusted   = CK_FALSE;
-   this->_checkSum  = NULL_PTR;
-   this->_startDate = NULL_PTR;
-   this->_endDate   = NULL_PTR;
-
-   this->_class = CKO_CERTIFICATE;
-
-   this->_ctrIndex = 0xFF;
-   this->_keySpec  = 0xFF;
-}
-
-CertificateObject::~CertificateObject()
-{
-   if(this->_checkSum != NULL_PTR)
-      delete this->_checkSum;
-
-   if(this->_startDate != NULL_PTR)
-      delete this->_startDate;
-
-   if(this->_endDate != NULL_PTR)
-      delete this->_endDate;
-
-}
-
-bool CertificateObject::IsEqual(const StorageObject * that) const
-{
-   if(_uniqueId != 0 && that->_uniqueId != 0)
-      return (_uniqueId == that->_uniqueId);
-
-   // Only objects that have been stored under p11 directory
-   // will have a non-zero _uniqueId. For other objects, do
-   // a deep comparison based on other attributes.
-   if(_class != that->_class)
-      return false;
-
-   const CertificateObject * thatCert = static_cast<const CertificateObject*>(that);
-   return ( (_ctrIndex == thatCert->_ctrIndex) &&
-      (_keySpec == thatCert->_keySpec) &&
-      (_checkValue == thatCert->_checkValue));
-}
-
-CK_BBOOL CertificateObject::Compare(CK_ATTRIBUTE attribute)
-{
-   switch(attribute.type){
-
-        case CKA_CERTIFICATE_TYPE:
-           return (this->_certType == *(CK_ULONG*)attribute.pValue);
-
-        case CKA_CERTIFICATE_CATEGORY:
-           return (this->_certCategory == *(CK_ULONG*)attribute.pValue);
-
-        case CKA_TRUSTED:
-           return (this->_trusted == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_CHECK_VALUE:
-           return Util::CompareU1Arrays(this->_checkSum,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_START_DATE:
-           return Util::CompareU1Arrays(this->_startDate,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_END_DATE:
-           return Util::CompareU1Arrays(this->_endDate,attribute.pValue,attribute.ulValueLen);
-
-        default:
-           return StorageObject::Compare(attribute);
-   }
-}
-
-CK_RV CertificateObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   CK_RV rv = CKR_OK;
-
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-   if(objCreation == CK_FALSE){
-      switch(attribute.type){
-            case CKA_CERTIFICATE_TYPE:
-            case CKA_CERTIFICATE_CATEGORY:
-               return CKR_ATTRIBUTE_READ_ONLY;
-      }
-   }
-
-   switch(attribute.type){
-
-        case CKA_CERTIFICATE_TYPE:
-           {
-              CK_ULONG utemp = StorageObject::ReadULongFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_certType = utemp;}
-           }
-           break;
-
-        case CKA_CERTIFICATE_CATEGORY:
-           {
-              CK_ULONG utemp = StorageObject::ReadULongFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_certCategory = utemp;}
-           }
-           break;
-
-        case CKA_TRUSTED:
-           {
-              CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_trusted = btemp; }
-           }
-           break;
-
-        case CKA_CHECK_VALUE:
-           if(this->_checkSum != NULL_PTR){
-              delete this->_checkSum;
-           }
-           this->_checkSum = StorageObject::ReadU1ArrayFromAttribute(attribute);
-           break;
-
-        case CKA_START_DATE:
-           {
-              u1Array* dtemp = StorageObject::ReadDateFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){
-                 if(this->_startDate != NULL_PTR){
-                    delete this->_startDate;
-                 }
-                 this->_startDate = dtemp;
-              }
-           }
-           break;
-
-        case CKA_END_DATE:
-           {
-              u1Array* dtemp = StorageObject::ReadDateFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){
-                 if(this->_endDate != NULL_PTR){
-                    delete this->_endDate;
-                 }
-                 this->_endDate = dtemp;
-              }
-           }
-           break;
-
-        default:
-           return StorageObject::SetAttribute(attribute,objCreation);
-   }
-
-   return rv;
-}
-
-CK_RV CertificateObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-   switch(attribute->type){
-
-        case CKA_CERTIFICATE_TYPE:
-           return StorageObject::PutULongInAttribute(this->_certType,attribute);
-
-        case CKA_CERTIFICATE_CATEGORY:
-           return StorageObject::PutULongInAttribute(this->_certCategory,attribute);
-
-        case CKA_TRUSTED:
-           return StorageObject::PutBBoolInAttribute(this->_trusted,attribute);
-
-        case CKA_CHECK_VALUE:
-           return StorageObject::PutU1ArrayInAttribute(this->_checkSum,attribute);
-
-        case CKA_START_DATE:
-           return StorageObject::PutU1ArrayInAttribute(this->_startDate,attribute);
-
-        case CKA_END_DATE:
-           return StorageObject::PutU1ArrayInAttribute(this->_endDate,attribute);
-
-        default:
-           return StorageObject::GetAttribute(attribute);
-   }
-}
-
-void CertificateObject::Serialize(std::vector<u1> *to)
-{
-   StorageObject::Serialize(to);
-
-   Util::PushULongInVector(to,this->_certType);
-
-   Util::PushULongInVector(to,this->_certCategory);
-
-   Util::PushBBoolInVector(to,this->_trusted);
-
-   Util::PushByteArrayInVector(to,this->_startDate);
-
-   Util::PushByteArrayInVector(to,this->_endDate);
-
-   Util::PushByteArrayInVector(to,this->_checkSum);
-
-   // serialize the extra fields
-
-   PKCS11_ASSERT(_checkValue != 0);
-   PKCS11_ASSERT(_ctrIndex < 100);
-   PKCS11_ASSERT(_keySpec == 1 || _keySpec == 2 );
-
-   Util::PushULongLongInVector(to,this->_checkValue);
-
-   Util::PushBBoolInVector(to,this->_ctrIndex);
-
-   Util::PushBBoolInVector(to,this->_keySpec);
-}
-
-void CertificateObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-   StorageObject::Deserialize(from,idx);
-
-   this->_certType = Util::ReadULongFromVector(from,idx);
-
-   this->_certCategory = Util::ReadULongFromVector(from,idx);
-
-   this->_trusted = Util::ReadBBoolFromVector(from,idx);
-
-   this->_startDate = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_endDate = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_checkSum = Util::ReadByteArrayFromVector(from,idx);
-
-   // serialize the extra fields
-
-   this->_checkValue = Util::ReadULongLongFromVector(from,idx);
-
-   this->_ctrIndex = Util::ReadBBoolFromVector(from,idx);
-
-   this->_keySpec = Util::ReadBBoolFromVector(from,idx);
-
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,57 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_certificateobject_h
-#define _include_certificateobject_h
-
-#include "storageobject.h"
-
-class CertificateObject : public StorageObject{
-
-public:
-    CK_ULONG        _certType;
-    CK_BBOOL        _trusted;
-    CK_ULONG        _certCategory;
-    u1Array*        _checkSum;
-    u1Array*        _startDate;
-    u1Array*        _endDate;
-
-    // extra fields
-    std::string     _certName;
-    u8              _checkValue;
-    CK_BYTE         _ctrIndex;
-    CK_BYTE         _keySpec;
-
-public:
-    CertificateObject();
-    virtual ~CertificateObject();
-
-    virtual bool IsEqual(const StorageObject * that) const;
-    virtual CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    virtual CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    virtual CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    virtual void Serialize(vector<u1>* to);
-    virtual void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/configure.in
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/configure.in	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/configure.in	2012-02-20 14:26:10 UTC (rev 141)
@@ -2,11 +2,13 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT(libgtop11dotnet, 2.1.3, hotline at gemalto.com)
+AC_INIT(libgtop11dotnet, m4_esyscmd([sh ./extract_version.sh |tr -d '\n']), hotline at gemalto.com)
 AM_INIT_AUTOMAKE
-AC_CONFIG_SRCDIR([PKCS11Module2/pkcs11.cpp])
+AC_CONFIG_SRCDIR([PKCS11.cpp])
 AC_CHECK_PROG([PKGCONFIG], [pkg-config], [yes])
 
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
 # Checks for programs.
 AC_PROG_CXX
 AC_PROG_CC
@@ -28,20 +30,19 @@
 	DYN_LIB_EXT="so"
 esac
 
-# Special check for pthread support
-ACX_PTHREAD(
-[
-	AC_DEFINE(HAVE_PTHREAD, 1,
-		[Define if you have POSIX threads libraries and header files.])
-], [
-	AC_MSG_ERROR([POSIX thread support required])
-])
+# --enable-system-boost
+AC_ARG_ENABLE(system-boost,
+	AC_HELP_STRING([--enable-system-boost], [Use libboost from the system]),
+	[system_boost="${enableval}" ], [ system_boost="no" ])
+AM_CONDITIONAL(ENABLE_SYSTEM_BOOST, test "$system_boost" != "no")
+AC_MSG_CHECKING([for system libboost])
+if test "$system_boost" != "no"
+then
+	AC_MSG_RESULT([yes])
+else
+	AC_MSG_RESULT([no])
+fi
 
-CC="$PTHREAD_CC"
-
-AC_SUBST(PTHREAD_LIBS)
-AC_SUBST(PTHREAD_CFLAGS)
-
 # check pcsc-lite version
 OLD_LIBS="$LIBS"
 PKG_CHECK_MODULES(PCSC, libpcsclite, [],
@@ -68,7 +69,6 @@
 
 AC_CONFIG_FILES([
 	Makefile
-	PKCS11Module2/Makefile
 	])
 AC_OUTPUT
 

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,7 +18,7 @@
  *
  */
 
-#include "stdafx.h"
+//#include "stdafx.h"
 #include "cr_global.h"
 #include "cr_nn.h"
 #include "cr_digit.h"

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,11 +18,12 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstring>
 #include "cr_rsa.h"
 #include "cr_global.h"
 #include "cr_nn.h"
 #include "cr_digit.h"
+#include <memory>
 
 static NN_DIGIT NN_AddDigitMult(NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int);
 static NN_DIGIT NN_SubDigitMult(NN_DIGIT *, NN_DIGIT *, NN_DIGIT, NN_DIGIT *, unsigned int);

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,11 +18,11 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstring>
 #include "ha_config.h"
 #include "cr_random.h"
 #include "cr_global.h"
-#include "platconfig.h"
+//#include "cryptoki.h"
 #include "digest.h"
 #include "md5.h"
 
@@ -54,8 +54,8 @@
 
         // Generate new output
         CMD5* md4Ctx = new CMD5();
-        md4Ctx->HashCore(randomStruct->state,0,16);
-        md4Ctx->HashFinal(randomStruct->output);
+        md4Ctx->hashCore(randomStruct->state,0,16);
+        md4Ctx->hashFinal(randomStruct->output);
         delete md4Ctx;
 
         available = 16;
@@ -96,8 +96,8 @@
     unsigned int i, x;
 
     CMD5* md5Ctx = new CMD5();
-    md5Ctx->HashCore(block,0,blockLen);
-    md5Ctx->HashFinal(digest);
+    md5Ctx->hashCore(block,0,blockLen);
+    md5Ctx->hashFinal(digest);
     delete md5Ctx;
 
     /* add digest to state */

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,12 +18,12 @@
  *
  */
 
-#include "stdafx.h"
+#include <cstring>
 #include "cr_rsa.h"
 #include "cr_global.h"
 #include "cr_nn.h"
 #include "cr_random.h"
-
+#include <memory>
 #include "ha_config.h"
 
 /**

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -21,6 +21,15 @@
 #ifndef _CR_RSA_H_
 #define _CR_RSA_H_
 
+#ifdef WIN32
+#include <Windows.h>
+#else
+#ifdef __APPLE__
+#include <PCSC/wintypes.h>
+#else
+#include <wintypes.h>
+#endif
+#endif
 #include "cr_random.h"
 
 /**

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,112 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-// Copied from ACS
-
-#include "stdafx.h"
-#include "critsect.h"
-
-#if !defined (_WIN32)
-#include <stdexcept>
-#endif
-
-CCriticalSection::CCriticalSection()
-{
-    Init();
-}
-
-/*
-CCriticalSection::CCriticalSection(bool)
-{
-    Init();
-}
-*/
-
-CCriticalSection::~CCriticalSection(void)
-{
-#if defined (_WIN32)
-
-    DeleteCriticalSection(&m_CriticalSection);
-
-#else
-
-    pthread_mutex_destroy(&m_Mutex);
-
-#endif
-}
-
-
-void CCriticalSection::Enter()
-{
-#if defined (_WIN32)
-
-    EnterCriticalSection(&m_CriticalSection);
-
-#else
-
-    if(pthread_equal(m_OwnerThread,pthread_self())) m_RefCount++;
-    else {
-        int Stat = pthread_mutex_lock(&m_Mutex);
-        if(Stat)
-            throw std::runtime_error("pthread_mutex_lock");
-
-        m_OwnerThread = pthread_self();
-        m_RefCount = 1;
-    }
-
-#endif
-}
-
-void CCriticalSection::Leave()
-{
-
-#if defined (_WIN32)
-
-    LeaveCriticalSection(&m_CriticalSection);
-
-#else
-
-    if(pthread_equal(m_OwnerThread,pthread_self())) {
-        m_RefCount--;
-        if(!m_RefCount) {
-            m_OwnerThread = 0;
-            pthread_mutex_unlock(&m_Mutex);
-        }
-    }
-
-#endif
-
-    return;
-}
-
-void CCriticalSection::Init()
-{
-#if defined (_WIN32)
-
-	InitializeCriticalSection(&m_CriticalSection);
-
-#else
-
-    pthread_mutex_init(&m_Mutex,0);
-    m_OwnerThread = 0;
-    m_RefCount = 0;
-
-#endif
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,95 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-// Copied from ACS
-
-#ifndef _include_critsect_h
-#define _include_critsect_h
-
-#if defined(_WIN32)
-
-#include <windows.h>
-
-#else
-
-#include <pthread.h>
-
-#endif
-
-class CCriticalSection
-{
-
-public:
-
-    // A non-default constructor with a dummy parameter is added since
-    // it is needed when CCriticalSection is used as static member in
-    // template classes to instantiate properly with GCC. See for instance
-    // http://gcc.gnu.org/ml/gcc-bugs/2005-01/msg03798.html
-
-    CCriticalSection();
-    //explicit CCriticalSection(bool dummy);
-    ~CCriticalSection();
-    void Enter();
-    void Leave();
-
-private:
-    void Init();
-
-#if defined(_WIN32)
-
-	CRITICAL_SECTION m_CriticalSection;
-
-#else
-
-    pthread_mutex_t m_Mutex;
-    pthread_t m_OwnerThread;
-    unsigned long m_RefCount;
-
-#endif
-
-};
-
-// Convenience class to manage locking
-
-class CCriticalSectionLocker
-{
-public:
-    CCriticalSectionLocker(CCriticalSection & cs) : m_cs(&cs)
-    {
-        m_cs->Enter();
-    }
-    CCriticalSectionLocker(CCriticalSection * cs) : m_cs(cs)
-    {
-        if(m_cs)
-            m_cs->Enter();
-    }
-   ~CCriticalSectionLocker()
-    {
-        if(m_cs)
-            m_cs->Leave();
-    }
-
-private:
-    CCriticalSection * m_cs;
-};
-
-
-#endif // _include_critsect_h
-

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/cryptoki.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cryptoki.h	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cryptoki.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,139 @@
+/*
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
+
+
+#ifndef __GEMALTO_CRYPTOKI__
+#define __GEMALTO_CRYPTOKI__
+
+
+  #if defined(_WINDOWS)
+  
+    #pragma pack(push, cryptoki, 1)
+    
+    // Specifies that the function is a DLL entry point
+    #define CK_IMPORT_SPEC __declspec(dllimport)
+    
+    // Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do not define it in applications
+    #ifdef CRYPTOKI_EXPORTS
+      // Specified that the function is an exported DLL entry point
+      #define CK_EXPORT_SPEC __declspec(dllexport)
+    #else
+      #define CK_EXPORT_SPEC CK_IMPORT_SPEC
+    #endif
+  
+    // Ensures the calling convention for Win32 builds
+    #define CK_CALL_SPEC __cdecl
+  
+    #define CK_PTR *
+  
+    #define CK_DEFINE_FUNCTION(returnType, name) \
+      returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+  
+    #define CK_DECLARE_FUNCTION(returnType, name) \
+      returnType CK_EXPORT_SPEC CK_CALL_SPEC name
+  
+    #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+      returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
+  
+    #define CK_CALLBACK_FUNCTION(returnType, name) \
+      returnType (CK_CALL_SPEC CK_PTR name)
+  
+    #ifndef NULL_PTR
+      #define NULL_PTR 0
+    #endif
+  
+    #include "pkcs11.h"
+    #include "pkcs-11v2-20a3.h"
+  
+    ///* C_GetCardProperty obtains a property value from the .NET MiniDriver */
+    //extern CK_DECLARE_FUNCTION(CK_RV, C_GetCardProperty)
+    //(
+    //    CK_SLOT_ID ulSlotID, 
+    //    CK_BYTE a_ucProperty, 
+    //    CK_BYTE a_ucFlags, 
+    //    CK_BYTE_PTR a_pValue, 
+    //    CK_ULONG_PTR a_pValueLen
+    //);
+
+    ///* C_SetCardProperty pushes a property value to the .NET MiniDriver */
+    //extern CK_DECLARE_FUNCTION(CK_RV, C_SetCardProperty)
+    //(
+    //    CK_SLOT_ID ulSlotID, 
+    //    CK_BYTE a_ucProperty, 
+    //    CK_BYTE a_ucFlags, 
+    //    CK_BYTE_PTR a_pValue, 
+    //    CK_ULONG_PTR a_pValueLen
+    //);
+  
+    #pragma pack(pop, cryptoki)
+  
+  #else
+  
+    #define CK_PTR *
+
+#ifdef __APPLE__
+    #define CK_DEFINE_FUNCTION(returnType, name) \
+      __attribute__((visibility("default"))) returnType name
+#else   
+    #define CK_DEFINE_FUNCTION(returnType, name) \
+      returnType name
+#endif
+     
+     #define CK_DECLARE_FUNCTION(returnType, name) \
+      returnType name
+    
+    #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+      returnType (* name)
+    
+    #define CK_CALLBACK_FUNCTION(returnType, name) \
+      returnType (* name)
+    
+    #define CK_ENTRY
+  
+    #ifndef NULL_PTR
+      #define NULL_PTR 0
+    #endif
+  
+    #include "pkcs11.h"
+    #include "pkcs-11v2-20a3.h"
+
+    ///* C_GetCardProperty obtains a property value from the .NET MiniDriver */
+    //extern CK_DECLARE_FUNCTION(CK_RV, C_GetCardProperty)
+    //(
+    //    CK_SLOT_ID ulSlotID, 
+    //    CK_BYTE a_ucProperty, 
+    //    CK_BYTE a_ucFlags, 
+    //    CK_BYTE_PTR a_pValue, 
+    //    CK_ULONG_PTR a_pValueLen
+    //);
+
+    ///* C_SetCardProperty pushes a property value to the .NET MiniDriver */
+    //extern CK_DECLARE_FUNCTION(CK_RV, C_SetCardProperty)
+    //(
+    //    CK_SLOT_ID ulSlotID, 
+    //    CK_BYTE a_ucProperty, 
+    //    CK_BYTE a_ucFlags, 
+    //    CK_BYTE_PTR a_pValue, 
+    //    CK_ULONG_PTR a_pValueLen
+    //);
+
+#endif
+
+#endif // __GEMALTO_CRYPTOKI__

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,175 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-#include "dataobject.h"
-
-DataObject::DataObject() : StorageObject()
-{
-   this->_class    = CKO_DATA;
-   this->_appName  = NULL_PTR;
-   this->_objId    = NULL_PTR;
-   this->_objValue = NULL_PTR;
-}
-
-DataObject::~DataObject(){
-
-   if(this->_appName != NULL_PTR){
-      delete this->_appName;
-   }
-
-   if(this->_objId != NULL_PTR){
-      delete this->_objId;
-   }
-
-   if(this->_objValue != NULL_PTR){
-      delete this->_objValue;
-   }
-}
-
-CK_BBOOL DataObject::Compare(CK_ATTRIBUTE attribute)
-{
-   CK_BBOOL bRet = CK_FALSE;
-
-   switch(attribute.type)
-   {
-   case CKA_APPLICATION:
-      bRet = Util::CompareU1Arrays(this->_appName,attribute.pValue,attribute.ulValueLen);
-      break;
-
-   case CKA_OBJECT_ID:
-      bRet = Util::CompareU1Arrays(this->_objId,attribute.pValue,attribute.ulValueLen);
-      break;
-
-   case CKA_VALUE:
-      bRet = Util::CompareU1Arrays(this->_objValue,attribute.pValue,attribute.ulValueLen);
-      break;
-
-   default:
-      bRet = StorageObject::Compare( attribute );
-      break;
-   }
-
-   return bRet;
-}
-
-CK_RV DataObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-   CK_RV rv = CKR_OK;
-
-   switch(attribute.type){
-
-        case CKA_APPLICATION:
-           {
-              u1Array* stemp = StorageObject::ReadStringFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){
-                 if(this->_appName != NULL_PTR){
-                    delete this->_appName;
-                 }
-                 this->_appName = stemp;
-              }
-           }
-           break;
-
-
-        case CKA_OBJECT_ID:
-           if(this->_objId != NULL_PTR){
-              delete this->_objId;
-           }
-           this->_objId = StorageObject::ReadU1ArrayFromAttribute(attribute);
-           break;
-
-        case CKA_VALUE:
-           if(this->_objValue != NULL_PTR){
-              delete this->_objValue;
-           }
-           this->_objValue = StorageObject::ReadU1ArrayFromAttribute(attribute);
-           break;
-
-        default:
-           return StorageObject::SetAttribute(attribute,objCreation);
-
-   }
-
-   return rv;
-}
-
-CK_RV DataObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-   CK_RV ulRet = CKR_OK;
-   switch(attribute->type)
-   {
-   case CKA_APPLICATION:
-      ulRet = StorageObject::PutU1ArrayInAttribute(this->_appName,attribute);
-      break;
-
-   case CKA_OBJECT_ID:
-      ulRet = StorageObject::PutU1ArrayInAttribute(this->_objId,attribute);
-      break;
-
-   case CKA_VALUE:
-      ulRet = StorageObject::PutU1ArrayInAttribute(this->_objValue,attribute);
-      break;
-
-   default:
-      ulRet = StorageObject::GetAttribute(attribute);
-      break;
-   }
-
-   return ulRet;
-}
-
-
-void DataObject::Serialize(std::vector<u1>* to)
-{
-   // first go ahead and serialize the fields in base class
-   StorageObject::Serialize(to);
-
-   // serialize label attribute
-   Util::PushByteArrayInVector(to,this->_appName);
-
-   // serialize label attribute
-   Util::PushByteArrayInVector(to,this->_objId);
-
-   // serialize label attribute
-   Util::PushByteArrayInVector(to,this->_objValue);
-}
-
-void DataObject::Deserialize(std::vector<u1> from,CK_ULONG_PTR idx)
-{
-   // first go ahead and de-serialize the fields in base class
-   StorageObject::Deserialize(from,idx);
-
-   this->_appName = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_objId = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_objValue = Util::ReadByteArrayFromVector(from,idx);
-}
-
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,51 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_dataobject_h
-#define _include_dataobject_h
-
-#include "storageobject.h"
-
-class DataObject : public StorageObject
-{
-
-public:
-    u1Array* _appName;
-    u1Array* _objId;
-    u1Array* _objValue;
-
-public:
-
-    DataObject();
-    virtual ~DataObject();
-
-    CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    void Serialize(vector<u1>* to);
-    void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-
-};
-
-
-#endif
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,13 +18,13 @@
  *
  */
 
-#include "stdafx.h"
-#include "platconfig.h"
-#include "symmalgo.h"
+//#include "stdafx.h"
+#include "cryptoki.h"
+//#include "symmalgo.h"
 #include "des.h"
 
 CDES::CDES(){
-    this->_blockSize = 8;
+    _blockSize = 8;
 }
 
 CDES::~CDES(){
@@ -35,7 +35,7 @@
                                   CK_BYTE_PTR output,CK_LONG output_offset)
 {
     // encryprtMode == ENCRYPT then we need to XOR input with iv
-    if(iv != NULL_PTR && this->_encryptMode == ENCRYPT){
+    if(iv != NULL_PTR && _encryptMode == ENCRYPT){
         for(CK_LONG i=0;i<8;i++){
             input[input_offset+i] ^= iv[i];
         }
@@ -43,7 +43,7 @@
 
     algo_DES_DESProcess(key,&input[input_offset],&output[output_offset],(u1)encryptMode);
 
-    if(iv != NULL_PTR && this->_encryptMode == DECRYPT){
+    if(iv != NULL_PTR && _encryptMode == DECRYPT){
         for(CK_LONG i=0;i<8;i++){
             output[output_offset+i] ^= iv[i];
         }

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/des.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/des.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/des.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -23,6 +23,7 @@
 
 #include "MarshallerCfg.h"
 #include "algo_des.h"
+#include "symmalgo.h"
 
 class CDES : public CSymmAlgo
 {

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,74 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "digest.h"
-
-CDigest::CDigest(){
-    this->_counter       = 0;
-    this->_workingOffset = 0;
-    this->_workingLength = 0;
-}
-
-CDigest::~CDigest(){
-    free(this->_hashValue);
-    free(this->_workingBuffer);
-}
-
-void CDigest::HashCore(CK_BYTE_PTR data,CK_LONG offset,CK_LONG count)
-{
-    while (count > 0)
-    {
-        // prepare working buffer.
-        if ((_workingOffset + count) >= this->_blockLength){
-            _workingLength = this->_blockLength - _workingOffset;
-        }
-        else{
-            _workingLength = count;
-        }
-
-        memcpy(&_workingBuffer[_workingOffset],&data[offset],_workingLength);
-
-        _workingOffset += _workingLength;
-        count -= _workingLength;
-        offset += _workingLength;
-
-        if ((_workingOffset == this->_blockLength) && (count > 0)){
-
-            TransformBlock(_workingBuffer,_counter,_hashValue);
-
-            _counter += this->_blockLength;
-            _workingOffset = 0;
-        }
-    }
-}
-
-void CDigest::HashFinal(CK_BYTE_PTR hash)
-{
-    TransformFinalBlock(_workingBuffer,_workingOffset,_counter,_hashValue);
-    memcpy(hash,_hashValue,this->_hashLength);
-}
-
-CK_LONG CDigest::HashLength(void)
-{
-    return this->_hashLength;
-}
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,32 +18,40 @@
  *
  */
 
-#ifndef _include_digest_h
-#define _include_digest_h
 
-class CDigest
-{
+#ifndef __GEMALTO_DIGEST__
+#define __GEMALTO_DIGEST__
+
+#include <cstdlib>
+
+class CDigest {
+
 protected:
-    CK_BYTE_PTR  _workingBuffer;
-    CK_LONG      _workingOffset;
-    CK_LONG      _workingLength;
-    CK_LONG      _counter;
-    CK_BYTE_PTR  _hashValue;
-    CK_LONG      _hashLength;
-    CK_LONG      _blockLength;
+    
+	unsigned char*  _workingBuffer;
+    long      _workingOffset;
+    size_t      _workingLength;
+    long      _counter;
+    unsigned char*  _hashValue;
+    size_t      _hashLength;
+    long      _blockLength;
 
-    virtual void TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result) = 0;
-    virtual void TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result) = 0;
+    virtual void TransformBlock(unsigned char* data, long counter, unsigned char* result) = 0;
 
+    virtual void TransformFinalBlock (unsigned char* data, long length, long counter, unsigned char* result) = 0;
+
 public:
-    CDigest();
-    virtual ~CDigest();
+    
+	CDigest( );
 
-    void HashCore(CK_BYTE_PTR data,CK_LONG offset,CK_LONG count);
-    void HashFinal(CK_BYTE_PTR hash);
-    CK_LONG HashLength(void);
-};
+    virtual ~CDigest( );
+ 
+    void hashCore( unsigned char*, const long&, const long& );
 
+    void hashFinal( unsigned char* );
 
-#endif
+	inline long hashLength( void ) { return _hashLength; }
 
+};
+
+#endif // __GEMALTO_DIGEST__

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,340 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "error.h"
-#include "log.h"
-
-
-#define ERROR_MEMORY "Persistent"
-
-
-/* CheckMarshallerException
-*/
-CK_RV CkError::CheckMarshallerException( Marshaller::Exception &x )
-{
-   UnauthorizedAccessException* uae = dynamic_cast< UnauthorizedAccessException* >( &x );
-   if( uae )
-   {
-      Log::log( "CheckMarshallerException", "## Error ## UnauthorizedAccessException <%s>", x.what( ) );
-      return CKR_USER_NOT_LOGGED_IN;
-   }
-
-   OutOfMemoryException* oome = dynamic_cast< OutOfMemoryException* >( &x );
-   if( oome )
-   {
-      Log::log( "CheckMarshallerException", "## Error ## OutOfMemoryException <%s>", x.what( ) );
-      return CKR_DEVICE_MEMORY;
-   }
-
-   if( NULL != x.what( ) )
-   {
-      if( 0 == strcmp( x.what( ), ERROR_MEMORY ) )
-      {
-         Log::log( "CheckMarshallerException", "## Error ## OutOfMemoryException %s <%s>", ERROR_MEMORY, x.what( ) );
-         return CKR_DEVICE_MEMORY;
-      }
-   }
-
-   {
-      DirectoryNotFoundException * e = dynamic_cast<DirectoryNotFoundException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## DirectoryNotFoundException <%s>", x.what( ) );
-         return CKR_TOKEN_NOT_RECOGNIZED;
-      }
-   }
-   {
-      FileNotFoundException * e = dynamic_cast<FileNotFoundException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## FileNotFoundException <%s>", x.what( ) );
-         return CKR_TOKEN_NOT_RECOGNIZED;
-      }
-   }
-   {
-      IOException * e = dynamic_cast<IOException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## IOException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      RemotingException * e = dynamic_cast<RemotingException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## RemotingException <%s>", x.what( ) );
-         return CKR_TOKEN_NOT_PRESENT;
-      }
-   }
-
-   {
-      CryptographicException * e = dynamic_cast<CryptographicException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## CryptographicException <%s>", x.what( ) );
-         return CKR_DEVICE_MEMORY;
-      }
-   }
-
-   {
-      SystemException * e = dynamic_cast<SystemException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## SystemException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ArgumentException * e = dynamic_cast<ArgumentException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ArgumentException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ArgumentNullException * e = dynamic_cast<ArgumentNullException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ArgumentNullException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ArgumentOutOfRangeException * e = dynamic_cast<ArgumentOutOfRangeException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ArgumentOutOfRangeException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      IndexOutOfRangeException * e = dynamic_cast<IndexOutOfRangeException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## IndexOutOfRangeException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      InvalidCastException * e = dynamic_cast<InvalidCastException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## InvalidCastException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      InvalidOperationException * e = dynamic_cast<InvalidOperationException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## InvalidOperationException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      NotImplementedException * e = dynamic_cast<NotImplementedException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## NotImplementedException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      NotSupportedException * e = dynamic_cast<NotSupportedException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## NotSupportedException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      NullReferenceException * e = dynamic_cast<NullReferenceException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## NullReferenceException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ObjectDisposedException * e = dynamic_cast<ObjectDisposedException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ObjectDisposedException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ApplicationException * e = dynamic_cast<ApplicationException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ApplicationException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ArithmeticException * e = dynamic_cast<ArithmeticException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ArithmeticException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      ArrayTypeMismatchException * e = dynamic_cast<ArrayTypeMismatchException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## ArrayTypeMismatchException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      BadImageFormatException * e = dynamic_cast<BadImageFormatException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## BadImageFormatException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      DirectoryNotFoundException * e = dynamic_cast<DirectoryNotFoundException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## DirectoryNotFoundException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      DivideByZeroException * e = dynamic_cast<DivideByZeroException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## DivideByZeroException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      FormatException * e = dynamic_cast<FormatException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## FormatException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      RankException * e = dynamic_cast<RankException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## RankException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      RemotingException * e = dynamic_cast<RemotingException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## RemotingException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      StackOverflowException * e = dynamic_cast<StackOverflowException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## StackOverflowException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      TypeLoadException * e = dynamic_cast<TypeLoadException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## TypeLoadException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      MemberAccessException * e = dynamic_cast<MemberAccessException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## MemberAccessException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      MissingFieldException * e = dynamic_cast<MissingFieldException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## MissingFieldException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      MissingMemberException * e = dynamic_cast<MissingMemberException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## MissingMemberException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      MissingMethodException * e = dynamic_cast<MissingMethodException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## MissingMethodException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      OverflowException * e = dynamic_cast<OverflowException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## OverflowException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      SecurityException * e = dynamic_cast<SecurityException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## SecurityException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      VerificationException * e = dynamic_cast<VerificationException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## VerificationException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-   {
-      SerializationException * e = dynamic_cast<SerializationException *>( &x );
-      if(e)
-      {
-         Log::log( "CheckMarshallerException", "## Error ## SerializationException <%s>", x.what( ) );
-         return CKR_DEVICE_ERROR;
-      }
-   }
-
-   return CKR_FUNCTION_FAILED;
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/error.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/error.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/error.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,62 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_error_h
-#define _include_error_h
-
-#include <string>
-#include <stdexcept>
-#include "cardmoduleservice.h"
-#include "platconfig.h"
-#include "Except.h"
-
-class PcscError : public std::runtime_error
-{
-public:
-    PcscError() : std::runtime_error(""), _err(0) {}
-    PcscError(unsigned long err) : std::runtime_error(""), _err(err) {}
-    PcscError(const std::string & message, unsigned long err = 0) : std::runtime_error(message), _err(err) {}
-
-    unsigned long Error() const {return _err;}
-
-private:
-    unsigned long _err;
-
-};
-
-
-class CkError : public std::runtime_error
-{
-public:
-    CkError() : std::runtime_error(""), _err(0) {}
-    CkError(CK_RV err) : std::runtime_error(""), _err(err) {}
-    CkError(const std::string & message, unsigned long err = 0) : std::runtime_error(message), _err(err) {}
-
-    CK_RV Error() const {return _err;}
-
-    static CK_RV CheckMarshallerException( Marshaller::Exception & x );
-
-private:
-    unsigned long _err;
-
-};
-
-#endif // _include_error_h
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,141 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef INCLUDE_EVENTING
-
-#include "stdafx.h"
-#include "platconfig.h"
-//#include "dbg.h"
-#ifndef WIN32
-#include <pthread.h>
-#include <sys/time.h>
-#endif
-#include "event.h"
-
-CEvent::CEvent(CK_ULONG timeOut)
-{
-	#ifdef WIN32
-    m_eventHandle = CreateEvent(NULL,TRUE,FALSE,NULL);
-    #else
-    pthread_mutex_init(&m_Mutex,0);
-    pthread_cond_init(&m_Condition,0);
-    #endif
-    m_timeOut     = timeOut;
-}
-
-CEvent::~CEvent(void)
-{
-	#ifdef WIN32
-    CloseHandle(m_eventHandle);
-    #else
-    pthread_mutex_destroy(&m_Mutex);
-    pthread_cond_destroy(&m_Condition);
-    #endif
-}
-
-void CEvent::Signal()
-{
-	#ifdef WIN32
-
-    if(!m_eventHandle)
-        assert(FALSE);  // throw CError(CKR_FUNCTION_FAILED);
-
-    PulseEvent(m_eventHandle);
-
-    #else
-
-    if(pthread_cond_broadcast(&m_Condition) == 0)
-    {
-    	//assert(FALSE);
-    }
-
-    #endif
-
-}
-
-void CEvent::Set()
-{
-	#ifdef WIN32
-
-    if(!m_eventHandle)
-        assert(FALSE);  // throw CError(CKR_FUNCTION_FAILED);
-
-    SetEvent(m_eventHandle);
-
-    #else
-
-    if(pthread_cond_signal( &m_Condition ) != 0)
-    {
-    	//assert(FALSE);
-    }
-
-
-    #endif
-}
-
-void CEvent::Reset()
-{
-	#ifdef WIN32
-    if(!m_eventHandle)
-        assert(FALSE);  // throw CError(CKR_FUNCTION_FAILED);
-
-    ResetEvent(m_eventHandle);
-    #endif
-}
-
-void CEvent::Wait()
-{
-	#ifdef WIN32
-    if(!m_eventHandle)
-        assert(FALSE);  // throw CError(CKR_FUNCTION_FAILED);
-
-    DWORD rv = WaitForSingleObject(m_eventHandle,m_timeOut);
-
-    if(rv == WAIT_TIMEOUT)
-        assert(FALSE);  // throw CError(CKR_FUNCTION_FAILED);
-
-    #else
-
-    struct timeval CurrTime;
-
-    gettimeofday(&CurrTime, NULL);
-
-    timespec Abstime;
-
-    // Calculate absolute time to time out.
-
-    Abstime.tv_sec = CurrTime.tv_sec + m_timeOut/1000;
-    Abstime.tv_nsec = CurrTime.tv_usec*1000 + (m_timeOut % 1000)*1000000;
-
-    if(Abstime.tv_nsec>999999999) {
-        Abstime.tv_sec++;
-        Abstime.tv_nsec -= 1000000000;
-    }
-
-    if(pthread_cond_timedwait(&m_Condition,&m_Mutex,&Abstime) == 0)
-    {
-    	//assert(FALSE);
-    }
-
-    #endif
-}
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/event.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/event.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/event.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,57 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_event_h
-#define _include_event_h
-
-#ifdef INCLUDE_EVENTING
-
-class CEvent
-{
-
-private:
-    #ifdef WIN32
-    HANDLE      m_eventHandle;
-    #else
-    pthread_mutex_t m_Mutex;
-    pthread_cond_t  m_Condition;
-    #endif
-    CK_ULONG    m_timeOut;
-
-public:
-    CEvent(CK_ULONG timeOut);
-    ~CEvent(void);
-
-    void Signal(void);
-    void Set(void);
-    void Reset(void);
-    void Wait(void);  // Throws CK_RV exception on error
-
-    #ifdef WIN32
-    HANDLE GetHandle() { return m_eventHandle;}
-    #endif
-};
-
-extern CEvent CryptokiEvent;
-
-#endif
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,258 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "keyobject.h"
-
-KeyObject::KeyObject() : StorageObject()
-{
-    this->_keyType          = 0;
-    this->_id               = NULL_PTR;
-    this->_startDate        = NULL_PTR;
-    this->_endDate          = NULL_PTR;
-    this->_allowedMechanism = NULL_PTR;
-
-    this->_local         = CK_FALSE;
-    this->_mechanismType = CK_UNAVAILABLE_INFORMATION;//-1;
-}
-
-KeyObject::~KeyObject()
-{
-    if(this->_startDate != NULL_PTR){
-        delete this->_startDate;
-    }
-
-    if(this->_endDate != NULL_PTR){
-        delete this->_endDate;
-    }
-
-    if(this->_id != NULL_PTR){
-        delete this->_id;
-    }
-}
-
-CK_BBOOL KeyObject::Compare(CK_ATTRIBUTE attribute)
-{
-    switch(attribute.type)
-    {
-        case CKA_KEY_TYPE:
-            return (this->_keyType == *(CK_ULONG*)attribute.pValue);
-
-        case CKA_ID:
-            return Util::CompareU1Arrays(this->_id,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_START_DATE:
-            return Util::CompareU1Arrays(this->_startDate,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_END_DATE:
-            return Util::CompareU1Arrays(this->_endDate,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_LOCAL:
-            return (this->_local == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_DERIVE:
-            return (this->_derive == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_MECHANISM_TYPE:
-            return (this->_mechanismType == *(CK_ULONG*)attribute.pValue);
-
-        case CKA_ALLOWED_MECHANISMS:
-            return Util::CompareU4Arrays(this->_allowedMechanism,attribute.pValue,attribute.ulValueLen);
-
-        default:
-            return StorageObject::Compare(attribute);
-
-    }
-}
-
-CK_RV KeyObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-    CK_RV rv = CKR_OK;
-
-    if(objCreation == CK_FALSE){
-        switch(attribute.type){
-            case CKA_KEY_TYPE:
-            case CKA_LOCAL:
-            case CKA_MECHANISM_TYPE:
-                return CKR_ATTRIBUTE_READ_ONLY;
-        }
-    }
-
-    switch(attribute.type){
-
-        case CKA_KEY_TYPE:
-            {
-                CK_ULONG utemp = StorageObject::ReadULongFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_keyType = utemp;}
-            }
-            break;
-
-        case CKA_ID:
-            if(this->_id != NULL_PTR){
-                delete this->_id;
-            }
-            this->_id = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_START_DATE:
-            {
-                u1Array* dtemp = StorageObject::ReadDateFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){
-                    if(this->_startDate != NULL_PTR){
-                        delete this->_startDate;
-                    }
-                    this->_startDate = dtemp;
-                }
-            }
-            break;
-
-        case CKA_END_DATE:
-           {
-                u1Array* dtemp = StorageObject::ReadDateFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){
-                    if(this->_endDate != NULL_PTR){
-                        delete this->_endDate;
-                    }
-                    this->_endDate = dtemp;
-                }
-            }
-            break;
-
-        case CKA_LOCAL:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_local = btemp; }
-            }
-            break;
-
-        case CKA_DERIVE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_derive = btemp; }
-            }
-            break;
-
-        case CKA_MECHANISM_TYPE:
-            {
-                CK_ULONG utemp = StorageObject::ReadULongFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_mechanismType = utemp;}
-            }
-            break;
-
-        case CKA_ALLOWED_MECHANISMS:
-            if(this->_allowedMechanism != NULL_PTR){
-                delete this->_allowedMechanism;
-            }
-            this->_allowedMechanism = new u4Array(attribute.ulValueLen/4);
-            memcpy((u1*)this->_allowedMechanism->GetBuffer(),(CK_BYTE_PTR)attribute.pValue,attribute.ulValueLen);
-            break;
-
-        default:
-            return StorageObject::SetAttribute(attribute,objCreation);
-
-    }
-
-    return rv;
-}
-
-CK_RV KeyObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-    switch(attribute->type)
-    {
-        case CKA_KEY_TYPE:
-            return StorageObject::PutULongInAttribute(this->_keyType,attribute);
-
-        case CKA_ID:
-            return StorageObject::PutU1ArrayInAttribute(this->_id,attribute);
-
-        case CKA_START_DATE:
-            return StorageObject::PutU1ArrayInAttribute(this->_startDate,attribute);
-
-        case CKA_END_DATE:
-            return StorageObject::PutU1ArrayInAttribute(this->_endDate,attribute);
-
-        case CKA_LOCAL:
-            return StorageObject::PutBBoolInAttribute(this->_local,attribute);
-
-        case CKA_DERIVE:
-            return StorageObject::PutBBoolInAttribute(this->_derive,attribute);
-
-        case CKA_MECHANISM_TYPE:
-            return StorageObject::PutULongInAttribute(this->_mechanismType,attribute);
-
-        case CKA_ALLOWED_MECHANISMS:
-            return StorageObject::PutU4ArrayInAttribute(this->_allowedMechanism,attribute);
-
-        default:
-            return StorageObject::GetAttribute(attribute);
-    }
-}
-
-void KeyObject::Serialize(std::vector<u1> *to)
-{
-    StorageObject::Serialize(to);
-
-    Util::PushULongInVector(to,this->_keyType);
-
-    Util::PushByteArrayInVector(to,this->_id);
-
-    Util::PushByteArrayInVector(to,this->_startDate);
-
-    Util::PushByteArrayInVector(to,this->_endDate);
-
-    Util::PushBBoolInVector(to,this->_local);
-
-    Util::PushBBoolInVector(to,this->_derive);
-
-    Util::PushULongInVector(to,this->_mechanismType);
-
-    Util::PushIntArrayInVector(to,this->_allowedMechanism);
-}
-
-void KeyObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-    StorageObject::Deserialize(from,idx);
-
-    this->_keyType = Util::ReadULongFromVector(from,idx);
-
-    this->_id = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_startDate = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_endDate = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_local = Util::ReadBBoolFromVector(from,idx);
-
-    this->_derive = Util::ReadBBoolFromVector(from,idx);
-
-    this->_mechanismType = Util::ReadULongFromVector(from,idx);
-
-    this->_allowedMechanism = Util::ReadIntArrayFromVector(from,idx);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,52 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_keyobject_h
-#define _include_keyobject_h
-
-#include "storageobject.h"
-
-class KeyObject : public StorageObject
-{
-public:
-    CK_ULONG    _keyType;
-    u1Array*    _id;
-    u1Array*    _startDate;
-    u1Array*    _endDate;
-    CK_BBOOL    _derive;
-    CK_BBOOL    _local;
-    CK_ULONG    _mechanismType;
-    u4Array*    _allowedMechanism;
-
-public:
-    KeyObject();
-    virtual ~KeyObject();
-
-    virtual CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    virtual CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    virtual CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    virtual void Serialize(vector<u1>* to);
-    virtual void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,2207 +0,0 @@
-
-/* ---------------- Gemalto Debug -------------- */
-
-
-#include <string.h>
-#include "log.h"
-
-
-// Define to unable if you want to activate trace into the code or at compilation time
-//#define __DEBUG_GEMALTO__
-
-#ifdef WIN32
-#include <windows.h>
-#define LOG_FILE_NAME "c:\\Gemalto.NET.PKCS11.log"
-#else
-#define LOG_FILE_NAME "/tmp/Gemalto.NET.PKCS11.log"
-#endif
-
-
-#define T_BOOL 0
-#define T_BYTES 1
-#define T_LONG 2
-#define T_KEY_TYPE 3
-#define T_CERTIFICATE_TYPE 4
-#define T_CLASS 5
-#define T_DATE 6
-#define T_KEY_GEN_MECHANISM 7
-#define T_UNKNOWN 8
-
-unsigned long Log::m_ulStart = 0;
-
-/* Log a message into the log file
-*/
-void Log::log( const char * format, ... )
-{
-#ifdef __DEBUG_GEMALTO__
-   // Try to open the file
-   FILE* pLog = fopen( LOG_FILE_NAME, "a" );
-   if( NULL == pLog )
-   {
-      // The file does not exit. Nothing to log
-      return;
-   }
-
-   // Write the message to the log file
-   va_list args;
-   va_start( args, format );
-   vfprintf( pLog, format, args );
-   va_end( args );
-   fprintf(pLog, "\n");
-
-#ifndef WIN32
-   // Write the message to stderr stream
-   va_start( args, format );
-	vfprintf( stderr, format, args );
-   va_end( args );
-	fprintf( stderr, "\n");
-#else
-   // Get the size of the buffer necessary to write the message
-   // The size must be extended to include the '\n' and the '\0' characters.
-   va_start( args, format );
-   size_t len = _vscprintf( format, args );
-   va_end( args );
-
-   // Allocate the buffer for the message
-   char *buffer = new char[ len + 2 ];
-   memset( buffer, '\0', len + 2 );
-
-   // Write the message into the buffer.
-   va_start( args, format );
-   vsprintf_s( buffer, len + 1, format, args );
-   va_end( args );
-   buffer[ len ] = '\n';
-
-   // Write the message to the console
-   OutputDebugString( buffer );
-
-   // Release the buffer
-   delete[] buffer;
-#endif
-
-   va_end( args );
-
-   // Close the file
-   fclose( pLog );
-#endif
-}
-
-/*
-
-#ifdef __DEBUG_GEMALTO__
-void Log::log( const char * format, ... )
-{
-   // Try to open the file
-   FILE* pLog = fopen( LOG_FILE_NAME, "a" );
-   if( NULL == pLog )
-   {
-      // The file does not exit. Nothing to log
-      return;
-   }
-
-   // Get the size of the buffer necessary to write the message
-   // The size must be extended to include the '\n' and the '\0' characters.
-   va_list args;
-   va_start( args, format );
-#ifdef WIN32
-   size_t len = _vscprintf( format, args );
-#else
-   char tmp[1];
-   int len = vsnprintf( tmp, sizeof(tmp), format, args );
-#endif
-   va_end( args );
-
-   // Allocate the buffer for the message
-   char *buffer = new char[ len + 2 ];
-   memset( buffer, '\0', len + 2 );
-
-   // Write the message into the buffer.
-   va_start( args, format );
-#ifdef WIN32
-   vsprintf_s( buffer, len + 1, format, args );
-#else
-   vsprintf( buffer, format, args );
-#endif
-   va_end( args );
-   buffer[ len ] = '\n';
-
-   // Write the message to the console
-#ifdef WIN32
-   OutputDebugString( buffer );
-#else
-   printf( buffer );
-#endif
-
-   // Write the message to the log file
-   fputs( buffer, pLog );
-   fflush( pLog );
-
-   // Close the file
-   fclose( pLog );
-
-   // Release the buffer
-   delete[] buffer;
-}
-#else
-void Log::log( const char*, ... )
-{
-}
-#endif
-*/
-
-
-
-/*
-*/
-void Log::begin( const char* a_pMethod )
-{
-#ifdef __DEBUG_GEMALTO__
-   log( "%s - <BEGIN>", a_pMethod );
-#else
-	(void)a_pMethod;
-#endif
-}
-
-
-/*
-*/
-void Log::end( const char* a_pMethod )
-{
-#ifdef __DEBUG_GEMALTO__
-   log( "%s - <END>", a_pMethod );
-#endif
-}
-
-
-/*
-*/
-void Log::in( const char* a_pMethod )
-{
-#ifdef __DEBUG_GEMALTO__
-   log( "%s - [IN]", a_pMethod );
-#endif
-}
-
-
-/*
-*/
-void Log::out( const char* a_pMethod )
-{
-#ifdef __DEBUG_GEMALTO__
-   log( "%s - [OUT]", a_pMethod );
-#endif
-}
-
-
-/*
-*/
-void Log::error( const char* a_pMethod, const char* a_pError )
-{
-#ifdef __DEBUG_GEMALTO__
-   log( "%s - ## Error ## %s", a_pMethod, a_pError );
-#endif
-}
-
-
-
-void Log::logCK_UTF8CHAR_PTR( const char* a_pName, const unsigned char* a_pBuffer, const std::size_t& a_Size )
-{
-#ifdef __DEBUG_GEMALTO__
-   std::string s = "";
-   if( NULL_PTR != a_pBuffer )
-   {
-      toString( a_pBuffer, a_Size, s );
-   }
-   log( "%s - <%#02x> - size <%ld> - buffer <%s>", a_pName, a_pBuffer, a_Size, s.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_MECHANISM_INFO_PTR( const char* a_pMethod, CK_MECHANISM_INFO_PTR pInfo )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR != pInfo )
-	{
-	   std::string flags = "";
-	   CK_FLAGS f = pInfo->flags;
-	   mechanismFlagsToString( f, flags );
-
-      log( "%s - CK_MECHANISM_INFO - ulMinKeySize <%#02x> - ulMaxKeySize <%#02x> - flags <%s>", a_pMethod, pInfo->ulMinKeySize, pInfo->ulMaxKeySize, flags.c_str( ) );
-   }
-   else
-   {
-      log( "%s - CK_MECHANISM_INFO - NULL_PTR", a_pMethod );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_INFO( const char* a_pMethod, const CK_INFO_PTR pInfo )
-{
-#ifdef __DEBUG_GEMALTO__
-   if( NULL_PTR != pInfo )
-   {
-	   std::string s = "";
-	   CK_INFOToString( pInfo, s );
-      log( "%s - CK_INFO <%s>", a_pMethod, s.c_str( ) );
-   }
-   else
-   {
-      log( "%s - CK_INFO <NULL_PTR>", a_pMethod );
-   }
-#endif
-}
-
-
-void Log::logCK_RV( const char* a_pMethod, const CK_RV& rv )
-{
-#ifdef __DEBUG_GEMALTO__
-   if( CKR_OK == rv )
-   {
-      log( "%s - [RV] <0x00> (CKR_OK)", a_pMethod );
-   }
-   else
-  {
-      std::string s = "";
-      CK_RVToString( rv, s );
-      log( "%s - [RV] <%#02x> (%s)", a_pMethod, rv, s.c_str( ) );
-   }
-#endif
-}
-
-
-void Log::logCK_C_INITIALIZE_ARGS_PTR( const char* a_pMethod, CK_C_INITIALIZE_ARGS_PTR a_pArgs )
-{
-#ifdef __DEBUG_GEMALTO__
-   if( NULL_PTR != a_pArgs )
-   {
-		//log( a_pMethod, "pInitArgs->CreateMutex <%#02x>", a_pArgs.CreateMutex );
-		log( "%s - CK_C_INITIALIZE_ARGS - DestroyMutex <%#02x> - LockMutex <%#02x> - UnlockMutex <%#02x> - flags <%#02x> - pReserved <%#02x>",
-         a_pMethod, a_pArgs->DestroyMutex, a_pArgs->LockMutex, a_pArgs->UnlockMutex, a_pArgs->flags, a_pArgs->pReserved );
-   }
-   else
-   {
-		log( "%s - CK_C_INITIALIZE_ARGS - CreateMutex <NULL_PTR> - DestroyMutex <NULL_PTR> - LockMutex <NULL_PTR> - UnlockMutex <NULL_PTR> - flags <NULL_PTR> - pReserved <NULL_PTR>", a_pMethod );
-   }
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_SLOT_ID_PTR( const char* a_pMethod, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount )
-{
-#ifdef __DEBUG_GEMALTO__
-   if( NULL_PTR == pSlotList )
-   {
-      log( "%s - CK_SLOT_ID_PTR - pulCount <%#02x> (%ld) - pSlotList <NULL_PTR>", a_pMethod, pulCount, ( NULL_PTR != pulCount ) ? *pulCount : 0 );
-   }
-   else
-   {
-      std::string sList = "";
-      if( NULL_PTR != pulCount )
-      {
-	      for( size_t i = 0 ; i < (size_t)*pulCount ; i++ )
-	      {
-		      std::string s = "";
-		      toString( (unsigned long) pSlotList[ i ], s );
-		      sList += s;
-		      if( i != (size_t)( *pulCount - 1 ) )
-		      {
-			      sList += ", " ;
-		      }
-	      }
-      }
-      log( "%s - CK_SLOT_ID_PTR - pulCount <%#02x> (%ld) - pSlotList <%#02x> (%s)", a_pMethod, pulCount, ( NULL_PTR != pulCount ) ? *pulCount : 0, pSlotList, sList.c_str( ) );
-   }
-#endif
-}
-
-
-void Log::logCK_SLOT_INFO_PTR( const char* a_pMethod, CK_SLOT_INFO_PTR pInfo )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR != pInfo )
-	{
-	   std::string slotDescription = "";
-	   toString( pInfo->slotDescription, 64, slotDescription );
-
-	   std::string manufacturerID = "";
-	   toString( pInfo->manufacturerID, 32, manufacturerID );
-
-	   std::string flags = "";
-	   CK_FLAGS f = pInfo->flags;
-	   slotFlagsToString( f, flags );
-
-	   std::string hardwareVersion = "";
-	   CK_VERSIONToString( &(pInfo->hardwareVersion), hardwareVersion );
-
-	   std::string firmwareVersion = "";
-	   CK_VERSIONToString( &(pInfo->firmwareVersion), firmwareVersion );
-
-      log( "%s - CK_SLOT_INFO_PTR - slotDescription <%s> - manufacturerID <%s> - flags <%s> - hardwareVersion <%s> - firmwareVersion <%s>",
-		   a_pMethod, slotDescription.c_str( ), manufacturerID.c_str( ), flags.c_str( ), hardwareVersion.c_str( ), firmwareVersion.c_str( ) );
-   }
-   else
-   {
-      log( "%s - CK_SLOT_INFO_PTR - NULL_PTR", a_pMethod );
-   }
-#endif
-}
-
-
-void Log::logCK_TOKEN_INFO_PTR( const char* a_pMethod, CK_TOKEN_INFO_PTR pInfo )
-{
-#ifdef __DEBUG_GEMALTO__
-   if( NULL_PTR != pInfo )
-	{
-	   std::string label = "";
-	   toString( pInfo->label, 32, label );
-
-	   std::string manufacturerID = "";
-	   toString( pInfo->manufacturerID, 32, manufacturerID );
-
-	   std::string model = "";
-	   toString( pInfo->model, 16, model );
-
-	   std::string serialNumber = "";
-	   toString( pInfo->serialNumber, 16, serialNumber );
-
-	   std::string hardwareVersion = "";
-	   CK_VERSIONToString( &(pInfo->hardwareVersion), hardwareVersion );
-
-	   std::string firmwareVersion = "";
-	   CK_VERSIONToString( &(pInfo->firmwareVersion), firmwareVersion );
-
-	   std::string utcTime = "";
-	   toString( pInfo->utcTime, 16, utcTime );
-
-	   log( "%s - CK_TOKEN_INFO_PTR - <%#02x> - label <%s> - manufacturerID <%s> - model <%s> - serialNumber <%s> - flags <%#02x> - ulMaxSessionCount <%#02x> - ulSessionCount <%#02x> - \
-		   ulMaxRwSessionCount <%#02x> - ulRwSessionCount <%#02x> - ulMaxPinLen <%#02x> - ulMinPinLen <%#02x> - ulTotalPublicMemory <%#02x> - \
-		   ulFreePublicMemory <%#02x> - ulTotalPrivateMemory <%#02x> - ulFreePrivateMemory <%#02x> - hardwareVersion <%s> - \
-		   firmwareVersion <%s> - utcTime <%s>",
-		   a_pMethod,
-         pInfo,
-         label.c_str( ),
-		   manufacturerID.c_str( ),
-		   model.c_str( ),
-		   serialNumber.c_str( ),
-		   pInfo->flags,
-		   pInfo->ulMaxSessionCount,
-		   pInfo->ulSessionCount,
-		   pInfo->ulMaxRwSessionCount,
-		   pInfo->ulRwSessionCount,
-		   pInfo->ulMaxPinLen,
-		   pInfo->ulMinPinLen,
-		   pInfo->ulTotalPublicMemory,
-		   pInfo->ulFreePublicMemory,
-		   pInfo->ulTotalPrivateMemory,
-		   pInfo->ulFreePrivateMemory,
-		   hardwareVersion.c_str( ),
-		   firmwareVersion.c_str( ),
-		   utcTime.c_str( ) );
-	}
-   else
-   {
-      log( "%s - CK_TOKEN_INFO_PTR - <NULL_PTR>", a_pMethod );
-   }
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_MECHANISM_TYPE( const char* a_pMethod, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount )
-{
-#ifdef __DEBUG_GEMALTO__
-   std::string s = "";
-   if( ( NULL_PTR != pMechanismList ) && ( NULL_PTR != pulCount ) )
-   {
-		CK_MECHANISM_TYPEToString( pMechanismList, *pulCount, s );
-	}
-   log( "%s - CK_MECHANISM_TYPE_PTR - pulCount <%#02x> (%ld) - pMechanismList <%#02x> (%s)", a_pMethod, pulCount, ( ( NULL_PTR != pulCount ) ? *pulCount : 0 ), pMechanismList, s.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_MECHANISM_TYPE( const char* a_pMethod, CK_MECHANISM_TYPE & ulMechanism )
-{
-#ifdef __DEBUG_GEMALTO__
-   std::string s = "";
-	CK_MECHANISM_TYPEToString( ulMechanism, s );
-   log( "%s - CK_MECHANISM_TYPE <%s>", a_pMethod, s.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::logSessionFlags( const char* a_pMethod, CK_FLAGS & flags )
-{
-#ifdef __DEBUG_GEMALTO__
-	std::string s = "";
-	sessionFlagsToString( flags, s );
-	log( "%s - CK_FLAGS <%s>", a_pMethod, s.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_SESSION_INFO_PTR( const char* a_pMethod, CK_SESSION_INFO_PTR pInfo )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR != pInfo )
-   {
-      std::string s = "";
-	   CK_SESSION_INFOToString( pInfo, s );
-	   log( "%s - CK_SESSION_INFO <%#02x> (%s)", a_pMethod, pInfo, s.c_str( ) );
-   }
-   else
-	{
-	   log( "%s - CK_SESSION_INFO <NULL_PTR>", a_pMethod );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_USER_TYPE( const char* a_pMethod, CK_USER_TYPE &userType )
-{
-#ifdef __DEBUG_GEMALTO__
-	std::string s = "";
-	CK_USER_TYPEToString( userType, s );
-	log( "%s - CK_USER_TYPE <%s>", a_pMethod, s.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_MECHANISM_PTR( const char* a_pMethod, CK_MECHANISM_PTR pMechanism )
-{
-#ifdef __DEBUG_GEMALTO__
-	std::string s = "";
-   CK_MECHANISMToString( pMechanism, s );
-	log( "%s - CK_MECHANISM_PTR <%s>", a_pMethod, s.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::logCK_ATTRIBUTE_PTR( const char* a_pMethod, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG& ulCount )
-{
-#ifdef __DEBUG_GEMALTO__
-   log( "%s - pTemplate <%#02x> - ulCount <%ld>", a_pMethod, pTemplate, ulCount );
-	if( NULL_PTR != pTemplate )
-	{
-	   for( size_t i = 0; i < (size_t)ulCount; i++ )
-	   {
-		   CK_ATTRIBUTE a = pTemplate[ i ];
-		   std::string attribute = "";
-		   CK_ATTRIBUTEToString( &a, attribute );
-
-         log( "%s	- Attribute #%d - %s", a_pMethod, i, attribute.c_str( ) );
-	   }
-   }
-#endif
-}
-
-
-/*
-*/
-void Log::CK_MECHANISMToString( CK_MECHANISM_PTR m, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == m )
-	{
-		return;
-	}
-
-	std::string mechanismType = "";
-	CK_MECHANISM_TYPE t = m->mechanism;
-	CK_MECHANISM_TYPEToString( t, mechanismType );
-
-	std::string mechanismParam = "";
-	toString( (const unsigned char*)m->pParameter, m->ulParameterLen, mechanismParam );
-
-	toString( result,
-		"Type <%s> - Parameter <%s> - ParameterLen <%#02x>",
-		mechanismType.c_str( ),
-		mechanismParam.c_str( ),
-		m->ulParameterLen );
-#endif
-}
-
-
-void Log::CK_ATTRIBUTEToString( const CK_ATTRIBUTE_PTR a, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == a )
-	{
-		return;
-	}
-
-	std::string t = "";
-	int type = T_UNKNOWN;
-	CK_ATTRIBUTE_TYPEToString( a->type, t, type );
-
-	if( ( (CK_ULONG)(-1) ) == a->ulValueLen )
-	{
-		toString( result, "Type <%s> - Length <-1> - Value <UNKNOWN>", t.c_str( ) );
-		return;
-	}
-
-	std::string v = "";
-	if( NULL_PTR == a->pValue )
-	{
-		v = "null";
-	}
-	else
-	{
-		switch( type )
-		{
-		case T_BOOL:
-			toString( ((bool*)a->pValue)[0], v );
-			break;
-
-		case T_BYTES:
-			toString( (CK_BYTE_PTR) a->pValue, a->ulValueLen, v );
-			break;
-
-		case T_LONG:
-			toString( ((CK_ULONG*)a->pValue)[0], v );
-			break;
-
-		case T_KEY_TYPE:
-			CK_KEY_TYPEToString( ((CK_KEY_TYPE *)a->pValue)[0], v );
-			break;
-
-		case T_CERTIFICATE_TYPE:
-			CK_CERTIFICATE_TYPEToString( ((CK_CERTIFICATE_TYPE *)a->pValue)[0], v );
-			break;
-
-		case T_CLASS:
-			CK_OBJECT_CLASSToString( ((CK_OBJECT_CLASS *)a->pValue)[0], v );
-			break;
-
-		case T_DATE:
-			CK_DATEToString( (CK_DATE*) a->pValue, v );
-			break;
-
-		case T_KEY_GEN_MECHANISM:
-			CK_MECHANISM_TYPEToString( ((CK_MECHANISM_TYPE *)a->pValue)[0], v );
-			break;
-
-		default:
-			v = "UNPREDICTABLE VALUE";
-		}
-	}
-
-	toString( result, "Type <%s> - Length <%#02x> - Value <%s>", t.c_str( ), a->ulValueLen, v.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::CK_ATTRIBUTE_TYPEToString( const CK_ATTRIBUTE_TYPE& a, std::string &t, int& type )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( a )
-	{
-	case CKA_CLASS:
-		t = "CKA_CLASS";
-		type = T_CLASS;
-		break;
-
-	case CKA_TOKEN:
-		t = "CKA_TOKEN";
-		type = T_BOOL;
-		break;
-
-	case CKA_PRIVATE:
-		t = "CKA_PRIVATE";
-		type = T_BOOL;
-		break;
-
-	case CKA_LABEL:
-		t = "CKA_LABEL";
-		type = T_BYTES;
-		break;
-
-	case CKA_APPLICATION:
-		t = "CKA_APPLICATION";
-		type = T_BYTES;
-		break;
-
-	case CKA_VALUE:
-		t = "CKA_VALUE";
-		type = T_BYTES;
-		break;
-
-	case CKA_CERTIFICATE_TYPE:
-		t = "CKA_CERTIFICATE_TYPE";
-		type = T_CERTIFICATE_TYPE;
-		break;
-
-	case CKA_ISSUER:
-		t = "CKA_ISSUER";
-		type = T_BYTES;
-		break;
-
-	case CKA_SERIAL_NUMBER:
-		t = "CKA_SERIAL_NUMBER";
-		type = T_BYTES;
-		break;
-
-	case CKA_KEY_TYPE:
-		t = "CKA_KEY_TYPE";
-		type = T_KEY_TYPE;
-		break;
-
-	case CKA_SUBJECT:
-		t = "CKA_SUBJECT";
-		type = T_BYTES;
-		break;
-
-	case CKA_ID:
-		t = "CKA_ID";
-		type = T_BYTES;
-		break;
-
-	case CKA_SENSITIVE:
-		t = "CKA_SENSITIVE";
-		type = T_BOOL;
-		break;
-
-	case CKA_ENCRYPT:
-		t = "CKA_ENCRYPT";
-		type = T_BOOL;
-		break;
-
-	case CKA_DECRYPT:
-		t = "CKA_DECRYPT";
-		type = T_BOOL;
-		break;
-
-	case CKA_WRAP:
-		t = "CKA_WRAP";
-		type = T_BOOL;
-		break;
-
-	case CKA_UNWRAP:
-		t = "CKA_UNWRAP";
-		type = T_BOOL;
-		break;
-
-	case CKA_SIGN:
-		t = "CKA_SIGN";
-		type = T_BOOL;
-		break;
-
-	case CKA_SIGN_RECOVER:
-		t = "CKA_SIGN_RECOVER";
-		type = T_BOOL;
-		break;
-
-	case CKA_VERIFY:
-		t = "CKA_VERIFY";
-		type = T_BOOL;
-		break;
-
-	case CKA_VERIFY_RECOVER:
-		t = "CKA_VERIFY_RECOVER";
-		type = T_BOOL;
-		break;
-
-	case CKA_DERIVE:
-		t = "CKA_DERIVE";
-		type = T_BOOL;
-		break;
-
-	case CKA_START_DATE:
-		t = "CKA_START_DATE";
-		type = T_DATE;
-		break;
-
-	case CKA_END_DATE:
-		t = "CKA_END_DATE";
-		type = T_DATE;
-		break;
-
-	case CKA_MODULUS:
-		t = "CKA_MODULUS";
-		type = T_BYTES;
-		break;
-
-	case CKA_MODULUS_BITS:
-		t = "CKA_MODULUS_BITS";
-		type = T_LONG;
-		break;
-
-	case CKA_PUBLIC_EXPONENT:
-		t = "CKA_PUBLIC_EXPONENT";
-		type = T_BYTES;
-		break;
-
-	case CKA_PRIVATE_EXPONENT:
-		t = "CKA_PRIVATE_EXPONENT";
-		type = T_BYTES;
-		break;
-
-	case CKA_PRIME_1:
-		t = "CKA_PRIME_1";
-		type = T_BYTES;
-		break;
-
-	case CKA_PRIME_2:
-		t = "CKA_PRIME_2";
-		type = T_BYTES;
-		break;
-
-	case CKA_EXPONENT_1:
-		t = "CKA_EXPONENT_1";
-		type = T_BYTES;
-		break;
-
-	case CKA_EXPONENT_2:
-		t = "CKA_EXPONENT_2";
-		type = T_BYTES;
-		break;
-
-	case CKA_COEFFICIENT:
-		t = "CKA_COEFFICIENT";
-		type = T_BYTES;
-		break;
-
-	case CKA_PRIME:
-		t = "CKA_PRIME";
-		type = T_BYTES;
-		break;
-
-	case CKA_SUBPRIME:
-		t = "CKA_SUBPRIME";
-		type = T_BYTES;
-		break;
-
-	case CKA_BASE:
-		t = "CKA_BASE";
-		type = T_BYTES;
-		break;
-
-	case CKA_VALUE_BITS:
-		t = "CKA_VALUE_BITS";
-		type = T_BYTES;
-		break;
-
-	case CKA_VALUE_LEN:
-		t = "CKA_VALUE_LEN";
-		type = T_LONG;
-		break;
-
-	case CKA_EXTRACTABLE:
-		t = "CKA_EXTRACTABLE";
-		type = T_BOOL;
-		break;
-
-	case CKA_LOCAL:
-		t = "CKA_LOCAL";
-		type = T_BOOL;
-		break;
-
-	case CKA_NEVER_EXTRACTABLE:
-		t = "CKA_NEVER_EXTRACTABLE";
-		type = T_BOOL;
-		break;
-
-	case CKA_ALWAYS_SENSITIVE:
-		t = "CKA_ALWAYS_SENSITIVE";
-		type = T_BOOL;
-		break;
-
-	case CKA_MODIFIABLE:
-		t = "CKA_MODIFIABLE";
-		type = T_BOOL;
-		break;
-
-	case CKA_ECDSA_PARAMS:
-		t = "CKA_ECDSA_PARAMS";
-		type = T_BYTES;
-		break;
-
-	case CKA_EC_POINT:
-		t = "CKA_EC_POINT";
-		type = T_BYTES;
-		break;
-
-	case CKA_VENDOR_DEFINED:
-		t = "CKA_VENDOR_DEFINED";
-		type = T_BYTES;
-		break;
-
-		//case CKA_KEY_GEN_MECHANISM:
-		//	t = "CKA_KEY_GEN_MECHANISM";
-		//	type = T_KEY_GEN_MECHANISM;
-		//	break;
-
-	default:
-		toString( t, "UNKNOWN TYPE <%#02x>", a );
-		type = T_UNKNOWN;
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_DATEToString( const CK_DATE* t, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == t )
-	{
-		return;
-	}
-
-	std::string year = "";
-	toString( t->year, 4, year );
-
-	std::string month = "";
-	toString( t->month, 2, month );
-
-	std::string day = "";
-	toString( t->day, 2, day );
-
-	result = "Year <" + year + "> - Month <" + month + "> - Day <" + day + ">";
-#endif
-}
-
-
-/*
-*/
-void Log::CK_OBJECT_CLASSToString( const CK_OBJECT_CLASS& t, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( t )
-	{
-	case CKO_DATA:
-		result = "CKO_DATA";
-		break;
-
-	case CKO_CERTIFICATE:
-		result = "CKO_CERTIFICATE";
-		break;
-
-	case CKO_PUBLIC_KEY:
-		result = "CKO_PUBLIC_KEY";
-		break;
-
-	case CKO_PRIVATE_KEY:
-		result = "CKO_PRIVATE_KEY";
-		break;
-
-	case CKO_SECRET_KEY:
-		result = "CKO_SECRET_KEY";
-		break;
-
-	case CKO_VENDOR_DEFINED:
-		result = "CKO_VENDOR_DEFINED";
-		break;
-
-	default:
-		toString( result, "UNKNOWN OBJECT CLASS <%#02x>", t );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_KEY_TYPEToString( const CK_KEY_TYPE& t, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( t )
-	{
-	case CKK_RSA:
-		result = "CKK_RSA";
-		break;
-
-	case CKK_DSA:
-		result = "CKK_DSA";
-		break;
-
-	case CKK_ECDSA:
-		result = "CKK_ECDSA";
-		break;
-
-	case CKK_DH:
-		result = "CKK_DH";
-		break;
-
-	case CKK_KEA:
-		result = "CKK_KEA";
-		break;
-
-	case CKK_GENERIC_SECRET:
-		result = "CKK_GENERIC_SECRET";
-		break;
-
-	case CKK_RC2:
-		result = "CKK_RC2";
-		break;
-
-	case CKK_RC4:
-		result = "CKK_RC4";
-		break;
-
-	case CKK_DES:
-		result = "CKK_DES";
-		break;
-
-	case CKK_DES2:
-		result = "CKK_DES2";
-		break;
-
-	case CKK_DES3:
-		result = "CKK_DES3";
-		break;
-
-	case CKK_CAST:
-		result = "CKK_CAST";
-		break;
-
-	case CKK_CAST3:
-		result = "CKK_CAST3";
-		break;
-
-	case CKK_CAST5:
-		result = "CKK_CAST5/128";
-		break;
-
-	case CKK_RC5:
-		result = "CKK_RC5";
-		break;
-
-	case CKK_IDEA:
-		result = "CKK_IDEA";
-		break;
-
-	case CKK_SKIPJACK:
-		result = "CKK_SKIPJACK";
-		break;
-
-	case CKK_BATON:
-		result = "CKK_BATON";
-		break;
-
-	case CKK_JUNIPER:
-		result = "CKK_JUNIPER";
-		break;
-
-	case CKK_CDMF:
-		result = "CKK_CDMF";
-		break;
-
-	case CKK_VENDOR_DEFINED:
-		result = "CKK_VENDOR_DEFINED";
-		break;
-
-	default:
-		toString( result, "UNKNOWN KEY TYPE <%#02x>", t );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_CERTIFICATE_TYPEToString( const CK_CERTIFICATE_TYPE &t, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( t )
-	{
-	case CKC_X_509:
-		result = "CKC_X_509";
-		break;
-
-	case CKC_VENDOR_DEFINED:
-		result = "CKC_VENDOR_DEFINED";
-		break;
-
-	default:
-		toString( result, "UNKNOWN CERTIFICATE TYPE <%#02x>", t );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_INFOToString( CK_INFO_PTR pInfo, std::string& result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == pInfo )
-	{
-		return;
-	}
-
-	std::string cryptokiVersion = "";
-	CK_VERSIONToString( &(pInfo->cryptokiVersion), cryptokiVersion );
-
-	std::string manufacturerID = "";
-	toString( pInfo->manufacturerID, 32, manufacturerID );
-
-	std::string flags = "";
-	CK_FLAGS f = pInfo->flags;
-	toString( f, flags );
-
-	std::string libraryDescription = "";
-	toString( pInfo->libraryDescription, 32, libraryDescription );
-
-	std::string libraryVersion = "";
-	CK_VERSIONToString( &(pInfo->libraryVersion), libraryVersion );
-
-	result = "cryptokiVersion <" + cryptokiVersion
-		+ "> - manufacturerID <" + manufacturerID
-		+ "> - flags <" + flags
-		+ "> - libraryDescription <" + libraryDescription
-		+ "> - libraryVersion <" + libraryVersion
-		+ ">";
-#endif
-}
-
-
-/*
-*/
-void Log::CK_RVToString( const CK_RV& rv, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( rv )
-	{
-	case CKR_OK:
-		result = "CKR_OK";
-		break;
-	case CKR_CANCEL:
-		result = "CKR_CANCEL";
-		break;
-	case CKR_HOST_MEMORY:
-		result = "CKR_HOST_MEMORY";
-		break;
-	case CKR_SLOT_ID_INVALID:
-		result = "CKR_SLOT_ID_INVALID";
-		break;
-	case CKR_GENERAL_ERROR:
-		result = "CKR_GENERAL_ERROR";
-		break;
-	case CKR_FUNCTION_FAILED:
-		result = "CKR_FUNCTION_FAILED";
-		break;
-	case CKR_ARGUMENTS_BAD:
-		result = "CKR_ARGUMENTS_BAD";
-		break;
-	case CKR_NO_EVENT:
-		result = "CKR_NO_EVENT";
-		break;
-	case CKR_NEED_TO_CREATE_THREADS:
-		result = "CKR_NEED_TO_CREATE_THREADS";
-		break;
-	case CKR_CANT_LOCK:
-		result = "CKR_CANT_LOCK";
-		break;
-	case CKR_ATTRIBUTE_READ_ONLY:
-		result = "CKR_ATTRIBUTE_READ_ONLY";
-		break;
-	case CKR_ATTRIBUTE_SENSITIVE:
-		result = "CKR_ATTRIBUTE_SENSITIVE";
-		break;
-	case CKR_ATTRIBUTE_TYPE_INVALID:
-		result = "CKR_ATTRIBUTE_TYPE_INVALID";
-		break;
-	case CKR_ATTRIBUTE_VALUE_INVALID:
-		result = "CKR_ATTRIBUTE_VALUE_INVALID";
-		break;
-	case CKR_DATA_INVALID:
-		result = "CKR_DATA_INVALID";
-		break;
-	case CKR_DATA_LEN_RANGE:
-		result = "CKR_DATA_LEN_RANGE";
-		break;
-	case CKR_DEVICE_ERROR:
-		result = "CKR_DEVICE_ERROR";
-		break;
-	case CKR_DEVICE_MEMORY:
-		result = "CKR_DEVICE_MEMORY";
-		break;
-	case CKR_DEVICE_REMOVED:
-		result = "CKR_DEVICE_REMOVED";
-		break;
-	case CKR_ENCRYPTED_DATA_INVALID:
-		result = "CKR_ENCRYPTED_DATA_INVALID";
-		break;
-	case CKR_ENCRYPTED_DATA_LEN_RANGE:
-		result = "CKR_ENCRYPTED_DATA_LEN_RANGE";
-		break;
-	case CKR_FUNCTION_CANCELED:
-		result = "CKR_FUNCTION_CANCELED";
-		break;
-	case CKR_FUNCTION_NOT_PARALLEL:
-		result = "CKR_FUNCTION_NOT_PARALLEL";
-		break;
-	case CKR_FUNCTION_NOT_SUPPORTED:
-		result = "CKR_FUNCTION_NOT_SUPPORTED";
-		break;
-	case CKR_KEY_HANDLE_INVALID:
-		result = "CKR_KEY_HANDLE_INVALID";
-		break;
-	case CKR_KEY_SIZE_RANGE:
-		result = "CKR_KEY_SIZE_RANGE";
-		break;
-	case CKR_KEY_TYPE_INCONSISTENT:
-		result = "CKR_KEY_TYPE_INCONSISTENT";
-		break;
-	case CKR_KEY_NOT_NEEDED:
-		result = "CKR_KEY_NOT_NEEDED";
-		break;
-	case CKR_KEY_CHANGED:
-		result = "CKR_KEY_CHANGED";
-		break;
-	case CKR_KEY_NEEDED:
-		result = "CKR_KEY_NEEDED";
-		break;
-	case CKR_KEY_INDIGESTIBLE:
-		result = "CKR_KEY_INDIGESTIBLE";
-		break;
-	case CKR_KEY_FUNCTION_NOT_PERMITTED:
-		result = "CKR_KEY_FUNCTION_NOT_PERMITTED";
-		break;
-	case CKR_KEY_NOT_WRAPPABLE:
-		result = "CKR_KEY_NOT_WRAPPABLE";
-		break;
-	case CKR_KEY_UNEXTRACTABLE:
-		result = "CKR_KEY_UNEXTRACTABLE";
-		break;
-	case CKR_MECHANISM_INVALID:
-		result = "CKR_MECHANISM_INVALID";
-		break;
-	case CKR_MECHANISM_PARAM_INVALID:
-		result = "CKR_MECHANISM_PARAM_INVALID";
-		break;
-	case CKR_OBJECT_HANDLE_INVALID:
-		result = "CKR_OBJECT_HANDLE_INVALID";
-		break;
-	case CKR_OPERATION_ACTIVE:
-		result = "CKR_OPERATION_ACTIVE";
-		break;
-	case CKR_OPERATION_NOT_INITIALIZED:
-		result = "CKR_OPERATION_NOT_INITIALIZED";
-		break;
-	case CKR_PIN_INCORRECT:
-		result = "CKR_PIN_INCORRECT";
-		break;
-	case CKR_PIN_INVALID:
-		result = "CKR_PIN_INVALID";
-		break;
-	case CKR_PIN_LEN_RANGE:
-		result = "CKR_PIN_LEN_RANGE";
-		break;
-	case CKR_PIN_EXPIRED:
-		result = "CKR_PIN_EXPIRED";
-		break;
-	case CKR_PIN_LOCKED:
-		result = "CKR_PIN_LOCKED";
-		break;
-	case CKR_SESSION_CLOSED:
-		result = "CKR_SESSION_CLOSED";
-		break;
-	case CKR_SESSION_COUNT:
-		result = "CKR_SESSION_COUNT";
-		break;
-	case CKR_SESSION_HANDLE_INVALID:
-		result = "CKR_SESSION_HANDLE_INVALID";
-		break;
-	case CKR_SESSION_PARALLEL_NOT_SUPPORTED:
-		result = "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
-		break;
-	case CKR_SESSION_READ_ONLY:
-		result = "CKR_SESSION_READ_ONLY";
-		break;
-	case CKR_SESSION_EXISTS:
-		result = "CKR_SESSION_EXISTS";
-		break;
-	case CKR_SESSION_READ_ONLY_EXISTS:
-		result = "CKR_SESSION_READ_ONLY_EXISTS";
-		break;
-	case CKR_SESSION_READ_WRITE_SO_EXISTS:
-		result = "CKR_SESSION_READ_WRITE_SO_EXISTS";
-		break;
-	case CKR_SIGNATURE_INVALID:
-		result = "CKR_SIGNATURE_INVALID";
-		break;
-	case CKR_SIGNATURE_LEN_RANGE:
-		result = "CKR_SIGNATURE_LEN_RANGE";
-		break;
-	case CKR_TEMPLATE_INCOMPLETE:
-		result = "CKR_TEMPLATE_INCOMPLETE";
-		break;
-	case CKR_TEMPLATE_INCONSISTENT:
-		result = "CKR_TEMPLATE_INCONSISTENT";
-		break;
-	case CKR_TOKEN_NOT_PRESENT:
-		result = "CKR_TOKEN_NOT_PRESENT";
-		break;
-	case CKR_TOKEN_NOT_RECOGNIZED:
-		result = "CKR_TOKEN_NOT_RECOGNIZED";
-		break;
-	case CKR_TOKEN_WRITE_PROTECTED:
-		result = "CKR_TOKEN_WRITE_PROTECTED";
-		break;
-	case CKR_UNWRAPPING_KEY_HANDLE_INVALID:
-		result = "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
-		break;
-	case CKR_UNWRAPPING_KEY_SIZE_RANGE:
-		result = "CKR_UNWRAPPING_KEY_SIZE_RANGE";
-		break;
-	case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT:
-		result = "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
-		break;
-	case CKR_USER_ALREADY_LOGGED_IN:
-		result = "CKR_USER_ALREADY_LOGGED_IN";
-		break;
-	case CKR_USER_NOT_LOGGED_IN:
-		result = "CKR_USER_NOT_LOGGED_IN";
-		break;
-	case CKR_USER_PIN_NOT_INITIALIZED:
-		result = "CKR_USER_PIN_NOT_INITIALIZED";
-		break;
-	case CKR_USER_TYPE_INVALID:
-		result = "CKR_USER_TYPE_INVALID";
-		break;
-	case CKR_USER_ANOTHER_ALREADY_LOGGED_IN:
-		result = "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
-		break;
-	case CKR_USER_TOO_MANY_TYPES:
-		result = "CKR_USER_TOO_MANY_TYPES";
-		break;
-	case CKR_WRAPPED_KEY_INVALID:
-		result = "CKR_WRAPPED_KEY_INVALID";
-		break;
-	case CKR_WRAPPED_KEY_LEN_RANGE:
-		result = "CKR_WRAPPED_KEY_LEN_RANGE";
-		break;
-	case CKR_WRAPPING_KEY_HANDLE_INVALID:
-		result = "CKR_WRAPPING_KEY_HANDLE_INVALID";
-		break;
-	case CKR_WRAPPING_KEY_SIZE_RANGE:
-		result = "CKR_WRAPPING_KEY_SIZE_RANGE";
-		break;
-	case CKR_WRAPPING_KEY_TYPE_INCONSISTENT:
-		result = "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
-		break;
-	case CKR_RANDOM_SEED_NOT_SUPPORTED:
-		result = "CKR_RANDOM_SEED_NOT_SUPPORTED";
-		break;
-	case CKR_RANDOM_NO_RNG:
-		result = "CKR_RANDOM_NO_RNG";
-		break;
-	case CKR_BUFFER_TOO_SMALL:
-		result = "CKR_BUFFER_TOO_SMALL";
-		break;
-	case CKR_SAVED_STATE_INVALID:
-		result = "CKR_SAVED_STATE_INVALID";
-		break;
-	case CKR_INFORMATION_SENSITIVE:
-		result = "CKR_INFORMATION_SENSITIVE";
-		break;
-	case CKR_STATE_UNSAVEABLE:
-		result = "CKR_STATE_UNSAVEABLE";
-		break;
-	case CKR_CRYPTOKI_NOT_INITIALIZED:
-		result = "CKR_CRYPTOKI_NOT_INITIALIZED";
-		break;
-	case CKR_CRYPTOKI_ALREADY_INITIALIZED:
-		result = "CKR_CRYPTOKI_ALREADY_INITIALIZED";
-		break;
-	case CKR_MUTEX_BAD:
-		result = "CKR_MUTEX_BAD";
-		break;
-	case CKR_MUTEX_NOT_LOCKED:
-		result = "CKR_MUTEX_NOT_LOCKED";
-		break;
-	case CKR_VENDOR_DEFINED:
-		result = "CKR_VENDOR_DEFINED";
-		break;
-	default:
-		toString( result, "UNKNOWN ERROR <%#02x>", rv );
-	}
-#endif
-}
-
-/*
-*/
-void Log::toString( std::string &result, const char * format, ... )
-{
-#ifdef __DEBUG_GEMALTO__
-	result = "";
-
-   // Get the size of the buffer necessary to write the message
-   // The size must be extended to include the '\n' and the '\0' characters.
-   va_list args;
-   va_start( args, format );
-#ifdef WIN32
-   size_t len = _vscprintf( format, args );
-#else
-   char tmp[1];
-   int len = vsnprintf( tmp, sizeof(tmp), format, args );
-#endif
-   va_end( args );
-
-   // Allocate the buffer for the message
-   char *buffer = new char[ len + 2 ];
-   memset( buffer, '\0', len + 2 );
-
-   // Write the message into the buffer.
-   va_start( args, format );
-#ifdef WIN32
-   vsprintf_s( buffer, len + 1, format, args );
-#else
-   vsprintf( buffer, format, args );
-#endif
-   va_end( args );
-
-   // Write the message to the string
-   result = buffer;
-
-   // Release the buffer
-   delete[] buffer;
-#endif
-}
-
-
-/*
-*/
-void Log::toString( const unsigned char* buffer, std::size_t size, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( ( NULL == buffer ) || ( 1 > size ) )
-	{
-		//result.assign( "null" );
-		return;
-	}
-
-    std::ostringstream oss;
-	oss.rdbuf( )->str( "" );
-
-    // Afficher en héxadécimal et en majuscule
-    oss << std::hex << std::uppercase;
-
-    // Remplir les blancs avec des zéros
-    oss << std::setfill('0');
-
-    for( std::size_t i = 0; i < size; ++i )
-    {
-        // Séparer chaque octet par un espace
-        if (i != 0)
-            oss << ' ';
-
-        // Afficher sa valeur hexadécimale précédée de "0x"
-        // setw(2) permet de forcer l'affichage à 2 caractères
-        oss << /*"0x" <<*/ std::setw(2) << static_cast<int>( buffer[i] );
-    }
-
-    result.assign( oss.str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::toString( const unsigned long &l, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	classtoString<unsigned long>( l, result );
-#endif
-}
-
-
-template<typename T> void Log::classtoString( const T & value, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL == &value )
-	{
-		return;
-	}
-	std::ostringstream str;
-	str << value;
-	result.assign( str.str( ) );
-#endif
-}
-
-
-void Log::slotFlagsToString( const CK_FLAGS& f, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	result = "";
-
-	// Slot Information Flags
-	if( f & CKF_TOKEN_PRESENT )
-	{
-		result += "CKF_TOKEN_PRESENT";
-	}
-
-	if( f & CKF_REMOVABLE_DEVICE )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_REMOVABLE_DEVICE";
-	}
-
-	if( f & CKF_HW_SLOT )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_HW_SLOT";
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_VERSIONToString( CK_VERSION_PTR pVersion, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == pVersion )
-	{
-		return;
-	}
-
-	toString( result, "%#02x - %#02x", pVersion->major, pVersion->minor );
-#endif
-}
-
-
-/*
-*/
-void Log::CK_MECHANISM_TYPEToString( CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG mechanismListLen, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == pMechanismList )
-	{
-		return;
-	}
-
-	result = "";
-
-	for( size_t i = 0 ; i < (size_t)mechanismListLen; i++ )
-	{
-		std::string m = "";
-		CK_MECHANISM_TYPEToString( pMechanismList[ i ], m );
-		result += m;
-		if( i != (size_t)( mechanismListLen - 1 ) )
-		{
-			result +=", ";
-		}
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_MECHANISM_TYPEToString( const CK_MECHANISM_TYPE &t, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( t )
-	{
-	case CKM_RSA_PKCS_KEY_PAIR_GEN:
-		result = "CKM_RSA_PKCS_KEY_PAIR_GEN";
-		break;
-	case CKM_RSA_PKCS:
-		result = "CKM_RSA_PKCS";
-		break;
-	case CKM_RSA_9796:
-		result = "CKM_RSA_9796";
-		break;
-	case CKM_RSA_X_509:
-		result = "CKM_RSA_X_509";
-		break;
-	case CKM_MD2_RSA_PKCS:
-		result = "CKM_MD2_RSA_PKCS";
-		break;
-	case CKM_MD5_RSA_PKCS:
-		result = "CKM_MD5_RSA_PKCS";
-		break;
-	case CKM_SHA1_RSA_PKCS:
-		result = "CKM_SHA1_RSA_PKCS";
-		break;
-	case CKM_DSA_KEY_PAIR_GEN:
-		result = "CKM_DSA_KEY_PAIR_GEN";
-		break;
-	case CKM_DSA:
-		result = "CKM_DSA";
-		break;
-	case CKM_DSA_SHA1:
-		result = "CKM_DSA_SHA1";
-		break;
-	case CKM_DH_PKCS_KEY_PAIR_GEN:
-		result = "CKM_DH_PKCS_KEY_PAIR_GEN";
-		break;
-	case CKM_DH_PKCS_DERIVE:
-		result = "CKM_DH_PKCS_DERIVE";
-		break;
-	case CKM_RC2_KEY_GEN:
-		result = "CKM_RC2_KEY_GEN";
-		break;
-	case CKM_RC2_ECB:
-		result = "CKM_RC2_ECB";
-		break;
-	case CKM_RC2_CBC:
-		result = "CKM_RC2_CBC";
-		break;
-	case CKM_RC2_MAC:
-		result = "CKM_RC2_MAC";
-		break;
-	case CKM_RC2_MAC_GENERAL:
-		result = "CKM_RC2_MAC_GENERAL";
-		break;
-	case CKM_RC2_CBC_PAD:
-		result = "CKM_RC2_CBC_PAD";
-		break;
-	case CKM_RC4_KEY_GEN:
-		result = "CKM_RC4_KEY_GEN";
-		break;
-	case CKM_RC4:
-		result = "CKM_RC4";
-		break;
-	case CKM_DES_KEY_GEN:
-		result = "CKM_DES_KEY_GEN";
-		break;
-	case CKM_DES_ECB:
-		result = "CKM_DES_ECB";
-		break;
-	case CKM_DES_CBC:
-		result = "CKM_DES_CBC";
-		break;
-	case CKM_DES_MAC:
-		result = "CKM_DES_MAC";
-		break;
-	case CKM_DES_MAC_GENERAL:
-		result = "CKM_DES_MAC_GENERAL";
-		break;
-	case CKM_DES_CBC_PAD:
-		result = "CKM_DES_CBC_PAD";
-		break;
-	case CKM_DES2_KEY_GEN:
-		result = "CKM_DES2_KEY_GEN";
-		break;
-	case CKM_DES3_KEY_GEN:
-		result = "CKM_DES3_KEY_GEN";
-		break;
-	case CKM_DES3_ECB:
-		result = "CKM_DES3_ECB";
-		break;
-	case CKM_DES3_CBC:
-		result = "CKM_DES3_CBC";
-		break;
-	case CKM_DES3_MAC:
-		result = "CKM_DES3_MAC";
-		break;
-	case CKM_DES3_MAC_GENERAL:
-		result = "CKM_DES3_MAC_GENERAL";
-		break;
-	case CKM_DES3_CBC_PAD:
-		result = "CKM_DES3_CBC_PAD";
-		break;
-	case CKM_CDMF_KEY_GEN:
-		result = "CKM_CDMF_KEY_GEN";
-		break;
-	case CKM_CDMF_ECB:
-		result = "CKM_CDMF_ECB";
-		break;
-	case CKM_CDMF_CBC:
-		result = "CKM_CDMF_CBC";
-		break;
-	case CKM_CDMF_MAC:
-		result = "CKM_CDMF_MAC";
-		break;
-	case CKM_CDMF_MAC_GENERAL:
-		result = "CKM_CDMF_MAC_GENERAL";
-		break;
-	case CKM_CDMF_CBC_PAD:
-		result = "CKM_CDMF_CBC_PAD";
-		break;
-	case CKM_MD2:
-		result = "CKM_MD2";
-		break;
-	case CKM_MD2_HMAC:
-		result = "CKM_MD2_HMAC";
-		break;
-	case CKM_MD2_HMAC_GENERAL:
-		result = "CKM_MD2_HMAC_GENERAL";
-		break;
-	case CKM_MD5:
-		result = "CKM_MD5";
-		break;
-	case CKM_MD5_HMAC:
-		result = "CKM_MD5_HMAC";
-		break;
-	case CKM_MD5_HMAC_GENERAL:
-		result = "CKM_MD5_HMAC_GENERAL";
-		break;
-	case CKM_SHA_1:
-		result = "CKM_SHA_1";
-		break;
-	case CKM_SHA_1_HMAC:
-		result = "CKM_SHA_1_HMAC";
-		break;
-	case CKM_SHA_1_HMAC_GENERAL:
-		result = "CKM_SHA_1_HMAC_GENERAL";
-		break;
-	case CKM_CAST_KEY_GEN:
-		result = "CKM_CAST_KEY_GEN";
-		break;
-	case CKM_CAST_ECB:
-		result = "CKM_CAST_ECB";
-		break;
-	case CKM_CAST_CBC:
-		result = "CKM_CAST_CBC";
-		break;
-	case CKM_CAST_MAC:
-		result = "CKM_CAST_MAC";
-		break;
-	case CKM_CAST_MAC_GENERAL:
-		result = "CKM_CAST_MAC_GENERAL";
-		break;
-	case CKM_CAST_CBC_PAD:
-		result = "CKM_CAST_CBC_PAD";
-		break;
-	case CKM_CAST3_KEY_GEN:
-		result = "CKM_CAST3_KEY_GEN";
-		break;
-	case CKM_CAST3_ECB:
-		result = "CKM_CAST3_ECB";
-		break;
-	case CKM_CAST3_CBC:
-		result = "CKM_CAST3_CBC";
-		break;
-	case CKM_CAST3_MAC:
-		result = "CKM_CAST3_MAC";
-		break;
-	case CKM_CAST3_MAC_GENERAL:
-		result = "CKM_CAST3_MAC_GENERAL";
-		break;
-	case CKM_CAST3_CBC_PAD:
-		result = "CKM_CAST3_CBC_PAD";
-		break;
-		/*case CKM_CAST5_KEY_GEN:
-		result = "CKM_CAST5_KEY_GEN";
-		break;*/
-	case CKM_CAST128_KEY_GEN:
-		result = "CKM_CAST128_KEY_GEN/CKM_CAST5_KEY_GEN";
-		break;
-		/*case CKM_CAST5_ECB:
-		result = "CKM_CAST5_ECB";
-		break;*/
-	case CKM_CAST128_ECB:
-		result = "CKM_CAST128_ECB/CKM_CAST5_ECB";
-		break;
-		/*case CKM_CAST5_CBC:
-		result = "CKM_CAST5_CBC";
-		break;*/
-	case CKM_CAST128_CBC:
-		result = "CKM_CAST128_CBC/CKM_CAST5_CBC";
-		break;
-		/*case CKM_CAST5_MAC:
-		result = "CKM_CAST5_MAC";
-		break;*/
-	case CKM_CAST128_MAC:
-		result = "CKM_CAST128_MAC/CKM_CAST5_MAC";
-		break;
-		/*case CKM_CAST5_MAC_GENERAL:
-		result = "CKM_CAST5_MAC_GENERAL";
-		break;*/
-	case CKM_CAST128_MAC_GENERAL:
-		result = "CKM_CAST128_MAC_GENERAL/CKM_CAST5_MAC_GENERAL";
-		break;
-		/*case CKM_CAST5_CBC_PAD:
-		result = "CKM_CAST5_CBC_PAD";
-		break;*/
-	case CKM_CAST128_CBC_PAD:
-		result = "CKM_CAST128_CBC_PAD/CKM_CAST5_CBC_PAD";
-		break;
-	case CKM_RC5_KEY_GEN:
-		result = "CKM_RC5_KEY_GEN";
-		break;
-	case CKM_RC5_ECB:
-		result = "CKM_RC5_ECB";
-		break;
-	case CKM_RC5_CBC:
-		result = "CKM_RC5_CBC";
-		break;
-	case CKM_RC5_MAC:
-		result = "CKM_RC5_MAC";
-		break;
-	case CKM_RC5_MAC_GENERAL:
-		result = "CKM_RC5_MAC_GENERAL";
-		break;
-	case CKM_RC5_CBC_PAD:
-		result = "CKM_RC5_CBC_PAD";
-		break;
-	case CKM_IDEA_KEY_GEN:
-		result = "CKM_IDEA_KEY_GEN";
-		break;
-	case CKM_IDEA_ECB:
-		result = "CKM_IDEA_ECB";
-		break;
-	case CKM_IDEA_CBC:
-		result = "CKM_IDEA_CBC";
-		break;
-	case CKM_IDEA_MAC:
-		result = "CKM_IDEA_MAC";
-		break;
-	case CKM_IDEA_MAC_GENERAL:
-		result = "CKM_IDEA_MAC_GENERAL";
-		break;
-	case CKM_IDEA_CBC_PAD:
-		result = "CKM_IDEA_CBC_PAD";
-		break;
-	case CKM_GENERIC_SECRET_KEY_GEN:
-		result = "CKM_GENERIC_SECRET_KEY_GEN";
-		break;
-	case CKM_CONCATENATE_BASE_AND_KEY:
-		result = "CKM_CONCATENATE_BASE_AND_KEY";
-		break;
-	case CKM_CONCATENATE_BASE_AND_DATA:
-		result = "CKM_CONCATENATE_BASE_AND_DATA";
-		break;
-	case CKM_CONCATENATE_DATA_AND_BASE:
-		result = "CKM_CONCATENATE_DATA_AND_BASE";
-		break;
-	case CKM_XOR_BASE_AND_DATA:
-		result = "CKM_XOR_BASE_AND_DATA";
-		break;
-	case CKM_EXTRACT_KEY_FROM_KEY:
-		result = "CKM_EXTRACT_KEY_FROM_KEY";
-		break;
-	case CKM_SSL3_PRE_MASTER_KEY_GEN:
-		result = "CKM_SSL3_PRE_MASTER_KEY_GEN";
-		break;
-	case CKM_SSL3_MASTER_KEY_DERIVE:
-		result = "CKM_SSL3_MASTER_KEY_DERIVE";
-		break;
-	case CKM_SSL3_KEY_AND_MAC_DERIVE:
-		result = "CKM_SSL3_KEY_AND_MAC_DERIVE";
-		break;
-	case CKM_SSL3_MD5_MAC:
-		result = "CKM_SSL3_MD5_MAC";
-		break;
-	case CKM_SSL3_SHA1_MAC:
-		result = "CKM_SSL3_SHA1_MAC";
-		break;
-	case CKM_MD5_KEY_DERIVATION:
-		result = "CKM_MD5_KEY_DERIVATION";
-		break;
-	case CKM_MD2_KEY_DERIVATION:
-		result = "CKM_MD2_KEY_DERIVATION";
-		break;
-	case CKM_SHA1_KEY_DERIVATION:
-		result = "CKM_SHA1_KEY_DERIVATION";
-		break;
-	case CKM_PBE_MD2_DES_CBC:
-		result = "CKM_PBE_MD2_DES_CBC";
-		break;
-	case CKM_PBE_MD5_DES_CBC:
-		result = "CKM_PBE_MD5_DES_CBC";
-		break;
-	case CKM_PBE_MD5_CAST_CBC:
-		result = "CKM_PBE_MD5_CAST_CBC";
-		break;
-	case CKM_PBE_MD5_CAST3_CBC:
-		result = "CKM_PBE_MD5_CAST3_CBC";
-		break;
-		/*case CKM_PBE_MD5_CAST5_CBC:
-		result = "CKM_PBE_MD5_CAST5_CBC";
-		break;*/
-	case CKM_PBE_MD5_CAST128_CBC:
-		result = "CKM_PBE_MD5_CAST128_CBC/CKM_PBE_MD5_CAST5_CBC";
-		break;
-		/*case CKM_PBE_SHA1_CAST5_CBC:
-		result = "CKM_PBE_SHA1_CAST5_CBC";
-		break;*/
-	case CKM_PBE_SHA1_CAST128_CBC:
-		result = "CKM_PBE_SHA1_CAST128_CBC/CKM_PBE_SHA1_CAST5_CBC";
-		break;
-	case CKM_PBE_SHA1_RC4_128:
-		result = "CKM_PBE_SHA1_RC4_128";
-		break;
-	case CKM_PBE_SHA1_RC4_40:
-		result = "CKM_PBE_SHA1_RC4_40";
-		break;
-	case CKM_PBE_SHA1_DES3_EDE_CBC:
-		result = "CKM_PBE_SHA1_DES3_EDE_CBC";
-		break;
-	case CKM_PBE_SHA1_DES2_EDE_CBC:
-		result = "CKM_PBE_SHA1_DES2_EDE_CBC";
-		break;
-	case CKM_PBE_SHA1_RC2_128_CBC:
-		result = "CKM_PBE_SHA1_RC2_128_CBC";
-		break;
-	case CKM_PBE_SHA1_RC2_40_CBC:
-		result = "CKM_PBE_SHA1_RC2_40_CBC";
-		break;
-	case CKM_PBA_SHA1_WITH_SHA1_HMAC:
-		result = "CKM_PBA_SHA1_WITH_SHA1_HMAC";
-		break;
-	case CKM_KEY_WRAP_LYNKS:
-		result = "CKM_KEY_WRAP_LYNKS";
-		break;
-	case CKM_KEY_WRAP_SET_OAEP:
-		result = "CKM_KEY_WRAP_SET_OAEP";
-		break;
-	case CKM_SKIPJACK_KEY_GEN:
-		result = "CKM_SKIPJACK_KEY_GEN";
-		break;
-	case CKM_SKIPJACK_ECB64:
-		result = "CKM_SKIPJACK_ECB64";
-		break;
-	case CKM_SKIPJACK_CBC64:
-		result = "CKM_SKIPJACK_CBC64";
-		break;
-	case CKM_SKIPJACK_OFB64:
-		result = "CKM_SKIPJACK_OFB64";
-		break;
-	case CKM_SKIPJACK_CFB64:
-		result = "CKM_SKIPJACK_CFB64";
-		break;
-	case CKM_SKIPJACK_CFB32:
-		result = "CKM_SKIPJACK_CFB32";
-		break;
-	case CKM_SKIPJACK_CFB16:
-		result = "CKM_SKIPJACK_CFB16";
-		break;
-	case CKM_SKIPJACK_CFB8:
-		result = "CKM_SKIPJACK_CFB8";
-		break;
-	case CKM_SKIPJACK_WRAP:
-		result = "CKM_SKIPJACK_WRAP";
-		break;
-	case CKM_SKIPJACK_PRIVATE_WRAP:
-		result = "CKM_SKIPJACK_PRIVATE_WRAP";
-		break;
-	case CKM_SKIPJACK_RELAYX:
-		result = "CKM_SKIPJACK_RELAYX";
-		break;
-	case CKM_KEA_KEY_PAIR_GEN:
-		result = "CKM_KEA_KEY_PAIR_GEN";
-		break;
-	case CKM_KEA_KEY_DERIVE:
-		result = "CKM_KEA_KEY_DERIVE";
-		break;
-	case CKM_FORTEZZA_TIMESTAMP:
-		result = "CKM_FORTEZZA_TIMESTAMP";
-		break;
-	case CKM_BATON_KEY_GEN:
-		result = "CKM_BATON_KEY_GEN";
-		break;
-	case CKM_BATON_ECB128:
-		result = "CKM_BATON_ECB128";
-		break;
-	case CKM_BATON_ECB96:
-		result = "CKM_BATON_ECB96";
-		break;
-	case CKM_BATON_CBC128:
-		result = "CKM_BATON_CBC128";
-		break;
-	case CKM_BATON_COUNTER:
-		result = "CKM_BATON_COUNTER";
-		break;
-	case CKM_BATON_SHUFFLE:
-		result = "CKM_BATON_SHUFFLE";
-		break;
-	case CKM_BATON_WRAP:
-		result = "CKM_RSA_9796";
-		break;
-	case CKM_ECDSA:
-		result = "CKM_ECDSA";
-		break;
-	case CKM_ECDSA_SHA1:
-		result = "CKM_ECDSA_SHA1";
-		break;
-	case CKM_JUNIPER_KEY_GEN:
-		result = "CKM_JUNIPER_KEY_GEN";
-		break;
-	case CKM_JUNIPER_ECB128:
-		result = "CKM_JUNIPER_ECB128";
-		break;
-	case CKM_JUNIPER_CBC128:
-		result = "CKM_JUNIPER_CBC128";
-		break;
-	case CKM_JUNIPER_COUNTER:
-		result = "CKM_JUNIPER_COUNTER";
-		break;
-	case CKM_JUNIPER_SHUFFLE:
-		result = "CKM_JUNIPER_SHUFFLE";
-		break;
-	case CKM_JUNIPER_WRAP:
-		result = "CKM_JUNIPER_WRAP";
-		break;
-	case CKM_FASTHASH:
-		result = "CKM_FASTHASH";
-		break;
-	case CKM_VENDOR_DEFINED:
-		result = "CKM_VENDOR_DEFINED";
-		break;
-	case CKM_SHA256:
-		result = "CKM_SHA256";
-		break;
-	case CKM_SHA256_RSA_PKCS:
-		result = "CKM_SHA256_RSA_PKCS";
-		break;
-	default:
-		toString( result, "UNKNOWN MECHANISM <%#02x>", t );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_MECHANISM_INFOToString( CK_MECHANISM_INFO_PTR pInfo, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == pInfo )
-	{
-		 return;
-	}
-
-	std::string flags = "";
-	CK_FLAGS f = pInfo->flags;
-	mechanismFlagsToString( f, flags );
-
-	toString( result, "ulMinKeySize <%#02x> - ulMaxKeySize <%#02x> - flags <%s>", pInfo->ulMinKeySize, pInfo->ulMaxKeySize, flags.c_str( ) );
-#endif
-}
-
-
-/*
-*/
-void Log::mechanismFlagsToString( const CK_FLAGS& f, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( f & CKF_EXTENSION )
-	{
-		result += "CKF_EXTENSION";
-	}
-	if( f & CKF_DERIVE )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_DERIVE";
-	}
-	if( f & CKF_UNWRAP )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_UNWRAP";
-	}
-	if( f & CKF_WRAP )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_WRAP";
-	}
-	if( f & CKF_GENERATE_KEY_PAIR )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_GENERATE_KEY_PAIR";
-	}
-	if( f & CKF_GENERATE )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_GENERATE";
-	}
-	if( f & CKF_VERIFY_RECOVER )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_VERIFY_RECOVER";
-	}
-	if( f & CKF_VERIFY )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_VERIFY";
-	}
-	if( f & CKF_SIGN_RECOVER )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_SIGN_RECOVER";
-	}
-	if( f & CKF_HW )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_HW";
-	}
-	if( f & CKF_ENCRYPT )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_ENCRYPT";
-	}
-	if( f & CKF_DECRYPT )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_DECRYPT";
-	}
-	if( f & CKF_DIGEST )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_DIGEST";
-	}
-	if( f & CKF_SIGN )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_SIGN";
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::sessionFlagsToString( const CK_FLAGS &f, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	result = "";
-
-	// Session information flags
-	if( f & CKF_SERIAL_SESSION )
-	{
-		result += "CKF_SERIAL_SESSION";
-	}
-
-	if( f & CKF_RW_SESSION )
-	{
-		if( !result.empty( ) )
-		{
-			result += " | ";
-		}
-		result += "CKF_RW_SESSION";
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::CK_SESSION_INFOToString( CK_SESSION_INFO_PTR pInfo, std::string& result )
-{
-#ifdef __DEBUG_GEMALTO__
-	if( NULL_PTR == pInfo )
-	{
-		return;
-	}
-
-	std::string flags = "";
-	CK_FLAGS f = pInfo->flags;
-	sessionFlagsToString( f, flags );
-
-	toString( result, "slotID <%#02x> - state <%#02x> - flags <%#02x> (%s) - ulDeviceError <%#02x>",
-				pInfo->slotID,
-				pInfo->state,
-				pInfo->flags,
-				flags.c_str( ),
-				pInfo->ulDeviceError );
-#endif
-}
-
-/*
-*/
-void Log::CK_USER_TYPEToString( const CK_USER_TYPE& t, std::string &result )
-{
-#ifdef __DEBUG_GEMALTO__
-	switch( t )
-	{
-	case CKU_USER:
-		result = "CKU_USER";
-		break;
-
-	case CKU_SO:
-		result  = "CKU_SO";
-		break;
-
-	default:
-		toString( result, "UNKNOWN USER TYPE <%#02x>", t );
-	}
-#endif
-}
-
-
-/*
-*/
-void Log::start( void )
-{
-#ifdef __DEBUG_GEMALTO__
-#ifdef WIN32
-   m_ulStart = GetTickCount( );
-#endif
-#endif
-}
-
-
-/*
-*/
-void Log::stop( const char* a_pMethod )
-{
-#ifdef __DEBUG_GEMALTO__
-#ifdef WIN32
-   unsigned long ulTickCount = GetTickCount( ) - m_ulStart;
-   Log::log( "%s - Spend <%ld> milliseconds", a_pMethod, ulTickCount );
-#endif
-#endif
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/log.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/log.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/log.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,96 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_log_h
-#define _include_log_h
-
-#include <string>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sstream>
-#include <iostream>
-#include <iomanip>
-#include "platconfig.h"
-
-
-class Log
-{
-public:
-
-   static void log( const char * format, ... );
-
-   static void error( const char*, const char* );
-   static void in( const char* a_pMethod );
-   static void out( const char* a_pMethod );
-   static void begin( const char* a_pMethod );
-   static void end( const char* a_pMethod );
-
-   static void start( void );
-   static void stop( const char* a_pMethod );
-
-   static void logCK_SLOT_ID_PTR( const char*, CK_SLOT_ID_PTR, CK_ULONG_PTR );
-   static void logCK_SLOT_INFO_PTR( const char*, CK_SLOT_INFO_PTR );
-   static void logCK_C_INITIALIZE_ARGS_PTR( const char*, CK_C_INITIALIZE_ARGS_PTR );
-   static void logCK_INFO( const char*, const CK_INFO_PTR );
-   static void logCK_RV( const char*, const CK_RV & );
-   static void logCK_UTF8CHAR_PTR( const char*, const unsigned char*, const std::size_t& );
-   static void logCK_TOKEN_INFO_PTR( const char*, CK_TOKEN_INFO_PTR );
-   static void logCK_MECHANISM_TYPE( const char*, CK_MECHANISM_TYPE_PTR, CK_ULONG_PTR );
-   static void logCK_MECHANISM_TYPE( const char*, CK_MECHANISM_TYPE & );
-   static void logCK_SESSION_INFO_PTR( const char*, CK_SESSION_INFO_PTR );
-   static void logCK_USER_TYPE( const char*, CK_USER_TYPE & );
-   static void logCK_ATTRIBUTE_PTR( const char*, CK_ATTRIBUTE_PTR, CK_ULONG & );
-   static void logSessionFlags( const char*, CK_FLAGS & );
-   static void logCK_MECHANISM_INFO_PTR( const char*, CK_MECHANISM_INFO_PTR );
-   static void logCK_MECHANISM_PTR( const char*, CK_MECHANISM_PTR );
-
-   static void CK_MECHANISMToString( CK_MECHANISM_PTR, std::string & );
-   static void CK_CERTIFICATE_TYPEToString( const CK_CERTIFICATE_TYPE &, std::string & );
-   static void CK_KEY_TYPEToString( const CK_KEY_TYPE&, std::string & );
-   static void CK_OBJECT_CLASSToString( const CK_OBJECT_CLASS&, std::string & );
-   static void CK_DATEToString( const CK_DATE*, std::string & );
-   static void CK_INFOToString( CK_INFO_PTR pInfo, std::string &result );
-   static void slotFlagsToString( const CK_FLAGS& f, std::string &result );
-   static void mechanismFlagsToString( const CK_FLAGS &, std::string & );
-   static void sessionFlagsToString( const CK_FLAGS & , std::string & );
-   static void CK_VERSIONToString( CK_VERSION_PTR pVersion, std::string& result );
-   static void CK_RVToString( const CK_RV& rv, std::string &result );
-   static void CK_MECHANISM_TYPEToString( CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG mechanismListLen, std::string &result );
-   static void CK_MECHANISM_TYPEToString( const CK_MECHANISM_TYPE &, std::string & );
-   static void CK_MECHANISM_INFOToString( CK_MECHANISM_INFO_PTR pInfo, std::string &result );
-   static void CK_SESSION_INFOToString( CK_SESSION_INFO_PTR, std::string& );
-   static void CK_USER_TYPEToString( const CK_USER_TYPE&, std::string & );
-   static void CK_ATTRIBUTEToString( const CK_ATTRIBUTE_PTR, std::string & );
-   static void CK_ATTRIBUTE_TYPEToString( const CK_ATTRIBUTE_TYPE& , std::string &, int& );
-
-   static void toStringHex( const unsigned char* buffer, const std::size_t& size, std::string &result );
-   static void toString( std::string &result, const char * format, ... );
-   static void toString( const unsigned char* buffer, std::size_t size, std::string &result );
-   static void toString( const unsigned long &l, std::string &result );
-
-   template<typename T> static void classtoString( const T & value, std::string &result );
-
-   static unsigned long m_ulStart;
-
-
-};
-
-
-#endif

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,74 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "digest.h"
-#include "md5.h"
-
-CMD5::CMD5(){
-    this->_hashValue     = (CK_BYTE_PTR)malloc(MD5_HASH_LENGTH);
-    this->_workingBuffer = (CK_BYTE_PTR)malloc(MD5_BLOCK_LENGTH);
-    this->_hashLength    = MD5_HASH_LENGTH;
-    this->_blockLength   = MD5_BLOCK_LENGTH;
-}
-
-CMD5::~CMD5(){
-}
-
-void CMD5::TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result)
-{
-    algo_md5_context ctx;
-
-    ctx.digest = (u4*)result;
-
-    if (counter == 0) {
-		algo_md5_starts(&ctx);
-    } else {
-        ctx.total[0] = counter;
-        ctx.total[1] = 0;
-    }
-
-    algo_md5_update(&ctx, data, MD5_BLOCK_LENGTH);
-}
-
-void CMD5::TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result)
-{
-    algo_md5_context ctx;
-
-    ctx.digest = (u4*)result;
-
-    if (counter == 0) {
-		algo_md5_starts(&ctx);
-    } else {
-        ctx.total[0] = counter;
-        ctx.total[1] = 0;
-    }
-
-    // allocate tempory working buffer
-    ctx.input = (u1*)malloc(MD5_BLOCK_LENGTH);
-    memset(ctx.input,0,MD5_BLOCK_LENGTH);
-
-    algo_md5_update(&ctx,data,length);
-    algo_md5_finish(&ctx);
-
-    free(ctx.input);
-}
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,21 +18,27 @@
  *
  */
 
+
 #ifndef _include_md5_h
 #define _include_md5_h
 
-#include "MarshallerCfg.h"
-#include "algo_md5.h"
 
+#include "digest.h"
+
+
 class CMD5 : public CDigest
 {
 private:
-    void TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result);
-    void TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result);
 
+    void TransformBlock( unsigned char* data, long counter, unsigned char* result );
+
+    void TransformFinalBlock( unsigned char* data, long length, long counter, unsigned char* result );
+
 public:
-    CMD5();
-    ~CMD5();
+
+    CMD5( );
+    
+	virtual ~CMD5( );
 };
 
 #endif

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,144 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef INCLUDE_EVENTING
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include <string>
-#ifndef WIN32
-#include <pthread.h>
-#endif
-#include "mutex.h"
-
-CMutex::CMutex()
-{
-#ifdef WIN32
-    m_hMutex = NULL;
-#endif
-    m_strName = "";
-}
-
-CMutex::CMutex(const char* nm)
-{
-    m_strName = nm;
-
-#ifdef WIN32
-    m_hMutex = (unsigned long*)CreateMutex(NULL,FALSE,nm);
-
-    if(m_hMutex == NULL)
-    {
-        assert(FALSE); //throw ThreadException("Failed to create mutex");
-    }
-#else
-    pthread_mutex_init(&m_hMutex,0);
-    m_ownerThread = 0;
-    m_refCount = 0;
-#endif
-}
-
-#ifdef WIN32
-void CMutex::create(const char* nm)
-#else
-void CMutex::create(const char*)
-#endif
-{
-
-#ifdef WIN32
-    if(m_hMutex != NULL)
-    {
-        CloseHandle(m_hMutex);
-        m_hMutex = NULL;
-    }
-
-    m_strName = nm;
-    m_hMutex = (unsigned long*)CreateMutex(NULL,FALSE,nm);
-
-    if(m_hMutex == NULL)
-    {
-        assert(FALSE); //throw ThreadException("Failed to create mutex");
-    }
-#else
-    if(pthread_equal(m_ownerThread,pthread_self()))
-    {
-        m_refCount++;
-    }
-    else
-    {
-        if(pthread_mutex_lock(&m_hMutex) == 0)
-        {
-            //assert(FALSE);
-        }
-        m_ownerThread = pthread_self();
-        m_refCount = 1;
-    }
-
-
-#endif
-}
-
-#ifdef WIN32
-unsigned long* CMutex::getMutexHandle()
-{
-    return m_hMutex;
-}
-#endif
-
-std::string CMutex::getName()
-{
-    return m_strName;
-}
-
-void CMutex::release()
-{
-#ifdef WIN32
-    if(m_hMutex != NULL)
-    {
-        CloseHandle(m_hMutex);
-        m_hMutex = NULL;
-    }
-#else
-    if(pthread_equal(m_ownerThread,pthread_self()))
-    {
-        m_refCount--;
-
-        if(!m_refCount)
-        {
-            m_ownerThread = 0;
-            pthread_mutex_unlock(&m_hMutex);
-        }
-    }
-#endif
-}
-
-CMutex::~CMutex()
-{
-#ifdef WIN32
-    if(m_hMutex != NULL)
-    {
-        CloseHandle(m_hMutex);
-    }
-#else
-    pthread_mutex_destroy(&m_hMutex);
-#endif
-}
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,54 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_mutex_h
-#define _include_mutex_h
-
-#ifdef INCLUDE_EVENTING
-
-class CMutex
-{
-private:
-    // unsigned long* to the low-level mutex object
-#ifdef WIN32
-    unsigned long* m_hMutex;
-#else
-    pthread_mutex_t m_hMutex;
-    pthread_t 		m_ownerThread;
-    unsigned long 	m_refCount;
-#endif
-    // name to identify the mutex
-    std::string m_strName;
-
-public:
-    CMutex();
-    CMutex(const char* nm);
-    ~CMutex();
-
-    void create(const char* nm);
-    unsigned long* getMutexHandle();
-    std::string getName();
-    void release();
-};
-
-#endif
-
-#endif
-

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/pbbase.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pbbase.h	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pbbase.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,526 @@
+/*
+ * Copyright (c) 2005, 2006, Precise Biometrics AB
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Precise Biometrics AB nor the names of its
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ */
+
+/*****************************************************************************
+ *
+ * Header file for the API exported from pbbase and pbbase2.
+ *
+ ****************************************************************************/
+#ifndef HEADER_PBBASE_H
+#define HEADER_PBBASE_H
+
+#include <stdlib.h>
+#include <limits.h>
+
+#if !defined(PBBASE_NO_PCSC)
+#ifdef __APPLE__
+#include <PCSC/winscard.h>
+#include <PCSC/wintypes.h>
+#else
+#include <winscard.h>
+#endif
+#endif
+
+#ifdef _WIN32
+#undef PBCALL
+#define PBCALL __cdecl
+#else
+#undef PBCALL
+#define PBCALL
+#endif
+
+typedef unsigned int pb_handle_t;
+typedef void (PBCALL *pb_image_cb_t)(pb_handle_t, pb_handle_t, void*);
+typedef void (PBCALL *pb_pnp_cb_t)(pb_handle_t, int, void*);
+
+struct pb_init_data_v1 {
+            pb_pnp_cb_t     pnp_cb;
+            void*           pnp_context;
+};
+
+/*
+ * Precise Biometrics error codes.
+ */
+
+/* The function returned without errors. */
+#define PB_EOK                0
+
+/* At least one buffer has an incorrect size. */
+#define PB_EBUFFER            1
+
+/* The function returned because the caller canceled it. */
+#define PB_ECANCEL            2
+
+/* An undefined fatal error has occurred. This error code is used for
+ * errors that "cannot happen" and isn't covered by any other error code. */
+#define PB_EFATAL             3
+
+/* The BIR is corrupt or not recognized as a BIR of the correct type. */
+#define PB_EBIR               4
+
+/* The data passed to the function is not of the correct format. */
+#define PB_EDATA              5
+
+/* The reader handle does not represent any connected reader. */
+#define PB_EREADER            6
+
+/* The session handle does not represent any open session. */
+#define PB_ESESSION           7
+
+/* File error. (e.g. "no such file", etc.) */
+#define PB_EFILE              8
+
+/* Cannot allocate enough memory. */
+#define PB_EMEMORY            9
+
+/* There is no smart card in the reader. */
+#define PB_ESMARTCARD        10
+
+/* The caller requested a version of a structure, interface etc. that is
+ * not supported by the implementation. */
+#define PB_EVERSION          11
+
+/* A function is called before the interface being initialized. */
+#define PB_EINIT             12
+
+/* The requested operation is not supported. */
+#define PB_ESUPPORT          13
+
+/* At least one of the parameters is invalid. */
+#define PB_EPARAMETER        14
+
+/* The reader is busy (only used by GUI components). */
+#define PB_EBUSY             15
+
+/* The operation timed-out before it could finish the operation. */
+#define PB_ETIMEOUT          16
+
+/* The attribute is read-only. */
+#define PB_EREADONLY         17
+
+/* There is no such attribute for this object type. */
+#define PB_EATTRIBUTE        18
+
+/* The operation is not permitted (such as reading verification data out
+ * of a secure reader, or trying to read from a token without providing
+ * the correct read key.) */
+#define PB_EPERMISSION       19
+
+/* The handle passed to the function is not correct. */
+#define PB_EHANDLE           20
+
+/* Communication error. */
+#define PB_ECOMMUNICATION    21
+
+
+/* Precise Biometrics True and False. */
+#define PB_TRUE   1
+#define PB_FALSE  0
+
+/* Enrolment purposes. */
+#define PB_PURPOSE_ENROLL_BIOMATCH                   0x00000003
+#define PB_PURPOSE_ENROLL_ANSI378                    0x02000006
+#define PB_PURPOSE_ENROLL_MOC_PPM7                   0x00018001
+#define PB_PURPOSE_ENROLL_MOC_HYBRID                 0x00018002
+#define PB_PURPOSE_ENROLL_MOC_HYBRID2                0x00018007
+
+/* Process purposes. */
+#define PB_PURPOSE_PROCESS_CLIENTSERVER              0x01000001
+#define PB_PURPOSE_PROCESS_ANSI378                   0x01000006
+
+/* Other purposes. */
+#define PB_PURPOSE_RAW_IMAGE                         0x02000002
+#define PB_PURPOSE_WAIT_FINGER_ABSENT                0x02000004
+#define PB_PURPOSE_ENROLL_ANY                        0x02000005
+
+/* PNP Events. */
+#define PB_PNP_INSERTED                                       1
+#define PB_PNP_REMOVED                                        2
+
+/* Directions. */
+#define PB_DIRECTION_NONE                                     0
+#define PB_DIRECTION_UP                                       1
+#define PB_DIRECTION_DOWN                                     2
+#define PB_DIRECTION_LEFT                                     4
+#define PB_DIRECTION_UP_LEFT                                  5
+#define PB_DIRECTION_DOWN_LEFT                                6
+#define PB_DIRECTION_RIGHT                                    8
+#define PB_DIRECTION_UP_RIGHT                                 9
+#define PB_DIRECTION_DOWN_RIGHT                              10
+#define PB_MASK_DIRECTIONS                                   15
+
+/* Finger condition. */
+#define PB_CONDITION_UNKNOWN                                  0
+#define PB_CONDITION_OK                                       1
+#define PB_CONDITION_DRY                                     -1
+#define PB_CONDITION_WET                                     -2
+
+/* Timeout constants */
+#define PB_TIMEOUT_FOREVER                             UINT_MAX
+
+/* Fingerprint representations. */
+#define PB_FPR_DEFAULT                                        0
+#define PB_FPR_STYLIZED                                       1
+#define PB_FPR_FINGERPRINT                                    2
+
+/* pb_handle_t values. */
+#define PB_HANDLE_INVALID                                     0
+#define PB_READER_SOFTWARE                                    1
+#define PB_READER_ANY                                         2
+
+/* Attributes. */
+#define PB_ATTR_PCSC_NAME                            0x00000000
+#define PB_ATTR_PRODUCT_NAME                         0x00000001
+#define PB_ATTR_IS_EMBEDDED                          0x00000002
+#define PB_ATTR_SENSOR_IMPRESSION_TYPE               0x00000004
+#define PB_ATTR_DATA_LENGTH                          0x10000001
+#define PB_ATTR_USE_LATENT_PROTECTION                0x20000001
+#define PB_ATTR_CANCEL                               0x20000002
+#define PB_ATTR_NOF_OPEN_HANDLES                     0x20000003
+#define PB_ATTR_MAX_NOF_OPEN_HANDLES                 0x20000004
+
+/* The sensor impression type returned by PB_ATTR_SENSOR_IMPRESSION_TYPE. */
+#define PB_IMPRESSION_TYPE_PLAIN                              0
+#define PB_IMPRESSION_TYPE_SWIPE                              8
+
+/* Security levels. */
+#define PB_FAR_100                              (0x7fffffff/100)
+#define PB_FAR_1000                            (0x7fffffff/1000)
+#define PB_FAR_10000                          (0x7fffffff/10000)
+#define PB_FAR_100000                        (0x7fffffff/100000)
+#define PB_FAR_1000000                      (0x7fffffff/1000000)
+
+/* Tags. */
+#ifndef PB_BIR_TAG_PAYLOAD
+#define PB_BIR_TAG_PAYLOAD                                 0xc0
+#define PB_BIR_TAG_TEMPLATE                                0xc1
+#define PB_BIR_TAG_IMAGE                                   0xc3
+#define PB_BIR_TAG_BIOMETRIC_HEADER                        0xc5
+#define PB_BIR_TAG_REFERENCE_DATA                          0xc6
+#define PB_BIR_TAG_VERIFICATION_DATA                       0xc7
+#define PB_BIR_TAG_FINGER_CONTAINER                        0xe3
+#define PB_BIR_TAG_BIOMETRIC_SUBTYPE                       0xc2
+#endif /* PB_BIR_TAG_PAYLOAD */
+
+/* Image orientation values. */
+#ifndef PB_BIR_ORIENTATION_ROT_0
+#define PB_BIR_ORIENTATION_ROT_0                              0
+#define PB_BIR_ORIENTATION_ROT_90                             1
+#define PB_BIR_ORIENTATION_ROT_180                            2
+#define PB_BIR_ORIENTATION_ROT_270                            3
+#define PB_BIR_ORIENTATION_ROT_0_MIRROR                       4
+#define PB_BIR_ORIENTATION_ROT_90_MIRROR                      5
+#define PB_BIR_ORIENTATION_ROT_180_MIRROR                     6
+#define PB_BIR_ORIENTATION_ROT_270_MIRROR                     7
+#endif /* PB_BIR_ORIENTATION_ROT_0 */
+
+/* Finger constants. */
+#ifndef PB_BIR_FINGER_LEFT_LITTLE
+#define PB_BIR_FINGER_LEFT_LITTLE                            54
+#define PB_BIR_FINGER_LEFT_RING                              50
+#define PB_BIR_FINGER_LEFT_MIDDLE                            46
+#define PB_BIR_FINGER_LEFT_POINTER                           42
+#define PB_BIR_FINGER_LEFT_THUMB                             38
+#define PB_BIR_FINGER_RIGHT_THUMB                            37
+#define PB_BIR_FINGER_RIGHT_POINTER                          41
+#define PB_BIR_FINGER_RIGHT_MIDDLE                           45
+#define PB_BIR_FINGER_RIGHT_RING                             49
+#define PB_BIR_FINGER_RIGHT_LITTLE                           53
+#endif /* PB_BIR_FINGER_LEFT_LITTLE */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * General functions.
+ */
+
+int PBCALL pb_initialize(
+        int                     version,
+        void*                   init_data,
+        int*                    id);
+
+int PBCALL pb_list_readers(
+        pb_handle_t**           readerlist, 
+        int*                    numreaders);
+
+int PBCALL pb_open_session(
+        pb_handle_t             reader, 
+        unsigned int            timeout,
+        pb_handle_t*            session);
+
+int PBCALL pb_close_session(
+        pb_handle_t*            session);
+
+int PBCALL pb_get_reader_attribute(
+        pb_handle_t             reader,
+        unsigned int            attribute,
+        void*                   value,
+        size_t                  size,
+        size_t*                 size_returned);
+
+int PBCALL pb_set_reader_attribute(
+        pb_handle_t             reader,
+        unsigned int            attribute,
+        const void*             value,
+        size_t                  size);
+
+int PBCALL pb_get_session_attribute(
+        pb_handle_t             session,
+        unsigned int            attribute,
+        void*                   value,
+        size_t                  size,
+        size_t*                 size_returned);
+
+int PBCALL pb_set_session_attribute(
+        pb_handle_t             session,
+        unsigned int            attribute,
+        const void*             value,
+        size_t                  size);
+
+int PBCALL pb_get_bir_attribute(
+        pb_handle_t             session,
+        pb_handle_t             bir,
+        unsigned int            attribute,
+        void*                   value,
+        size_t                  size,
+        size_t*                 size_returned);
+
+int PBCALL pb_set_bir_attribute(
+        pb_handle_t             session,
+        pb_handle_t             bir,
+        unsigned int            attribute,
+        const void*             value,
+        size_t                  size);
+
+int PBCALL pb_handle_to_bir(
+        pb_handle_t             session,
+        pb_handle_t             handle,
+        void**                  bir,
+        size_t*                 len);
+
+int PBCALL pb_bir_to_handle(
+        pb_handle_t             session,                          
+        const void*             bir,
+        size_t                  len,
+        pb_handle_t*            handle);
+
+int PBCALL pb_cancel(
+        pb_handle_t             session);
+
+int PBCALL pb_free_bir_handle(
+        pb_handle_t             session,
+        pb_handle_t*            bir);
+
+int PBCALL pb_free(
+        void*                   ptr);
+ 
+int PBCALL pb_release(
+        int                     id);
+
+
+/*
+ * Feedback functions.
+ */
+
+int PBCALL pb_finger_guide(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        unsigned int*           direction,
+        unsigned int*           score);
+
+int PBCALL pb_finger_present(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        int*                    present);
+
+int PBCALL pb_finger_quality(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        int*                    quality,
+        int*                    finger_condition);
+
+int PBCALL pb_get_image_for_viewing(
+        pb_handle_t             session,
+        pb_handle_t             src_image,
+        int                     dest_x_size,
+        int                     dest_y_size,
+        int                     dest_x_buf_size,
+        int                     representation,
+        void*                   dest_image);
+
+
+/*
+ * Biometric functions.
+ */
+
+int PBCALL pb_capture_image(
+        pb_handle_t             session,
+        unsigned int            purpose,
+        unsigned int            timeout,
+        pb_image_cb_t           callback,
+        void*                   context,
+        pb_handle_t*            image);
+
+int PBCALL pb_capture_verification_data(
+        pb_handle_t             session,
+        pb_handle_t             biometric_header,
+        unsigned int            timeout,
+        pb_image_cb_t           callback,
+        void*                   context,
+        pb_handle_t*            verification_data);
+
+int PBCALL pb_create_template(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        unsigned int            purpose,
+        int*                    quality,
+        pb_handle_t*            bir);
+
+int PBCALL pb_create_moc_template(
+        pb_handle_t             session,
+        pb_handle_t             source_bir,
+        unsigned int            purpose,
+        int                     far_requested,
+        int*                    quality,
+        pb_handle_t*            biometric_header,
+        pb_handle_t*            reference_data);
+
+int PBCALL pb_create_verification_data(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        pb_handle_t             biometric_header,
+        pb_handle_t*            verification_data);
+
+int PBCALL pb_enroll(
+        pb_handle_t             session,
+        unsigned int            purpose,
+        unsigned int            timeout,
+        pb_image_cb_t           callback,
+        void*                   context,
+        int*                    quality,
+        pb_handle_t*            image,
+        pb_handle_t*            bir);
+
+int PBCALL pb_enroll_moc(
+        pb_handle_t             session,
+        unsigned int            purpose,
+        int                     far_requested,
+        unsigned int            timeout,
+        pb_image_cb_t           callback,
+        void*                   context,
+        int*                    quality,
+        pb_handle_t*            image,
+        pb_handle_t*            biometric_header,
+        pb_handle_t*            reference_data);
+
+int PBCALL pb_process(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        unsigned int            purpose,
+        int*                    quality,
+        void**                  bir,
+        size_t*                 bir_size);
+
+int PBCALL pb_validate_moc_template(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        pb_handle_t             biometric_header,
+        pb_handle_t             reference_data,
+        int*                    quality);
+
+int PBCALL pb_validate_template(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        pb_handle_t             bir,
+        int*                    quality);
+
+int PBCALL pb_verify(
+        pb_handle_t             session,
+        pb_handle_t*            templates,
+        int                     ntemplates,
+        const int*              far_requested,
+        const int*              frr_requested,
+        unsigned int            timeout,
+        pb_image_cb_t           callback,
+        void*                   context,
+        int*                    result,
+        int*                    far_achieved,
+        int*                    frr_achieved,
+        int*                    score);
+
+int PBCALL pb_verify_match(
+        pb_handle_t             session,
+        pb_handle_t             image,
+        pb_handle_t*            templates,
+        unsigned int            ntemplates,
+        const int*              far_requested,
+        const int*              frr_requested,
+        int*                    match_result,
+        int*                    index,
+        int*                    far_achieved,
+        int*                    frr_achieved,
+        int*                    score);
+
+
+/*
+ * Smart card functions.
+ */
+
+#if !defined(PBBASE_NO_PCSC)
+int PBCALL pb_session_from_scardhandle(
+        SCARDHANDLE             hCard,
+        unsigned int            timeout,
+        pb_handle_t*            session);
+
+int PBCALL pb_write_bir_to_card(
+        pb_handle_t             session,
+        pb_handle_t             bir,
+        size_t                  bir_offset,
+        size_t                  sendbuf_offset,
+        size_t                  size,
+        SCARDHANDLE             hCard,
+        LPCSCARD_IO_REQUEST     pioSendPci,
+        LPCBYTE                 pbSendBuffer,
+        DWORD                   cbSendLength,
+        LPSCARD_IO_REQUEST      pioRecvPci,
+        LPBYTE                  pbRecvBuffer,
+        LPDWORD                 pcbRecvLength);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HEADER_PBBASE_H */

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs-11v2-20a3.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs-11v2-20a3.h	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs-11v2-20a3.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,119 @@
+/* pkcs-11v2-20a3.h include file for the PKCS #11 Version 2.20 Amendment 3
+   document. */
+
+/* $Revision: 1.1 $ */
+
+/* License to copy and use this software is granted provided that it is
+ * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
+ * (Cryptoki) Version 2.20 Amendment 3" in all material mentioning or
+ * referencing this software.
+
+ * RSA Security Inc. makes no representations concerning either the 
+ * merchantability of this software or the suitability of this software for
+ * any particular purpose. It is provided "as is" without express or implied
+ * warranty of any kind.
+ */
+
+/* This file is preferably included after inclusion of pkcs11.h */
+
+#ifndef _PKCS_11V2_20A3_H_
+#define _PKCS_11V2_20A3_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Key types */
+
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
+#define CKK_CAMELLIA                   0x00000025
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
+#define CKK_ARIA                       0x00000026
+
+
+/* Mask-generating functions */
+
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
+#define CKG_MGF1_SHA224                0x00000005
+
+
+/* Mechanism Identifiers */
+
+/* SHA-224 is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224                     0x00000255
+#define CKM_SHA224_HMAC                0x00000256
+#define CKM_SHA224_HMAC_GENERAL        0x00000257
+
+/* SHA-224 key derivation is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224_KEY_DERIVATION      0x00000396
+
+/* SHA-224 RSA mechanisms are new for PKCS #11 v2.20 amendment 3 */
+#define CKM_SHA224_RSA_PKCS            0x00000046
+#define CKM_SHA224_RSA_PKCS_PSS        0x00000047
+
+/* AES counter mode is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_AES_CTR                    0x00001086
+
+/* Camellia is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_CAMELLIA_KEY_GEN           0x00000550
+#define CKM_CAMELLIA_ECB               0x00000551
+#define CKM_CAMELLIA_CBC               0x00000552
+#define CKM_CAMELLIA_MAC               0x00000553
+#define CKM_CAMELLIA_MAC_GENERAL       0x00000554
+#define CKM_CAMELLIA_CBC_PAD           0x00000555
+#define CKM_CAMELLIA_ECB_ENCRYPT_DATA  0x00000556
+#define CKM_CAMELLIA_CBC_ENCRYPT_DATA  0x00000557
+#define CKM_CAMELLIA_CTR               0x00000558
+
+/* ARIA is new for PKCS #11 v2.20 amendment 3 */
+#define CKM_ARIA_KEY_GEN               0x00000560
+#define CKM_ARIA_ECB                   0x00000561
+#define CKM_ARIA_CBC                   0x00000562
+#define CKM_ARIA_MAC                   0x00000563
+#define CKM_ARIA_MAC_GENERAL           0x00000564
+#define CKM_ARIA_CBC_PAD               0x00000565
+#define CKM_ARIA_ECB_ENCRYPT_DATA      0x00000566
+#define CKM_ARIA_CBC_ENCRYPT_DATA      0x00000567
+
+
+/* Mechanism parameters */
+
+/* CK_AES_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_AES_CTR_PARAMS {
+    CK_ULONG ulCounterBits;
+    CK_BYTE cb[16];
+} CK_AES_CTR_PARAMS;
+
+typedef CK_AES_CTR_PARAMS CK_PTR CK_AES_CTR_PARAMS_PTR;
+
+/* CK_CAMELLIA_CTR_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_CAMELLIA_CTR_PARAMS {
+    CK_ULONG ulCounterBits;
+    CK_BYTE cb[16];
+} CK_CAMELLIA_CTR_PARAMS;
+
+typedef CK_CAMELLIA_CTR_PARAMS CK_PTR CK_CAMELLIA_CTR_PARAMS_PTR;
+
+/* CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS {
+    CK_BYTE      iv[16];
+    CK_BYTE_PTR  pData;
+    CK_ULONG     length;
+} CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_CAMELLIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_ARIA_CBC_ENCRYPT_DATA_PARAMS is new for PKCS #11 v2.20 amendment 3 */
+typedef struct CK_ARIA_CBC_ENCRYPT_DATA_PARAMS {
+    CK_BYTE      iv[16];
+    CK_BYTE_PTR  pData;
+    CK_ULONG     length;
+} CK_ARIA_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_ARIA_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_ARIA_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,2741 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#define CRYPTOKIVERSION_INTERFACE_MAJOR  0x02
-#define CRYPTOKIVERSION_INTERFACE_MINOR  0x14
-
-#define CRYPTOKIVERSION_LIBRARY_MAJOR    0x02
-#define CRYPTOKIVERSION_LIBRARY_MINOR    0x00
-
-#define LIBRARY_DESCRIPTION             "CF .NET PKCS#11 Module"
-#define MANUFACTURER_ID                 "Gemalto"
-
-#include <string>
-
-#include "stdafx.h"
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include "error.h"
-#include "platconfig.h"
-#include "config.h"
-#include "digest.h"
-#include "symmalgo.h"
-#include "thread.h"
-#include "event.h"
-#include "mutex.h"
-#include "session.h"
-#include "slot.h"
-#include "application.h"
-#include "critsect.h"
-#include "log.h"
-
-
-static CK_BBOOL _isInitialized = FALSE;
-
-
-// This libarary is thread protected by a single critical section
-// This coarse grained approach is for simplicty, the alternative
-// require significant work.
-CCriticalSection _critSect;
-
-CCriticalSection _critSectAPI;
-
-
-static const CK_FUNCTION_LIST FunctionList = {
-   { CRYPTOKIVERSION_LIBRARY_MAJOR, CRYPTOKIVERSION_LIBRARY_MINOR },
-
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-
-#define CK_PKCS11_FUNCTION_INFO(func) func,
-
-#include "pkcs11f.h"
-
-#undef CK_PKCS11_FUNCTION_INFO
-#undef CK_NEED_ARG_LIST
-};
-
-
-#define PKCS11_TRY \
-   if (!_isInitialized) { \
-   return CKR_CRYPTOKI_NOT_INITIALIZED; } \
-   CCriticalSectionLocker __cslock(_critSect); \
-   try
-
-
-#define PKCS11_CATCH(rv) \
-   catch(CkError & err) { rv = err.Error(); } \
-   catch(PcscError & ) { rv = CKR_FUNCTION_FAILED; } \
-   catch(Marshaller::Exception & exc) { rv = CkError::CheckMarshallerException(exc); } \
-   catch(...) { rv = CKR_GENERAL_ERROR; }
-
-
-// Put all static initializations here to ensure they
-// occur in correct order.
-
-CEvent CryptokiEvent(0xFFFFFFFF);
-
-// CStartStopControl to support clean up at DLL unload
-class CStartStopControl
-{
-public:
-   CStartStopControl() {};
-   ~CStartStopControl() {
-      Application::End( );
-   }
-} foo;
-
-
-extern "C"
-{
-
-
-   /**
-   * C_Initialize initializes the Cryptoki library.
-   *
-   * @param pInitArgs
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Initialize )( CK_VOID_PTR pInitArgs )
-   {     
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Initialize" );
-         Log::in( "C_Initialize" );
-         Log::log( "C_Initialize - pInitArgs <%#02x>", pInitArgs );
-         //SLog::log( S"C_Initialize - isInitialized <%#02x>", _isInitialized );
-
-         // Already Initialized
-         if( TRUE == _isInitialized )
-         {
-            Log::error( "C_Initialize", "CKR_CRYPTOKI_ALREADY_INITIALIZED" );
-            rv = CKR_CRYPTOKI_ALREADY_INITIALIZED;
-         }
-         else if( NULL_PTR != pInitArgs )
-         {
-            CK_C_INITIALIZE_ARGS initArgs = *(CK_C_INITIALIZE_ARGS_PTR)pInitArgs;
-
-            Log::logCK_C_INITIALIZE_ARGS_PTR( "C_Initialize", (CK_C_INITIALIZE_ARGS_PTR)pInitArgs );
-
-            if( NULL_PTR != initArgs.pReserved )
-            {
-               Log::error( "C_Initialize", "CKR_ARGUMENTS_BAD" );
-               rv = CKR_ARGUMENTS_BAD;
-            }
-            else if( initArgs.flags & CKF_LIBRARY_CANT_CREATE_OS_THREADS )
-            {
-               Log::error( "C_Initialize", "CKR_NEED_TO_CREATE_THREADS" );
-               rv = CKR_NEED_TO_CREATE_THREADS;
-            }
-            else if( initArgs.flags & CKF_OS_LOCKING_OK )
-            {
-               if( initArgs.CreateMutex || initArgs.DestroyMutex || initArgs.LockMutex || initArgs.UnlockMutex )
-               {
-                  Log::error( "C_Initialize", "CKR_CANT_LOCK" );
-                  rv = CKR_CANT_LOCK;
-               }
-            }
-            else if( initArgs.CreateMutex || initArgs.DestroyMutex || initArgs.LockMutex || initArgs.UnlockMutex )
-            {
-               if( !initArgs.CreateMutex || !initArgs.DestroyMutex || !initArgs.LockMutex || !initArgs.UnlockMutex )
-               {
-                  Log::error( "C_Initialize", "CKR_ARGUMENTS_BAD" );
-                  rv = CKR_ARGUMENTS_BAD;
-               }
-               else if( !( initArgs.flags & CKF_OS_LOCKING_OK ) )
-               {
-                  Log::error( "C_Initialize", "CKR_CANT_LOCK" );
-                  rv = CKR_CANT_LOCK;
-               }
-            }
-         }
-
-         if (rv == CKR_OK)
-         {
-            Application::InitApplication( );
-            _isInitialized = TRUE;
-         }
-
-         Log::log( "C_Initialize - isInitialized <%#02x>", _isInitialized );
-
-         Log::logCK_RV( "C_Initialize", rv );
-         Log::end( "C_Initialize\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_Finalize indicates that an application is done with the
-   * Cryptoki library.
-   *
-   * @param pReserved reserved.Should be NULL_PTR
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Finalize )( CK_VOID_PTR pReserved )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Finalize" );
-         Log::in( "C_Finalize" );
-         Log::log( "C_Finalize - pReserved <%#02x>", pReserved );
-
-         // Not Initialized
-         if( !_isInitialized )
-         {
-            Log::error( "C_Finalize", "CKR_CRYPTOKI_NOT_INITIALIZED" );
-            rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-         }
-         else if( NULL_PTR != pReserved )
-         {
-            Log::error( "C_Finalize", "CKR_ARGUMENTS_BAD" );
-            rv = CKR_ARGUMENTS_BAD;
-         }
-         else
-         {
-            _isInitialized = FALSE;
-            Application::End( );
-         }
-
-         Log::logCK_RV( "C_Finalize", rv );
-         Log::end( "C_Finalize\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetInfo returns general information about Cryptoki.
-   *
-   * @param pInfo location that receives information
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetInfo )( CK_INFO_PTR pInfo )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetInfo" );
-         Log::in( "C_GetInfo" );
-         Log::logCK_INFO( "C_GetInfo", pInfo );
-
-         if( FALSE == _isInitialized )
-         {
-            rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-         }
-         else if( NULL_PTR == pInfo )
-         {
-            rv = CKR_ARGUMENTS_BAD;
-         }
-         else
-         {
-            pInfo->cryptokiVersion.major = CRYPTOKIVERSION_INTERFACE_MAJOR;
-            pInfo->cryptokiVersion.minor = CRYPTOKIVERSION_INTERFACE_MINOR;
-            pInfo->flags = 0;
-            memset(pInfo->libraryDescription, ' ', sizeof(pInfo->libraryDescription));
-            memcpy(pInfo->libraryDescription, LIBRARY_DESCRIPTION, strlen(LIBRARY_DESCRIPTION));
-            memset(pInfo->manufacturerID, ' ', sizeof(pInfo->manufacturerID));
-            memcpy(pInfo->manufacturerID, MANUFACTURER_ID, strlen(MANUFACTURER_ID));
-            pInfo->libraryVersion.major  = CRYPTOKIVERSION_LIBRARY_MAJOR;
-            pInfo->libraryVersion.minor  = CRYPTOKIVERSION_LIBRARY_MINOR;
-         }
-
-         Log::logCK_RV( "C_GetInfo", rv );
-         Log::out( "C_GetInfo" );
-         Log::logCK_INFO( "C_GetInfo", pInfo );
-         Log::end( "C_GetInfo\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-   /**
-   * C_GetFunctionList returns the function list.
-   *
-   * @param ppFunctionList receives pointer to function list
-   */
-   CK_DEFINE_FUNCTION( CK_RV,C_GetFunctionList )( CK_FUNCTION_LIST_PTR_PTR ppFunctionList )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetFunctionList" );
-         Log::in( "C_GetFunctionList" );
-         Log::log( "C_GetFunctionList - CK_FUNCTION_LIST_PTR_PTR <%#02x>", ppFunctionList );
-
-         if( NULL_PTR == ppFunctionList )
-         {
-            rv = CKR_ARGUMENTS_BAD;
-         }
-         else
-         {
-            // this is the only function which an application can call before calling C_Initialize
-            *ppFunctionList = (CK_FUNCTION_LIST_PTR)&FunctionList;
-         }
-
-         Log::logCK_RV( "C_GetFunctionList", rv );
-         Log::out( "C_GetFunctionList" );
-         Log::log( "C_GetFunctionList - CK_FUNCTION_LIST_PTR_PTR <%#02x>", ppFunctionList );
-         Log::end( "C_GetFunctionList\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetSlotList obtains a list of slots in the system.
-   *
-   * @param tokenPresent only slots with tokens
-   * @param pSlotList    receives array of slot IDs
-   * @param pulCount     receives number of slots
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetSlotList )( CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetSlotList" );
-         Log::in( "C_GetSlotList" );
-         Log::log( "C_GetSlotList - tokenPresent <%d>", tokenPresent );
-         Log::logCK_SLOT_ID_PTR( "C_GetSlotList", pSlotList, pulCount );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Application::Enumerate( tokenPresent, pSlotList, pulCount );
-         }
-         PKCS11_CATCH( rv )
-         Log::stop( "C_GetSlotList" );
-
-         Log::logCK_RV( "C_GetSlotList", rv );
-         Log::out( "C_GetSlotList" );
-         Log::logCK_SLOT_ID_PTR( "C_GetSlotList", pSlotList, pulCount );
-         Log::end( "C_GetSlotList\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetSlotInfo obtains information about a particular slot in
-   * the system.
-   *
-   * @param slotId the ID of the slot
-   * @param pInfo  received the slot information
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetSlotInfo )( CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetSlotInfo" );
-         Log::in( "C_GetSlotInfo" );
-         Log::log( "C_GetSlotInfo - slotID <%ld>", slotID );
-         Log::logCK_SLOT_INFO_PTR( "C_GetSlotInfo", pInfo );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-           //if(Application::_numSlots == 0)
-           // {
-           //    //CK_ULONG slotCount = 0;
-           //    //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-           //    CK_ULONG slotCount = 32;
-           //    CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-           //    Application::Enumerate( CK_FALSE, slots, &slotCount );
-           //    free(slots);
-           // }
-
-            Slot* pSlot = NULL_PTR;
-            rv = Application::GetSlotFromSlotId( slotID, &pSlot );
-
-            if(rv == CKR_OK)
-            {
-               rv = pSlot->GetInfo( pInfo );
-            }
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GetSlotInfo" );
-
-         Log::logCK_RV( "C_GetSlotInfo", rv );
-         Log::out( "C_GetSlotInfo" );
-         Log::logCK_SLOT_INFO_PTR( "C_GetSlotInfo", pInfo );
-         Log::end( "C_GetSlotInfo\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetTokenInfo obtains information about a particular token
-   * in the system.
-   *
-   * @param slotID ID of the token's slot
-   * @param pInfo  receives the token information
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetTokenInfo )( CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetTokenInfo" );
-         Log::in( "C_GetTokenInfo" );
-         Log::log( "C_GetTokenInfo - slotID <%ld>", slotID );
-         Log::logCK_TOKEN_INFO_PTR( "C_GetTokenInfo", pInfo );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            //if(Application::_numSlots == 0)
-            //{
-            //   //CK_ULONG slotCount = 0;
-            //   //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-            //   CK_ULONG slotCount = 32;
-            //   CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-            //   Application::Enumerate( CK_FALSE, slots, &slotCount );
-            //   free(slots);
-            //}
-
-            Slot* slot = NULL_PTR;
-            rv = Application::GetSlotFromSlotId(slotID,&slot);
-
-            if(rv == CKR_OK)
-            {
-               rv = slot->GetTokenInfo(pInfo);
-            }
-         }
-         //PKCS11_CATCH(rv)
-         catch( CkError & e )
-         {
-            rv = e.Error( );
-            //Log::log( "C_GetTokenInfo - ## Error ## CkError <%s> <%#02x>", e.what( ), e.Error( ) );
-         }
-         catch( PcscError & /*e*/ )
-         {
-            rv = CKR_FUNCTION_FAILED;
-            //Log::log( "C_GetTokenInfo - ## Error ## PcscError <%s> <%#02x> <%#02x>", e.what( ), e.Error( ), rv );
-         }
-         catch( Marshaller::Exception & e )
-         {
-            rv = CkError::CheckMarshallerException( e );
-            //Log::log( "C_GetTokenInfo - ## Error ## PcscError <%s> <%#02x>", e.what( ), rv );
-         }
-         catch( ... )
-         {
-            rv = CKR_GENERAL_ERROR;
-            //Log::log( "C_GetTokenInfo - ## Error ## (...) <%#02x>", rv );
-         }
-         Log::stop( "C_GetTokenInfo" );
-
-         Log::logCK_RV( "C_GetTokenInfo", rv );
-         Log::out( "C_GetTokenInfo" );
-         Log::logCK_TOKEN_INFO_PTR( "C_GetTokenInfo", pInfo );
-         Log::end( "C_GetTokenInfo\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetMechanismList obtains a list of mechanism types
-   * supported by a token.
-   *
-   * @param slotID ID of token's slot
-   * @param pMechanismList gets mech. array
-   * @param pulCount get number of mechs
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetMechanismList )( CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetMechanismList" );
-         Log::in( "C_GetMechanismList" );
-         Log::log( "C_GetMechanismList - slotID <%#02x>", slotID );
-         Log::logCK_MECHANISM_TYPE( "C_GetMechanismList", pMechanismList, pulCount );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            //if(Application::_numSlots == 0)
-            //{
-            //   //CK_ULONG slotCount = 0;
-            //   //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-            //   CK_ULONG slotCount = 32;
-            //   CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-            //   Application::Enumerate( CK_FALSE, slots, &slotCount );
-            //   free(slots);
-            //}
-
-            Slot* slot = NULL_PTR;
-            rv    = Application::GetSlotFromSlotId(slotID,&slot);
-
-            if(rv == CKR_OK)
-            {
-               rv = slot->GetMechanismList(pMechanismList,pulCount);
-            }
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GetMechanismList" );
-
-         Log::logCK_RV( "C_GetMechanismList", rv );
-         Log::out( "C_GetMechanismList" );
-         Log::logCK_MECHANISM_TYPE( "C_GetMechanismList", pMechanismList, pulCount );
-         Log::end( "C_GetMechanismList\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetMechanismInfo obtains information about a particular
-   * mechanism possibly supported by a token.
-   *
-   * @param slotID ID of the token's slot
-   * @param type  type of mechanism
-   * @param pInfo receives mechanism info
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetMechanismInfo )( CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetMechanismInfo" );
-         Log::in( "C_GetMechanismInfo" );
-         Log::log( "C_GetMechanismInfo - slotID <%#02x>", slotID );
-         Log::logCK_MECHANISM_TYPE( "C_GetMechanismInfo", type );
-         Log::logCK_MECHANISM_INFO_PTR( "C_GetMechanismInfo", pInfo );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            //if(Application::_numSlots == 0)
-            //{
-            //   //CK_ULONG slotCount = 0;
-            //   //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-            //   CK_ULONG slotCount = 32;
-            //   CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-            //   Application::Enumerate( CK_FALSE, slots, &slotCount );
-            //   free(slots);
-            //}
-
-            Slot* slot = NULL_PTR;
-            rv    = Application::GetSlotFromSlotId(slotID,&slot);
-
-            if(rv == CKR_OK)
-            {
-               rv = slot->GetMechanismInfo(type,pInfo);
-            }
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GetMechanismInfo" );
-
-         Log::logCK_RV( "C_GetMechanismInfo", rv );
-         Log::out( "C_GetMechanismInfo" );
-         Log::logCK_MECHANISM_INFO_PTR( "C_GetMechanismInfo", pInfo );
-         Log::end( "C_GetMechanismInfo\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_InitToken initializes a token.
-   *
-   * @param slotID ID of the token's slot
-   * @param pPin   the SO's initial PIN
-   * @param ulPinLen length in bytes of the PIN
-   * @param pLabel 32-byte token label (blank padded) pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_InitToken )( CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_InitToken" );
-         Log::in( "C_InitToken" );
-         Log::log( "C_InitToken - slotID <%#02x>", slotID );
-         Log::logCK_UTF8CHAR_PTR( "C_InitToken - pPin", pPin, ulPinLen );
-         Log::logCK_UTF8CHAR_PTR( "C_InitToken - pLabel", pLabel, 32 );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            //if(Application::_numSlots == 0)
-            //{
-            //   //CK_ULONG slotCount = 0;
-            //   //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-            //   CK_ULONG slotCount = 32;
-            //   CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-            //   Application::Enumerate( CK_FALSE, slots, &slotCount );
-            //   free(slots);
-            //}
-
-            Slot* slot = NULL_PTR;
-            rv    = Application::GetSlotFromSlotId(slotID,&slot);
-
-            if(rv == CKR_OK)
-            {
-               rv = slot->InitToken(pPin,ulPinLen,pLabel);
-            }
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_InitToken" );
-
-         Log::logCK_RV( "C_InitToken", rv );
-         Log::end( "C_InitToken\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_InitPIN initializes the normal user's PIN.
-   *
-   * @param hSession the session's handle
-   * @param pPin the noraml user's PIN
-   * @param ulPinLen length in bytes of the PIN
-   */
-   CK_DEFINE_FUNCTION( CK_RV,C_InitPIN )( CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_InitPIN" );
-         Log::in( "C_InitPIN" );
-         Log::log( "C_InitPIN - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_InitPIN - pPin", pPin, ulPinLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::InitPIN( hSession, pPin, ulPinLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_InitPIN" );
-
-         Log::logCK_RV( "C_InitPIN", rv );
-         Log::end( "C_InitPIN\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-      return rv;
-   }
-
-
-   /**
-   * C_SetPIN modifies the PIN of the user who is logged in.
-   *
-   * @param hSession   the session's handle
-   * @param pOldPin     the old PIN
-   * @param ulOldPin    length of the old PIN
-   * @param pNewPin     the new PIN
-   * @param ulNewLen    length of the new PIN
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_SetPIN )( CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, CK_ULONG ulOldLen, CK_UTF8CHAR_PTR pNewPin, CK_ULONG ulNewLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_SetPIN" );
-         Log::in( "C_SetPIN" );
-         Log::log( "C_SetPIN - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_SetPIN - pOldPin", pOldPin, ulOldLen );
-         Log::logCK_UTF8CHAR_PTR( "C_SetPIN - pNewPin", pNewPin, ulNewLen );
-
-         Log::start( );
-         CK_RV rv = CKR_OK;
-         PKCS11_TRY
-         {
-            rv = Slot::SetPIN( hSession, pOldPin, ulOldLen, pNewPin, ulNewLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_SetPIN" );
-
-         Log::logCK_RV( "C_SetPIN", rv );
-         Log::end( "C_SetPIN\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_OpenSession opens a session between an application and a
-   * token.
-   *
-   * @param slotID       the slot's ID
-   * @param flags        from CK_SESSION_INFO
-   * @param pApplication passed to callback
-   * @param Notify       callback function
-   * @param phSession    gets session handle
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_OpenSession )( CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_OpenSession" );
-         Log::in( "C_OpenSession" );
-         Log::log( "C_OpenSession - slotID <%#02x>", slotID );
-         Log::logSessionFlags( "C_OpenSession", flags );
-         Log::log( "C_OpenSession - pApplication <%#02x>", pApplication );
-         Log::log( "C_OpenSession - Notify <%#02x>", Notify );
-         Log::log( "C_OpenSession - phSession <%#02x> (%#02x)", phSession, ( ( NULL_PTR != phSession ) ? *phSession : 0 ) );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            //if(Application::_numSlots == 0)
-            //{
-            //   //CK_ULONG slotCount = 0;
-            //   //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-            //   CK_ULONG slotCount = 32;
-            //   CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-            //   Application::Enumerate( CK_FALSE, slots, &slotCount );
-            //   free(slots);
-            //}
-
-            Slot* slot = NULL_PTR;
-            rv = Application::GetSlotFromSlotId(slotID,&slot);
-
-            if(rv == CKR_OK)
-            {
-               PKCS11_ASSERT(slot != NULL_PTR);
-               rv = slot->OpenSession(flags,pApplication,Notify,phSession);
-            }
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_OpenSession" );
-
-         Log::logCK_RV( "C_OpenSession", rv );
-         Log::out( "C_OpenSession" );
-         Log::log( "C_OpenSession - phSession <%#02x> (%ld)", phSession, ( ( NULL_PTR != phSession ) ? *phSession : 0 ) );
-         Log::end( "C_OpenSession\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_CloseSession closes a session between an application and a
-   * token.
-   *
-   * @param hSession the session's handle
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_CloseSession )( CK_SESSION_HANDLE hSession )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_CloseSession" );
-         Log::in( "C_CloseSession" );
-         Log::log( "C_CloseSession - hSession <%#02x>", hSession );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::CloseSession(hSession);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_CloseSession" );
-
-         Log::logCK_RV( "C_CloseSession", rv );
-         Log::end( "C_CloseSession\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_CloseAllSessions closes all sessions with a token.
-   *
-   * @param slotID the token's slot
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_CloseAllSessions )( CK_SLOT_ID slotID )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_CloseAllSessions" );
-         Log::in( "C_CloseAllSessions" );
-         Log::log( "C_CloseAllSessions - slotID <%#02x>", slotID );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            //if(Application::_numSlots == 0)
-            //{
-            //   //CK_ULONG slotCount = 0;
-            //   //Application::Enumerate(CK_FALSE,NULL_PTR,&slotCount);
-            //   CK_ULONG slotCount = 32;
-            //   CK_SLOT_ID_PTR slots = (CK_SLOT_ID_PTR) malloc( sizeof( CK_SLOT_ID ) * slotCount );
-            //   Application::Enumerate( CK_FALSE, slots, &slotCount );
-            //   free(slots);
-            //}
-
-            Slot* slot = NULL_PTR;
-            rv    = Application::GetSlotFromSlotId(slotID,&slot);
-
-            if(rv == CKR_OK)
-            {
-               rv = slot->CloseAllSessions();
-            }
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_CloseAllSessions" );
-
-         Log::logCK_RV( "C_CloseAllSessions", rv );
-         Log::end( "C_CloseAllSessions\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetSessionInfo obtains information about the session.
-   *
-   * @param hSession the session's handle
-   * @param receives session info
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetSessionInfo )( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetSessionInfo" );
-         Log::in( "C_GetSessionInfo" );
-         Log::log( "C_GetSessionInfo - hSession <%#02x>", hSession );
-         Log::logCK_SESSION_INFO_PTR( "C_GetSessionInfo", pInfo );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::GetSessionInfo(hSession,pInfo);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GetSessionInfo" );
-
-         Log::logCK_RV( "C_GetSessionInfo", rv );
-         Log::out( "C_GetSessionInfo" );
-         Log::logCK_SESSION_INFO_PTR( "C_GetSessionInfo", pInfo );
-         Log::end( "C_GetSessionInfo\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetOperationState obtains the state of the cryptographic operation
-   * in a session.
-   *
-   * @param hSession session's handle
-   * @param pOperationState gets State
-   * @param pulOperationStateLen gets state length
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetOperationState )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_GetOperationState" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-      Log::logCK_RV( "C_GetOperationState", rv );
-      Log::end( "C_GetOperationState\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_SetOperationState restores the state of the cryptographic
-   * operation in a session.
-   *
-   * @param hSession session's handle
-   * @param pOperationState hold state
-   * @param ulOperationStateLen holds state length
-   * @param hEncryptionKey en/decryption key
-   * @param hAuthenticationKey sig/verify key
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_SetOperationState )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE )
-   {
-      Log::begin( "C_SetOperationState" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-      Log::logCK_RV( "C_SetOperationState", rv );
-      Log::end( "C_SetOperationState\n" );
-      return rv;
-   }
-
-   /**
-   * C_Login logs a user into a token.
-   *
-   * @param hSession the session's handle
-   * @param userType the user type
-   * @param pPin the user's PIN
-   * @param ulPinLen the length of the PIN
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Login )( CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Login" );
-         Log::in( "C_Login" );
-         Log::log( "C_Login - hSession <%#02x>", hSession );
-         Log::logCK_USER_TYPE( "C_Login", userType );
-         Log::logCK_UTF8CHAR_PTR( "C_Login - pPin", pPin, ulPinLen );
-         Log::log( "C_Login - ulPinLen <%ld>", ulPinLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::Login(hSession,userType,pPin,ulPinLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Login" );
-
-         Log::logCK_RV( "C_Login", rv );
-         Log::end( "C_Login\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_Logout logs a user out from a token.
-   *
-   * @param hSession the session's handle
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Logout )( CK_SESSION_HANDLE hSession )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Logout" );
-         Log::in( "C_Logout" );
-         Log::log( "C_Logout - hSession <%#02x>", hSession );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::Logout(hSession);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Logout" );
-
-         Log::logCK_RV( "C_Logout", rv );
-         Log::end( "C_Logout\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_CreateObject creates a new object.
-   *
-   * @param hSession  the session's handle
-   * @param pTemplate the object's template
-   * @param ulCount   attributes in template
-   * @param phObject  gets new object's handle.
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_CreateObject )( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_CreateObject" );
-         Log::in( "C_CreateObject" );
-         Log::log( "C_CreateObject - hSession <%#02x>", hSession );
-         Log::logCK_ATTRIBUTE_PTR( "C_CreateObject", pTemplate, ulCount );
-         Log::log( "C_CreateObject - phObject <%#02x>", phObject );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::CreateObject( hSession, pTemplate, ulCount, phObject );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_CreateObject" );
-
-         Log::logCK_RV( "C_CreateObject", rv );
-         Log::out( "C_CreateObject" );
-         Log::log( "C_CreateObject - phObject <%#02x> (%#02x)", phObject, ( ( NULL_PTR != phObject ) ? *phObject : 0 ) );
-         Log::end( "C_CreateObject\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_CopyObject copies an object, creating a new object for the
-   * copy. */
-   CK_DEFINE_FUNCTION(CK_RV,C_CopyObject )( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR )
-   {
-      Log::begin( "C_CopyObject" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_CopyObject", rv );
-      Log::end( "C_CopyObject\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DestroyObject destroys an object.
-   *
-   * @param hSession the session's handle
-   * @param hObject the object's handle
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DestroyObject )( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_DestroyObject" );
-         Log::in( "C_DestroyObject" );
-         Log::log( "C_DestroyObject - hSession <%#02x>", hSession );
-         Log::log( "C_DestroyObject - hObject <%#02x>", hObject );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::DestroyObject( hSession, hObject );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_DestroyObject" );
-
-         Log::logCK_RV( "C_DestroyObject", rv );
-         Log::end( "C_DestroyObject\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_GetObjectSize gets the size of an object in bytes. */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetObjectSize )( CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR )
-   {
-      Log::begin( "C_GetObjectSize" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_GetObjectSize", rv );
-      Log::end( "C_GetObjectSize\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_GetAttributeValue obtains the value of one or more object
-   * attributes.
-   *
-   * @param hSession    the session's handle
-   * @param hObject     the object's handle
-   * @param pTemplate   specifies attrs; gets vals
-   * @param ulCount     attributes in template
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetAttributeValue )( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GetAttributeValue" );
-         Log::in( "C_GetAttributeValue" );
-         Log::log( "C_GetAttributeValue - hSession <%#02x>", hSession );
-         Log::logCK_ATTRIBUTE_PTR( "C_GetAttributeValue", pTemplate, ulCount );
-         Log::log( "C_GetAttributeValue - hObject <%#02x>", hObject );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::GetAttributeValue(hSession,hObject,pTemplate,ulCount);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GetAttributeValue" );
-
-         Log::logCK_RV( "C_GetAttributeValue", rv );
-         Log::out( "C_GetAttributeValue" );
-         Log::logCK_ATTRIBUTE_PTR( "C_GetAttributeValue", pTemplate, ulCount );
-         Log::end( "C_GetAttributeValue\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_SetAttributeValue modifies the value of one or more object
-   * attributes
-   *
-   * @param   hSession    the session's handle
-   * @param   hObject     the object's handle
-   * @param   pTemplate   specifies attrs and values
-   * @param   ulCount     attributes in template
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_SetAttributeValue )( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_SetAttributeValue" );
-         Log::in( "C_SetAttributeValue" );
-         Log::log( "C_SetAttributeValue - hSession <%#02x>", hSession );
-         Log::logCK_ATTRIBUTE_PTR( "C_SetAttributeValue", pTemplate, ulCount );
-         Log::log( "C_SetAttributeValue - hObject <%#02x>", hObject );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::SetAttributeValue( hSession, hObject, pTemplate, ulCount );
-         }
-         PKCS11_CATCH( rv )
-         Log::stop( "C_SetAttributeValue" );
-
-         Log::logCK_RV( "C_SetAttributeValue", rv );
-         Log::end( "C_SetAttributeValue\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_FindObjectsInit initializes a search for token and session
-   * objects that match a template.
-   *
-   * @param hSession the session's handle
-   * @param pTemplate attribute values to match
-   * @param ulCount atrs in search template
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_FindObjectsInit )( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_FindObjectsInit" );
-         Log::in( "C_FindObjectsInit" );
-         Log::log( "C_FindObjectsInit - hSession <%#02x>", hSession );
-         Log::logCK_ATTRIBUTE_PTR( "C_FindObjectsInit", pTemplate, ulCount );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::FindObjectsInit(hSession,pTemplate,ulCount);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_FindObjectsInit" );
-
-         Log::logCK_RV( "C_FindObjectsInit", rv );
-         Log::end( "C_FindObjectsInit\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-      return rv;
-   }
-
-
-   /**
-   * C_FindObjects continues a search for token and session
-   * objects that match a template, obtaining additional object
-   * handles.
-   *
-   * @param hSession                session's handle
-   * @param phObject                gets obj. handles
-   * @param ulMaxObjectCount        max handles to get
-   * @param pulObjectCount          actual # returned
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_FindObjects )(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_FindObjects" );
-         Log::in( "C_FindObjects" );
-         Log::log( "C_FindObjects - hSession <%#02x>", hSession );
-         Log::log( "C_FindObjects - phObject <%#02x> (%#02x)", phObject, ( ( NULL_PTR != phObject ) ? *phObject : 0 ) );
-         Log::log( "C_FindObjects - ulMaxObjectCount <%#02x>", ulMaxObjectCount );
-         Log::log( "C_FindObjects - pulObjectCount <%#02x> (%#02x)", pulObjectCount, ( ( NULL_PTR != pulObjectCount ) ? *pulObjectCount : 0 ) );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::FindObjects( hSession, phObject, ulMaxObjectCount, pulObjectCount );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_FindObjects" );
-
-         Log::logCK_RV( "C_FindObjects", rv );
-         Log::out( "C_FindObjects" );
-         Log::log( "C_FindObjects - phObject <%#02x> (%#02x)", phObject, ( ( NULL_PTR != phObject ) ? *phObject : 0 ) );
-         Log::log( "C_FindObjects - pulObjectCount <%#02x> (%#02x)", pulObjectCount, ( ( NULL_PTR != pulObjectCount ) ? *pulObjectCount : 0 ) );
-         Log::end( "C_FindObjects\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_FindObjectsFinal finishes a search for token and session
-   * objects.
-   *
-   * @param hSession the session's handle
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_FindObjectsFinal )( CK_SESSION_HANDLE hSession )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_FindObjectsFinal" );
-         Log::in( "C_FindObjectsFinal" );
-         Log::log( "C_FindObjectsFinal - hSession <%#02x>", hSession );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::FindObjectsFinal(hSession);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_FindObjectsFinal" );
-
-         Log::logCK_RV( "C_FindObjectsFinal", rv );
-         Log::end( "C_FindObjectsFinal\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_EncryptInit initializes an encryption operation.
-   *
-   * @param hSession          the session's handle
-   * @param pMechanism        the encryption mechanism
-   * @param hKey              handle of encryption key
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_EncryptInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_EncryptInit" );
-         Log::in( "C_EncryptInit" );
-         Log::log( "C_EncryptInit - hSession <%#02x>", hSession );
-         Log::logCK_MECHANISM_PTR( "C_EncryptInit", pMechanism );
-         Log::log( "C_EncryptInit - hKey <%#02x>", hKey );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::EncryptInit(hSession,pMechanism,hKey);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_EncryptInit" );
-
-         Log::logCK_RV( "C_EncryptInit", rv );
-         Log::end( "C_EncryptInit\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_Encrypt encrypts single-part data.
-   *
-   * @param hSession               session's handle
-   * @param pData                  the plaintext data
-   * @param ulDataLen              bytes of plaintext
-   * @param pEncryptedData         gets ciphertext
-   * @param pulEncryptedData Len   gets c-text size
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Encrypt )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pEncryptedData, CK_ULONG_PTR pulEncryptedDataLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Encrypt" );
-         Log::in( "C_Encrypt" );
-         Log::log( "C_Encrypt - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_Encrypt - pData", pData, ulDataLen );
-         Log::logCK_UTF8CHAR_PTR( "C_Encrypt - pEncryptedData", pEncryptedData, (NULL_PTR == pulEncryptedDataLen) ? 0 : *pulEncryptedDataLen );
-
-         Log::start( );      
-         PKCS11_TRY
-         {
-            rv = Slot::Encrypt( hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Encrypt" );
-
-         Log::logCK_RV( "C_Encrypt", rv );
-         Log::out( "C_Encrypt" );
-         Log::logCK_UTF8CHAR_PTR( "C_Encrypt - pEncryptedData", pEncryptedData, (NULL_PTR == pulEncryptedDataLen) ? 0 : *pulEncryptedDataLen );
-         Log::end( "C_Encrypt\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_EncryptUpdate continues a multiple-part encryption
-   * operation.
-   *
-   * @param hSession                  session's handle
-   * @param pPart                     the plaintext data
-   * @param ulPartLen                 plaintext data len
-   * @param pEncryptedPart            gets ciphertext
-   * @param pulEncryptedPartLen       gets c-text size
-   *
-   */
-   CK_DEFINE_FUNCTION(CK_RV,C_EncryptUpdate)( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_EncryptUpdate" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_EncryptUpdate", rv );
-      Log::end( "C_EncryptUpdate\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_EncryptFinal finishes a multiple-part encryption
-   * operation.
-   *
-   * @param hSession                   session handle
-   * @param pLastEncryptedPart         last c-text
-   * @param pulLastEncryptedPartLen    gets last size
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_EncryptFinal )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_EncryptFinal" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_EncryptFinal", rv );
-      Log::end( "C_EncryptFinal\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DecryptInit initializes a decryption operation.
-   *
-   * @param hSession the session's handle
-   * @param pMechanism the decryption mechanism
-   * @param hKey handle of decrypting key
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DecryptInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_DecryptInit" );
-         Log::in( "C_DecryptInit" );
-         Log::log( "C_DecryptInit - hSession <%#02x>", hSession );
-         Log::logCK_MECHANISM_PTR( "C_DecryptInit", pMechanism );
-         Log::log( "C_DecryptInit - hKey <%#02x>", hKey );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::DecryptInit( hSession, pMechanism, hKey );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_DecryptInit" );
-
-         Log::logCK_RV( "C_DecryptInit", rv );
-         Log::end( "C_DecryptInit\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-
-   /**
-   * C_Decrypt decrypts encrypted data in a single part.
-   *
-   * @param hSession                   session's handle
-   * @param pEncryptedData             ciphertext
-   * @param ulEncryptedDataLen         ciphertext length
-   * @param pData                      gets plaintext
-   * @param pulDataLen                 gets p-text size
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Decrypt )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedData, CK_ULONG ulEncryptedDataLen, CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Decrypt" );
-         Log::in( "C_Decrypt" );
-         Log::log( "C_Decrypt - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_Decrypt - pEncryptedData", pEncryptedData, ulEncryptedDataLen );
-         Log::logCK_UTF8CHAR_PTR( "C_Decrypt - pData", pData, (NULL_PTR == pulDataLen) ? 0 : *pulDataLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::Decrypt(hSession,pEncryptedData,ulEncryptedDataLen,pData,pulDataLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Decrypt" );
-
-         Log::logCK_RV( "C_Decrypt", rv );
-         Log::out( "C_Decrypt" );
-         Log::logCK_UTF8CHAR_PTR( "C_Decrypt - pData", pData, (NULL_PTR == pulDataLen) ? 0 : *pulDataLen );
-         Log::end( "C_Decrypt\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_DecryptUpdate continues a multiple-part decryption
-   * operation.
-   *
-   * @param hSession           session's handle
-   * @param pEncryptedPart     encrypted data
-   * @param ulEncryptedPart    input length
-   * @param pPart              gets plaintext
-   * @param pulPartLen         p-text size
-   */
-   CK_DEFINE_FUNCTION(CK_RV,C_DecryptUpdate)( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_DecryptUpdate" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DecryptUpdate", rv );
-      Log::end( "C_DecryptUpdate\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DecryptFinal finishes a multiple-part decryption
-   * operation.
-   *
-   * @param hSession           the session's handle
-   * @param pLastPart          gets plaintext
-   * @param pulLastPartLen     p-text size
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DecryptFinal )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_DecryptFinal" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DecryptFinal", rv );
-      Log::end( "C_DecryptFinal\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DigestInit initializes a message-digesting operation.
-   *
-   * @param hSession the session's handle
-   * @param pMechanism the digesting mechanism
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DigestInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-          Log::begin( "C_DigestInit" );
-         Log::in( "C_DigestInit" );
-         Log::log( "C_DigestInit - hSession <%#02x>", hSession );
-         Log::logCK_MECHANISM_PTR( "C_DigestInit", pMechanism );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::DigestInit(hSession,pMechanism);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_DigestInit" );
-
-         Log::logCK_RV( "C_DigestInit", rv );
-         Log::end( "C_DigestInit\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_Digest digests data in a single part.
-   *
-   * @param hSession      the session's handle
-   * @param pData         data to be digested
-   * @param ulDataLen     bytes of data to digest
-   * @param pDigest       gets the message digest
-   * @param pulDigestLen  gets digest length
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Digest )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Digest" );
-         Log::in( "C_Digest" );
-         Log::log( "C_Digest - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_Digest - pData", pData, ulDataLen );
-         Log::logCK_UTF8CHAR_PTR( "C_Digest - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::Digest( hSession, pData, ulDataLen, pDigest, pulDigestLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Digest" );
-
-         Log::logCK_RV( "C_Digest", rv );
-         Log::out( "C_Digest" );
-         Log::logCK_UTF8CHAR_PTR( "C_Digest - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
-         Log::end( "C_Digest\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_DigestUpdate continues a multiple-part message-digesting
-   * operation.
-   *
-   * @param hSession       the session's handle
-   * @param pPart          data to be digested
-   * @param ulPartLen      bytes of data to be digested
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DigestUpdate )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_DigestUpdate" );
-         Log::in( "C_DigestUpdate" );
-         Log::log( "C_DigestUpdate - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_DigestUpdate - pPart", pPart, ulPartLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::DigestUpdate( hSession, pPart, ulPartLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_DigestUpdate" );
-
-         Log::logCK_RV( "C_DigestUpdate", rv );
-         Log::end( "C_DigestUpdate\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_DigestKey continues a multi-part message-digesting
-   * operation, by digesting the value of a secret key as part of
-   * the data already digested. */
-   CK_DEFINE_FUNCTION( CK_RV, C_DigestKey )( CK_SESSION_HANDLE, CK_OBJECT_HANDLE )
-   {
-      Log::begin( "C_DigestKey" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DigestKey", rv );
-      Log::end( "C_DigestKey\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DigestFinal finishes a multiple-part message-digesting
-   * operation.
-   *
-   * @param hSession       the session's handle
-   * @param pDigest        gets the message digest
-   * @param pulDigestLen   gets byte count of digest
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DigestFinal )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_ULONG_PTR pulDigestLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_DigestFinal" );
-         Log::in( "C_DigestFinal" );
-         Log::log( "C_DigestFinal - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_DigestFinal - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::DigestFinal( hSession, pDigest, pulDigestLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_DigestFinal" );
-
-         Log::logCK_RV( "C_DigestFinal", rv );
-         Log::out( "C_DigestFinal" );
-         Log::logCK_UTF8CHAR_PTR( "C_DigestFinal - pDigest", pDigest, (NULL_PTR == pulDigestLen) ? 0 : *pulDigestLen );
-         Log::end( "C_DigestFinal\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_SignInit initializes a signature (private key encryption)
-   * operation, where the signature is (will be) an appendix to
-   * the data, and plaintext cannot be recovered from the
-   * signature.
-   *
-   * @param hSession           the session's handle
-   * @param pMechanism         the signature mechanism
-   * @param hKey               handle of signature key
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_SignInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_SignInit" );
-         Log::in( "C_SignInit" );
-         Log::log( "C_SignInit - hSession <%#02x>", hSession );
-         Log::logCK_MECHANISM_PTR( "C_SignInit", pMechanism );
-         Log::log( "C_SignInit - hKey <%#02x>", hKey );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::SignInit(hSession,pMechanism,hKey);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_SignInit" );
-         
-         Log::logCK_RV( "C_SignInit", rv );
-         Log::end( "C_SignInit\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_Sign signs (encrypts with private key) data in a single
-   * part, where the signature is (will be) an appendix to the
-   * data, and plaintext cannot be recovered from the signature.
-   *
-   * @param hSession          the session's handle
-   * @param pData             the data to sign
-   * @param ulDataLen         count of bytes to sign
-   * @param pSignature        gets the signature
-   * @param pulSignatureLen   gets signature length
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Sign )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Sign" );
-         Log::in( "C_Sign" );
-         Log::log( "C_Sign - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_Sign - pData", pData, ulDataLen );
-         Log::logCK_UTF8CHAR_PTR( "C_Sign - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::Sign( hSession, pData, ulDataLen, pSignature, pulSignatureLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Sign" );
-         
-         Log::logCK_RV( "C_Sign", rv );
-         Log::out( "C_Sign" );
-         Log::logCK_UTF8CHAR_PTR( "C_Sign - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
-         Log::end( "C_Sign\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_SignUpdate continues a multiple-part signature operation,
-   * where the signature is (will be) an appendix to the data,
-   * and plaintext cannot be recovered from the signature.
-   *
-   * @param hSession       the session's handle
-   * @param pPart          the data to sign
-   * @param ulPartLen      count of bytes to sign
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_SignUpdate )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_SignUpdate" );
-         Log::in( "C_SignUpdate" );
-         Log::log( "C_SignUpdate - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_SignUpdate - pPart", pPart, ulPartLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::SignUpdate(hSession,pPart,ulPartLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_SignUpdate" );
-
-         Log::logCK_RV( "C_SignUpdate", rv );
-         Log::end( "C_SignUpdate\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_SignFinal finishes a multiple-part signature operation,
-   * returning the signature.
-   *
-   * @param hSession           the session's handle
-   * @param pSignature         gets the signature
-   * @param pulSignatureLen    gets signature length
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_SignFinal )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_SignFinal" );
-         Log::in( "C_SignFinal" );
-         Log::log( "C_SignFinal - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_SignFinal - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv =  Slot::SignFinal(hSession,pSignature,pulSignatureLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_SignFinal" );
-
-         Log::logCK_RV( "C_SignFinal", rv );
-         Log::out( "C_SignFinal" );
-         Log::logCK_UTF8CHAR_PTR( "C_SignFinal - pSignature", pSignature, (NULL_PTR == pulSignatureLen) ? 0 : *pulSignatureLen );
-         Log::end( "C_SignFinal\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_SignRecoverInit initializes a signature operation, where
-   * the data can be recovered from the signature. */
-   CK_DEFINE_FUNCTION( CK_RV, C_SignRecoverInit )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE )
-   {
-      Log::begin( "C_SignRecoverInit" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_SignRecoverInit", rv );
-      Log::end( "C_SignRecoverInit\n" );
-      return rv;
-   }
-
-
-   /* C_SignRecover signs data in a single operation, where the data can be recovered from the signature. */
-   CK_DEFINE_FUNCTION( CK_RV, C_SignRecover )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_SignRecover" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_SignRecover", rv );
-      Log::end( "C_SignRecover\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_VerifyInit initializes a verification operation, where the
-   * signature is an appendix to the data, and plaintext cannot
-   * cannot be recovered from the signature (e.g. DSA).
-   *
-   * @param hSession      the session's handle
-   * @param pMechanism    the verification mechanism
-   * @param hKey          verification key
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_VerifyInit )( CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_VerifyInit" );
-         Log::in( "C_VerifyInit" );
-         Log::log( "C_VerifyInit - hSession <%#02x>", hSession );
-         Log::logCK_MECHANISM_PTR( "C_VerifyInit", pMechanism );
-         Log::log( "C_VerifyInit - hKey <%#02x>", hKey );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::VerifyInit( hSession, pMechanism, hKey );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_VerifyInit" );
-
-         Log::logCK_RV( "C_VerifyInit", rv );
-         Log::end( "C_VerifyInit\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_Verify verifies a signature in a single-part operation,
-   * where the signature is an appendix to the data, and plaintext
-   * cannot be recovered from the signature.
-   *
-   * @param hSession           the session's handle
-   * @param pData              signed data
-   * @param ulDataLen          length of signed data
-   * @param pSignature         signature
-   * @param ulSignatureLen     signature length
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_Verify )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDataLen, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_Verify" );
-         Log::in( "C_Verify" );
-         Log::log( "C_Verify - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_Verify - pData", pData, ulDataLen );
-         Log::logCK_UTF8CHAR_PTR( "C_Verify - pSignature", pSignature, ulSignatureLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::Verify(hSession,pData,ulDataLen,pSignature,ulSignatureLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_Verify" );
-         
-         Log::logCK_RV( "C_Verify", rv );
-         Log::out( "C_Verify" );
-         Log::logCK_UTF8CHAR_PTR( "C_Verify - pSignature", pSignature, ulSignatureLen );
-         Log::end( "C_Verify\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_VerifyUpdate continues a multiple-part verification
-   * operation, where the signature is an appendix to the data,
-   * and plaintext cannot be recovered from the signature. */
-   CK_DEFINE_FUNCTION( CK_RV, C_VerifyUpdate )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_VerifyUpdate" );
-         Log::in( "C_VerifyUpdate" );
-         Log::log( "C_VerifyUpdate - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_VerifyUpdate - pPart", pPart, ulPartLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::VerifyUpdate(hSession,pPart,ulPartLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_VerifyUpdate" );
-
-         Log::logCK_RV( "C_VerifyUpdate", rv );
-         Log::end( "C_VerifyUpdate\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_VerifyFinal finishes a multiple-part verification
-   * operation, checking the signature. */
-   CK_DEFINE_FUNCTION( CK_RV, C_VerifyFinal )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG ulSignatureLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_VerifyFinal" );
-         Log::in( "C_VerifyFinal" );
-         Log::log( "C_VerifyFinal - hSession <%#02x>", hSession );
-         Log::logCK_UTF8CHAR_PTR( "C_VerifyFinal - pSignature", pSignature, ulSignatureLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::VerifyFinal(hSession,pSignature,ulSignatureLen);
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_VerifyFinal" );
-         
-         Log::logCK_RV( "C_VerifyFinal", rv );
-         Log::end( "C_VerifyFinal\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /* C_VerifyRecoverInit initializes a signature verification
-   * operation, where the data is recovered from the signature. */
-   CK_DEFINE_FUNCTION( CK_RV, C_VerifyRecoverInit )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE )
-   {
-      Log::begin( "C_VerifyRecoverInit" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_VerifyRecoverInit", rv );
-      Log::end( "C_VerifyRecoverInit\n" );
-      return rv;
-   }
-
-
-   /* C_VerifyRecover verifies a signature in a single-part
-   * operation, where the data is recovered from the signature. */
-   CK_DEFINE_FUNCTION( CK_RV, C_VerifyRecover )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_VerifyRecover" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_VerifyRecover", rv );
-      Log::end( "C_VerifyRecover\n" );
-      return rv;
-   }
-
-
-   /* C_DigestEncryptUpdate continues a multiple-part digesting and encryption operation. */
-   CK_DEFINE_FUNCTION( CK_RV, C_DigestEncryptUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_DigestEncryptUpdate" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DigestEncryptUpdate", rv );
-      Log::end( "C_DigestEncryptUpdate\n" );
-      return rv;
-   }
-
-
-   /* C_DecryptDigestUpdate continues a multiple-part decryption and digesting operation. */
-   CK_DEFINE_FUNCTION( CK_RV, C_DecryptDigestUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_DecryptDigestUpdate" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DecryptDigestUpdate", rv );
-      Log::end( "C_DecryptDigestUpdate\n" );
-      return rv;
-   }
-
-
-   /* C_SignEncryptUpdate continues a multiple-part signing and encryption operation. */
-   CK_DEFINE_FUNCTION( CK_RV, C_SignEncryptUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_SignEncryptUpdate" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_SignEncryptUpdate", rv );
-      Log::end( "C_SignEncryptUpdate\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DecryptVerifyUpdate continues a multiple-part decryption and verify operation. */
-   CK_DEFINE_FUNCTION( CK_RV, C_DecryptVerifyUpdate )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR , CK_ULONG_PTR )
-   {
-      Log::begin( "C_DecryptVerifyUpdate" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DecryptVerifyUpdate", rv );
-      Log::end( "C_DecryptVerifyUpdate\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_GenerateKey generates a secret key, creating a new key object.
-   *
-   * @param    hSession,    the session's handle
-   * @param    pMechanism   key generation mech.
-   * @param    pTemplate    template for new key
-   * @param    ulCount      # of attrs in template
-   * @param    phKey        gets handle of new key
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GenerateKey )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR )
-   {
-      Log::begin( "C_GenerateKey" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_GenerateKey", rv );
-      Log::end( "C_GenerateKey\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_GenerateKeyPair generates a public-key/private-key pair,
-   * creating new key objects.
-   *
-   * @param hSession,                    session handle
-   * @param pMechanism,                  key-gen mech.
-   * @param pPublicKeyTemplate,          template for pub. key
-   * @param ulPublicKeyAttributeCount,   # pub. attrs.
-   * @param pPrivateKeyTemplate,         template for priv. key
-   * @param ulPrivateKeyAttributeCount,  # priv. attrs.
-   * @param phPublicKey,                 gets pub. key handle
-   * @param phPrivateKey                 gets priv key handle
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GenerateKeyPair )(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pPublicKeyTemplate, CK_ULONG ulPublicKeyAttributeCount, CK_ATTRIBUTE_PTR pPrivateKeyTemplate, CK_ULONG ulPrivateKeyAttributeCount, CK_OBJECT_HANDLE_PTR phPublicKey, CK_OBJECT_HANDLE_PTR phPrivateKey )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GenerateKeyPair" );
-         Log::in( "C_GenerateKeyPair" );
-         Log::log( "C_GenerateKeyPair - hSession <%#02x>", hSession );
-         Log::logCK_MECHANISM_PTR( "C_GenerateKeyPair", pMechanism );
-         Log::logCK_ATTRIBUTE_PTR( "C_GenerateKeyPair", pPublicKeyTemplate, ulPublicKeyAttributeCount );
-         Log::logCK_ATTRIBUTE_PTR( "C_GenerateKeyPair", pPrivateKeyTemplate, ulPrivateKeyAttributeCount );
-         Log::log( "C_GenerateKeyPair - phPublicKey <%#02x>", (phPublicKey == NULL_PTR) ? 0 : *phPublicKey );
-         Log::log( "C_GenerateKeyPair - phPrivateKey <%#02x>", (phPrivateKey == NULL_PTR) ? 0 : *phPrivateKey );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::GenerateKeyPair( hSession, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GenerateKeyPair" );
-
-         Log::logCK_RV( "C_GenerateKeyPair", rv );
-         Log::out( "C_GenerateKeyPair" );
-         Log::log( "C_GenerateKeyPair - phPublicKey <%#02x>", (phPublicKey == NULL_PTR) ? 0 : *phPublicKey );
-         Log::log( "C_GenerateKeyPair - phPrivateKey <%#02x>", (phPrivateKey == NULL_PTR) ? 0 : *phPrivateKey );
-         Log::end( "C_GenerateKeyPair\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_WrapKey wraps (i.e., encrypts) a key.
-   *
-   * @param hSession              the session's handle
-   * @param pMechanism            the wrapping mechanism
-   * @param hWrappingKey          wrapping key
-   * @param hKey                  key to be wrapped
-   * @param pWrapperKey           gets wrapped key
-   * @param pulWrappedKeyLen      gets wrapped key size
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_WrapKey )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR )
-   {
-      Log::begin( "C_WrapKey" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_WrapKey", rv );
-      Log::end( "C_WrapKey\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
-   * key object.
-   *
-   * @param   hSession           session's handle
-   * @param   pMechanism         unwrapping mech.
-   * @param   hUnwrappingKey     unwrapping key
-   * @param   pWrappedKey        the wrapped key
-   * @param   ulWrappedKeyLen    wrapped key len
-   * @param   pTemplate          new key template
-   * @param   ulAttributeCount   template length
-   * @param   phKey              gets new handle
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV,C_UnwrapKey )(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR )
-   {
-      Log::begin( "C_UnwrapKey" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_UnwrapKey", rv );
-      Log::end( "C_UnwrapKey\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_DeriveKey derives a key from a base key, creating a new key
-   * object.
-   *
-   * @param hSession              session's handle
-   * @param pMechanism            key deriv. mech.
-   * @param hBaseKey              base key
-   * @param pTemplate             new key template
-   * @param ulAttributeCount      template length
-   * @param phKey                 gets new handle
-   *
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_DeriveKey )( CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR )
-   {
-      Log::begin( "C_DeriveKey" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_DeriveKey", rv );
-      Log::end( "C_DeriveKey\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_SeedRandom mixes additional seed material into the token's
-   * random number generator.
-   *
-   * @param hSession   the session's handle
-   * @param pSeed      the seed material
-   * @param ulSeedLen  length of seed material
-   */
-   CK_DEFINE_FUNCTION( CK_RV,C_SeedRandom )( CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG )
-   {
-      Log::begin( "C_SeedRandom" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_RANDOM_SEED_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_SeedRandom", rv );
-      Log::end( "C_SeedRandom\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_GenerateRandom generates random data.
-   *
-   * @param hSession       the session's handle
-   * @param RandomData     receives the random data
-   * @param ulRandomLen    # of bytes to generate
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GenerateRandom )( CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, CK_ULONG ulRandomLen )
-   {
-      CCriticalSectionLocker cslock( _critSectAPI );
-      
-      CK_RV rv = CKR_OK;
-      
-      try
-      {
-         Log::begin( "C_GenerateRandom" );
-         Log::in( "C_GenerateRandom" );
-         Log::logCK_UTF8CHAR_PTR( "C_GenerateRandom", pRandomData, ulRandomLen );
-
-         Log::start( );
-         PKCS11_TRY
-         {
-            rv = Slot::GenerateRandom( hSession, pRandomData, ulRandomLen );
-         }
-         PKCS11_CATCH(rv)
-         Log::stop( "C_GenerateRandom" );
-         
-         Log::logCK_RV( "C_GenerateRandom", rv );
-         Log::out( "C_GenerateRandom" );
-         Log::logCK_UTF8CHAR_PTR( "C_GenerateRandom", pRandomData, ulRandomLen );
-         Log::end( "C_GenerateRandom\n" );
-      }
-      catch( ... )
-      {
-         rv = CKR_GENERAL_ERROR;
-      }
-
-      return rv;
-   }
-
-
-   /**
-   * C_GetFunctionStatus is a legacy function; it obtains an
-   * updated status of a function running in parallel with an
-   * application.
-   *
-   * @param hSession the session's handle
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_GetFunctionStatus )( CK_SESSION_HANDLE )
-   {
-      Log::begin( "C_GetFunctionStatus" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_GetFunctionStatus", rv );
-      Log::end( "C_GetFunctionStatus\n" );
-      return rv;
-   }
-
-
-   /**
-   * C_CancelFunction is a legacy function; it cancels a function
-   * running in parallel.
-   *
-   * @param hSession the session's handle
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_CancelFunction )( CK_SESSION_HANDLE )
-   {
-      Log::begin( "C_CancelFunction" );
-
-      CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-      if( _isInitialized )
-      {
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-      }
-
-      Log::logCK_RV( "C_CancelFunction", rv );
-      Log::end( "C_CancelFunction\n" );
-      return rv;
-   }
-
-   /* Functions added in for Cryptoki Version 2.01 or later */
-
-   /**
-   * C_WaitForSlotEvent waits for a slot event (token insertion,
-   * removal, etc.) to occur.
-   *
-   * @param flags      blocking/nonblocking flag
-   * @param pSlot      location that receives the slot ID
-   * @param pReserved  reserved.  Should be NULL_PTR
-   */
-   CK_DEFINE_FUNCTION( CK_RV, C_WaitForSlotEvent )( CK_FLAGS flags, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR pReserved )
-   {
-      //Log::begin("C_WaitForSlotEvent");
-
-      // Not Initialized
-      if (!_isInitialized)
-      {
-         Log::error( "C_WaitForSlotEvent", "CKR_CRYPTOKI_NOT_INITIALIZED" );
-         return CKR_CRYPTOKI_NOT_INITIALIZED;
-      }
-
-      if((pReserved != NULL_PTR) || (pSlot == NULL_PTR))
-      {
-         Log::error( "C_WaitForSlotEvent", "CKR_ARGUMENTS_BAD" );
-         return CKR_ARGUMENTS_BAD;
-      }
-
-      *pSlot = CK_UNAVAILABLE_INFORMATION;// -1;
-
-#ifdef INCLUDE_EVENTING
-      CMutex mut("a");
-
-      CK_SLOT_ID sid = 0;
-      for(;sid<CONFIG_MAX_SLOT;sid++)
-      {
-         Slot* slot = Application::_slotCache[sid];
-         if(slot != NULL_PTR)
-         {
-            if(slot->GetEvent())
-            {
-               *pSlot = slot->GetSlotId();
-               slot->SetEvent(CK_FALSE);
-               break;
-            }
-         }
-      }
-
-      mut.release();
-
-      if(*pSlot == (CK_SLOT_ID)-1)
-      {
-
-         if(flags & CKF_DONT_BLOCK)
-         {
-            //Log::log("CKR_NO_EVENT");
-            return CKR_NO_EVENT;
-         }
-         else
-         {
-            CryptokiEvent.Wait();
-            //Log::log("CryptokiEvent signal received in WaitForSlotEvent..");
-
-            CMutex mut("b");
-
-            CK_SLOT_ID sid = 0;
-
-            for(;sid<CONFIG_MAX_SLOT;sid++)
-            {
-               Slot* slot = Application::_slotCache[sid];
-
-               if(slot != NULL_PTR)
-               {
-                  if(slot->GetEvent())
-                  {
-                     *pSlot = slot->GetSlotId();
-                     Log::log( "C_WaitForSlotEvent - SlotID <%#02x>\n", *pSlot );
-                     slot->SetEvent(CK_FALSE);
-                     break;
-                  }
-               }
-            }
-
-            mut.release();
-
-            if(*pSlot == (CK_SLOT_ID)-1)
-            {
-               //Log::log("CKR_NO_EVENT");
-               return CKR_NO_EVENT;
-            }
-         }
-      }
-
-      return CKR_OK;
-#else
-      return CKR_NO_EVENT;
-#endif
-   }
-
-} // extern "C"

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,5 +1,5 @@
 /* pkcs11.h include file for PKCS #11. */
-/* $Revision: 1.5 $ */
+/* $Revision: 1.1 $ */
 
 /* License to copy and use this software is granted provided that it is
  * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
@@ -7,10 +7,10 @@
 
  * License is also granted to make and use derivative works provided that
  * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
  * referencing the derived work.
 
- * RSA Security Inc. makes no representations concerning either the
+ * RSA Security Inc. makes no representations concerning either the 
  * merchantability of this software or the suitability of this software for
  * any particular purpose. It is provided "as is" without express or implied
  * warranty of any kind.
@@ -275,7 +275,7 @@
 
 #define CK_PKCS11_FUNCTION_INFO(name) \
   __PASTE(CK_,name) name;
-
+  
 struct CK_FUNCTION_LIST {
 
   CK_VERSION    version;  /* Cryptoki version */
@@ -297,4 +297,3 @@
 #endif
 
 #endif
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,5 +1,5 @@
 /* pkcs11f.h include file for PKCS #11. */
-/* $Revision: 1.5 $ */
+/* $Revision: 1.2 $ */
 
 /* License to copy and use this software is granted provided that it is
  * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
@@ -7,10 +7,10 @@
 
  * License is also granted to make and use derivative works provided that
  * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
+ * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
  * referencing the derived work.
 
- * RSA Security Inc. makes no representations concerning either the
+ * RSA Security Inc. makes no representations concerning either the 
  * merchantability of this software or the suitability of this software for
  * any particular purpose. It is provided "as is" without express or implied
  * warranty of any kind.
@@ -53,6 +53,7 @@
 );
 #endif
 
+
 /* C_GetFunctionList returns the function list. */
 CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
 #ifdef CK_NEED_ARG_LIST
@@ -62,6 +63,8 @@
 );
 #endif
 
+
+
 /* Slot and token management */
 
 /* C_GetSlotList obtains a list of slots in the system. */
@@ -74,6 +77,7 @@
 );
 #endif
 
+
 /* C_GetSlotInfo obtains information about a particular slot in
  * the system. */
 CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
@@ -85,7 +89,6 @@
 #endif
 
 
-
 /* C_GetTokenInfo obtains information about a particular token
  * in the system. */
 CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
@@ -96,6 +99,7 @@
 );
 #endif
 
+
 /* C_GetMechanismList obtains a list of mechanism types
  * supported by a token. */
 CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
@@ -107,6 +111,7 @@
 );
 #endif
 
+
 /* C_GetMechanismInfo obtains information about a particular
  * mechanism possibly supported by a token. */
 CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
@@ -248,6 +253,8 @@
 );
 #endif
 
+
+
 /* Object management */
 
 /* C_CreateObject creates a new object. */
@@ -359,6 +366,7 @@
 #endif
 
 
+
 /* Encryption and decryption */
 
 /* C_EncryptInit initializes an encryption operation. */
@@ -556,7 +564,7 @@
 
 
 /* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data,
+ * where the signature is (will be) an appendix to the data, 
  * and plaintext cannot be recovered from the signature. */
 CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
 #ifdef CK_NEED_ARG_LIST
@@ -568,7 +576,7 @@
 #endif
 
 
-/* C_SignFinal finishes a multiple-part signature operation,
+/* C_SignFinal finishes a multiple-part signature operation, 
  * returning the signature. */
 CK_PKCS11_FUNCTION_INFO(C_SignFinal)
 #ifdef CK_NEED_ARG_LIST
@@ -617,12 +625,12 @@
 (
   CK_SESSION_HANDLE hSession,    /* the session's handle */
   CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */
+  CK_OBJECT_HANDLE  hKey         /* verification key */ 
 );
 #endif
 
 
-/* C_Verify verifies a signature in a single-part operation,
+/* C_Verify verifies a signature in a single-part operation, 
  * where the signature is an appendix to the data, and plaintext
  * cannot be recovered from the signature. */
 CK_PKCS11_FUNCTION_INFO(C_Verify)
@@ -638,7 +646,7 @@
 
 
 /* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data,
+ * operation, where the signature is an appendix to the data, 
  * and plaintext cannot be recovered from the signature. */
 CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
 #ifdef CK_NEED_ARG_LIST
@@ -764,7 +772,7 @@
 #endif
 
 
-/* C_GenerateKeyPair generates a public-key/private-key pair,
+/* C_GenerateKeyPair generates a public-key/private-key pair, 
  * creating new key objects. */
 CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
 #ifdef CK_NEED_ARG_LIST
@@ -888,6 +896,8 @@
 );
 #endif
 
+
+
 /* Functions added in for Cryptoki Version 2.01 or later */
 
 /* C_WaitForSlotEvent waits for a slot event (token insertion,
@@ -901,3 +911,28 @@
 );
 #endif
 
+
+
+    /* C_GetCardProperty obtains a property value from the .NET MiniDriver */
+    CK_PKCS11_FUNCTION_INFO(C_GetCardProperty)
+    #ifdef CK_NEED_ARG_LIST
+    (
+        CK_SLOT_ID ulSlotID, 
+        CK_BYTE a_ucProperty, 
+        CK_BYTE a_ucFlags, 
+        CK_BYTE_PTR a_pValue, 
+        CK_ULONG_PTR a_pValueLen
+    );
+    #endif
+
+    /* C_SetCardProperty pushes a property value to the .NET MiniDriver */
+    CK_PKCS11_FUNCTION_INFO(C_SetCardProperty)
+    #ifdef CK_NEED_ARG_LIST
+    (
+        CK_SLOT_ID ulSlotID, 
+        CK_BYTE a_ucProperty, 
+        CK_BYTE a_ucFlags, 
+        CK_BYTE_PTR a_pValue, 
+        CK_ULONG a_pValueLen
+    );
+    #endif

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,5 +1,5 @@
 /* pkcs11t.h include file for PKCS #11. */
-/* $Revision: 1.5 $ */
+/* $Revision: 1.1 $ */
 
 /* License to copy and use this software is granted provided that it is
  * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
@@ -36,8 +36,6 @@
 #endif
 #endif
 
-typedef unsigned short CK_USHORT;
-
 /* an unsigned 8-bit value */
 typedef unsigned char     CK_BYTE;
 
@@ -281,13 +279,6 @@
 /* Context specific (added in v2.20) */
 #define CKU_CONTEXT_SPECIFIC   2
 
-/* Not defined in PKCS#11, Add by KS */
-#define CKU_NONE 99
-#define CO_OBJECT_HANDLE_MASK  0x0000FFFF
-#define CO_SESSION_OBJECT      0x00000000
-#define CO_TOKEN_OBJECT        0x10000000
-
-
 /* CK_STATE enumerates the session states */
 /* CK_STATE has been changed from an enum to a CK_ULONG for
  * v2.0 */
@@ -558,9 +549,6 @@
 
 #define CKA_VENDOR_DEFINED     0x80000000
 
-// Gemalto CKA
-#define CKA_GEMALTO_CTRINDEX   0x80000001
-#define CKA_GEMALTO_KEYSPEC    0x80000002
 
 /* CK_ATTRIBUTE is a structure that includes the type, length
  * and value of an attribute */
@@ -931,9 +919,6 @@
  *      Bit Flag               Mask        Meaning */
 #define CKF_HW                 0x00000001  /* performed by HW */
 
-// Added by KS
-#define CKF_SW                 0x00000000 /* performed by SW */
-
 /* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
  * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
  * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
@@ -1155,7 +1140,7 @@
 /* CK_C_INITIALIZE_ARGS provides the optional arguments to
  * C_Initialize */
 typedef struct CK_C_INITIALIZE_ARGS {
-  CK_CREATEMUTEX CreateMutex;
+  CK_CREATEMUTEX _CreateMutex;
   CK_DESTROYMUTEX DestroyMutex;
   CK_LOCKMUTEX LockMutex;
   CK_UNLOCKMUTEX UnlockMutex;
@@ -1698,4 +1683,3 @@
 typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
 
 #endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,97 +0,0 @@
-/* cryptoki.h include file for PKCS #11. */
-/* $Revision: 1.5 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This is a sample file containing the top level include directives
- * for building Win32 Cryptoki libraries and applications.
- */
-
-#ifndef _include_platconfig_h
-#define _include_platconfig_h
-
-#ifndef NULL_PTR
-    #define NULL_PTR 0
-#endif
-
-#ifdef _WIN32
-
-#pragma pack(push, plcryptoki, 1)
-
-/* Specifies that the function is a DLL entry point. */
-#define CK_IMPORT_SPEC __declspec(dllimport)
-
-#ifdef CRYPTOKI_EXPORTS
-#define CK_EXPORT_SPEC __declspec(dllexport)
-#else
-#define CK_EXPORT_SPEC CK_IMPORT_SPEC
-#endif
-
-/* Ensures the calling convention for Win32 builds */
-#define CK_CALL_SPEC __cdecl
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) \
-  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION(returnType, name) \
-  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-  returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
-
-#define CK_CALLBACK_FUNCTION(returnType, name) \
-  returnType (CK_CALL_SPEC CK_PTR name)
-
-#ifdef _DEBUG
-    #define PKCS11_ASSERT(X)        assert(X)
-#else
-    #define PKCS11_ASSERT(X)
-#endif
-
-#include "pkcs11.h"
-
-#pragma pack(pop, plcryptoki)
-
-#else
-
-#define CK_IMPORT_SPEC
-#define CK_EXPORT_SPEC
-#define CK_CALL_SPEC
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) \
-  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION(returnType, name) \
-  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-  returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
-
-#define CK_CALLBACK_FUNCTION(returnType, name) \
-  returnType (CK_CALL_SPEC CK_PTR name)
-
-#define PKCS11_ASSERT(X)
-
-#include "pkcs11.h"
-
-#endif
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,372 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "privatekeyobject.h"
-
-PrivateKeyObject :: PrivateKeyObject() : KeyObject()
-{
-    this->_class                = CKO_PRIVATE_KEY;
-
-    this->_subject              = NULL_PTR;
-    this->_sensitive            = CK_TRUE;
-    this->_decrypt              = CK_TRUE;
-    this->_sign                 = CK_TRUE;
-    this->_signRecover          = CK_TRUE;
-    this->_unwrap               = CK_FALSE;
-    this->_extractable          = CK_FALSE;
-    this->_alwaysSensitive      = CK_TRUE;
-    this->_neverExtractable     = CK_TRUE;
-    this->_wrapWithTrusted      = CK_FALSE;
-    this->_alwaysAuthenticate   = CK_FALSE;
-
-    this->_ctrIndex = 0xFF; //-1;
-    this->_keyType  = CK_UNAVAILABLE_INFORMATION; //-1;
-}
-
-PrivateKeyObject :: ~PrivateKeyObject(){
-
-    if(this->_subject != NULL_PTR){
-        delete this->_subject;
-    }
-}
-
-bool PrivateKeyObject::IsEqual(const StorageObject * that) const
-{
-    if(_uniqueId != 0 && that->_uniqueId != 0)
-        return (_uniqueId == that->_uniqueId);
-
-    // Only objects that have been stored under p11 directory
-    // will have a non-zero _uniqueId. For other objects, do
-    // a deep comparison based on other attributes.
-    if(_class != that->_class)
-        return false;
-
-    const PrivateKeyObject * thatCert = static_cast<const PrivateKeyObject*>(that);
-    return ( (_ctrIndex == thatCert->_ctrIndex) &&
-             (_keySpec == thatCert->_keySpec) &&
-             (_checkValue == thatCert->_checkValue));
-}
-
-CK_BBOOL PrivateKeyObject::Compare(CK_ATTRIBUTE attribute)
-{
-    switch(attribute.type){
-
-        case CKA_SENSITIVE:
-            return (this->_sensitive == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_DECRYPT:
-            return (this->_decrypt == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_SIGN:
-            return (this->_sign == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_SIGN_RECOVER:
-            return (this->_signRecover == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_UNWRAP:
-            return (this->_unwrap == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_EXTRACTABLE:
-            return (this->_extractable == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_ALWAYS_SENSITIVE:
-            return (this->_alwaysSensitive == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_NEVER_EXTRACTABLE:
-            return (this->_neverExtractable == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_WRAP_WITH_TRUSTED:
-            return (this->_wrapWithTrusted == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_ALWAYS_AUTHENTICATE:
-            return (this->_alwaysAuthenticate == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_SUBJECT:
-            return Util::CompareU1Arrays(this->_subject,attribute.pValue,attribute.ulValueLen);
-
-        default:
-            return KeyObject::Compare(attribute);
-
-    }
-}
-
-CK_RV PrivateKeyObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-    switch(attribute->type){
-
-        case CKA_SENSITIVE:
-            return StorageObject::PutBBoolInAttribute(this->_sensitive,attribute);
-
-        case CKA_DECRYPT:
-            return StorageObject::PutBBoolInAttribute(this->_decrypt,attribute);
-
-        case CKA_SIGN:
-            return StorageObject::PutBBoolInAttribute(this->_sign,attribute);
-
-        case CKA_SIGN_RECOVER:
-            return StorageObject::PutBBoolInAttribute(this->_signRecover,attribute);
-
-        case CKA_UNWRAP:
-            return StorageObject::PutBBoolInAttribute(this->_unwrap,attribute);
-
-        case CKA_EXTRACTABLE:
-            return StorageObject::PutBBoolInAttribute(this->_extractable,attribute);
-
-        case CKA_ALWAYS_SENSITIVE:
-            return StorageObject::PutBBoolInAttribute(this->_alwaysSensitive,attribute);
-
-        case CKA_NEVER_EXTRACTABLE:
-            return StorageObject::PutBBoolInAttribute(this->_neverExtractable,attribute);
-
-        case CKA_WRAP_WITH_TRUSTED:
-            return StorageObject::PutBBoolInAttribute(this->_wrapWithTrusted,attribute);
-
-        case CKA_ALWAYS_AUTHENTICATE:
-            return StorageObject::PutBBoolInAttribute(this->_alwaysAuthenticate,attribute);
-
-        case CKA_SUBJECT:
-            return StorageObject::PutU1ArrayInAttribute(this->_subject,attribute);
-
-        default:
-            return KeyObject::GetAttribute(attribute);
-    }
-}
-
-CK_RV PrivateKeyObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-    CK_RV rv = CKR_OK;
-
-    if(objCreation == CK_FALSE)
-    {
-        switch(attribute.type)
-        {
-            case CKA_ALWAYS_AUTHENTICATE:
-            case CKA_ALWAYS_SENSITIVE:
-            case CKA_NEVER_EXTRACTABLE:
-                return CKR_ATTRIBUTE_READ_ONLY;
-
-            case CKA_DECRYPT:
-            case CKA_EXTRACTABLE:
-            case CKA_SENSITIVE:
-            case CKA_SIGN:
-            case CKA_SIGN_RECOVER:
-            case CKA_UNWRAP:
-            case CKA_WRAP_WITH_TRUSTED:
-                if(*(CK_BBOOL*)attribute.pValue == CK_TRUE){
-                    return CKR_ATTRIBUTE_READ_ONLY;
-                }
-                break;
-        }
-    }
-
-    switch(attribute.type){
-
-        case CKA_SENSITIVE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){
-
-                    if((objCreation == CK_FALSE) && (this->_sensitive == CK_TRUE) && (btemp == CK_FALSE)){
-                        rv = CKR_ATTRIBUTE_READ_ONLY;
-                    }else{
-                        this->_sensitive = btemp;
-
-                        if(btemp == CK_FALSE){
-                            this->_alwaysSensitive = CK_FALSE;
-                        }
-                    }
-                }
-            }
-            break;
-
-        case CKA_DECRYPT:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_decrypt = btemp; }
-            }
-            break;
-
-        case CKA_SIGN:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_sign = btemp; }
-            }
-            break;
-
-        case CKA_SIGN_RECOVER:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_signRecover = btemp; }
-            }
-            break;
-
-        case CKA_UNWRAP:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_unwrap = btemp; }
-            }
-            break;
-
-        case CKA_EXTRACTABLE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){
-
-                    if((objCreation == CK_FALSE) && (this->_extractable == CK_FALSE) && (btemp == CK_TRUE)){
-                        rv = CKR_ATTRIBUTE_READ_ONLY;
-                    }else{
-                        this->_extractable = btemp;
-
-                        if(btemp == CK_TRUE){
-                            this->_neverExtractable = CK_FALSE;
-                        }
-                    }
-                }
-            }
-            break;
-
-        case CKA_ALWAYS_SENSITIVE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_alwaysSensitive = btemp; }
-            }
-            break;
-
-
-        case CKA_NEVER_EXTRACTABLE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_neverExtractable = btemp; }
-            }
-            break;
-
-        case CKA_WRAP_WITH_TRUSTED:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_wrapWithTrusted = btemp; }
-            }
-            break;
-
-        case CKA_ALWAYS_AUTHENTICATE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_alwaysAuthenticate = btemp; }
-            }
-            break;
-
-        case CKA_SUBJECT:
-            if(this->_subject != NULL_PTR){
-                delete this->_subject;
-            }
-            this->_subject = StorageObject::ReadU1ArrayFromAttribute(attribute);
-
-            break;
-
-        default:
-            return KeyObject::SetAttribute(attribute,objCreation);
-    }
-
-    return rv;
-}
-
-void PrivateKeyObject::Serialize(std::vector<u1> *to)
-{
-    KeyObject::Serialize(to);
-
-    Util::PushBBoolInVector(to,this->_sensitive);
-
-    Util::PushBBoolInVector(to,this->_decrypt);
-
-    Util::PushBBoolInVector(to,this->_sign);
-
-    Util::PushBBoolInVector(to,this->_signRecover);
-
-    Util::PushBBoolInVector(to,this->_unwrap);
-
-    Util::PushBBoolInVector(to,this->_extractable);
-
-    Util::PushBBoolInVector(to,this->_alwaysSensitive);
-
-    Util::PushBBoolInVector(to,this->_neverExtractable);
-
-    Util::PushBBoolInVector(to,this->_wrapWithTrusted);
-
-    Util::PushBBoolInVector(to,this->_alwaysAuthenticate);
-
-    Util::PushByteArrayInVector(to,this->_subject);
-
-    // serialize the extra fields
-
-    PKCS11_ASSERT(_checkValue != 0);
-    PKCS11_ASSERT(_ctrIndex < 100);
-    PKCS11_ASSERT(_keySpec == 1 || _keySpec == 2 );
-
-    Util::PushULongLongInVector(to,this->_checkValue);
-
-    Util::PushBBoolInVector(to,this->_ctrIndex);
-
-    Util::PushBBoolInVector(to,this->_keySpec);
-}
-
-void PrivateKeyObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-    KeyObject::Deserialize(from,idx);
-
-    this->_sensitive = Util::ReadBBoolFromVector(from,idx);
-
-    this->_decrypt = Util::ReadBBoolFromVector(from,idx);
-
-    this->_sign = Util::ReadBBoolFromVector(from,idx);
-
-    this->_signRecover = Util::ReadBBoolFromVector(from,idx);
-
-    this->_unwrap = Util::ReadBBoolFromVector(from,idx);
-
-    this->_extractable = Util::ReadBBoolFromVector(from,idx);
-
-    this->_alwaysSensitive = Util::ReadBBoolFromVector(from,idx);
-
-    this->_neverExtractable = Util::ReadBBoolFromVector(from,idx);
-
-    this->_wrapWithTrusted = Util::ReadBBoolFromVector(from,idx);
-
-    this->_alwaysAuthenticate = Util::ReadBBoolFromVector(from,idx);
-
-    this->_subject = Util::ReadByteArrayFromVector(from,idx);
-
-    // deserialize extra fields
-
-    this->_checkValue = Util::ReadULongLongFromVector(from,idx);
-
-    this->_ctrIndex = Util::ReadBBoolFromVector(from,idx);
-
-    this->_keySpec = Util::ReadBBoolFromVector(from,idx);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,63 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_privatekeyobject_h
-#define _include_privatekeyobject_h
-
-#include "keyobject.h"
-
-class PrivateKeyObject : public KeyObject
-{
-
-public:
-    u1Array*     _subject;
-    CK_BBOOL     _sensitive;
-    CK_BBOOL     _decrypt;
-    CK_BBOOL     _sign;
-    CK_BBOOL     _signRecover;
-    CK_BBOOL     _unwrap;
-    CK_BBOOL     _extractable;
-    CK_BBOOL     _alwaysSensitive;
-    CK_BBOOL     _neverExtractable;
-    CK_BBOOL     _wrapWithTrusted;
-    CK_BBOOL     _alwaysAuthenticate;
-
-    // extra fields which are not part of PKCS#11
-    // but are needed as extra information in card
-    u8          _checkValue;
-    CK_BYTE     _ctrIndex;
-    CK_BYTE     _keySpec;
-
-public:
-    PrivateKeyObject();
-    virtual ~PrivateKeyObject();
-
-    virtual bool IsEqual(const StorageObject * that) const;
-    virtual CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    virtual CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    virtual CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    virtual void Serialize(vector<u1>* to);
-    virtual void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,205 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "publickeyobject.h"
-
-PublicKeyObject :: PublicKeyObject() : KeyObject()
-{
-   this->_class         = CKO_PUBLIC_KEY;
-
-   this->_encrypt       = CK_TRUE;
-   this->_verify        = CK_TRUE;
-   this->_verifyRecover = CK_TRUE;
-   this->_wrap          = CK_FALSE;
-
-   this->_subject       = NULL_PTR;
-
-   this->_ctrIndex = 0xFF; //-1;
-   this->_keyType  = CK_UNAVAILABLE_INFORMATION; //-1;
-}
-
-PublicKeyObject :: ~PublicKeyObject(){
-
-   if(this->_subject != NULL_PTR){
-      delete this->_subject;
-   }
-}
-
-CK_BBOOL PublicKeyObject::Compare(CK_ATTRIBUTE attribute)
-{
-   switch(attribute.type){
-
-        case CKA_ENCRYPT:
-           return (this->_encrypt == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_VERIFY:
-           return (this->_verify == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_VERIFY_RECOVER:
-           return (this->_verifyRecover == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_WRAP:
-           return (this->_wrap == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_SUBJECT:
-           return Util::CompareU1Arrays(this->_subject,attribute.pValue,attribute.ulValueLen);
-
-        default:
-           return KeyObject::Compare(attribute);
-   }
-}
-
-CK_RV PublicKeyObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-   switch(attribute->type){
-
-        case CKA_ENCRYPT:
-           return StorageObject::PutBBoolInAttribute(this->_encrypt,attribute);
-
-        case CKA_VERIFY:
-           return StorageObject::PutBBoolInAttribute(this->_verify,attribute);
-
-        case CKA_VERIFY_RECOVER:
-           return StorageObject::PutBBoolInAttribute(this->_verifyRecover,attribute);
-
-        case CKA_WRAP:
-           return StorageObject::PutBBoolInAttribute(this->_wrap,attribute);
-
-        case CKA_SUBJECT:
-           return StorageObject::PutU1ArrayInAttribute(this->_subject,attribute);
-
-        default:
-           return KeyObject::GetAttribute(attribute);
-
-   }
-}
-
-CK_RV PublicKeyObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-   CK_RV rv = CKR_OK;
-
-   if(objCreation == CK_FALSE){
-      switch(attribute.type){
-            case CKA_ENCRYPT:
-            case CKA_TRUSTED:
-            case CKA_VERIFY:
-            case CKA_VERIFY_RECOVER:
-            case CKA_WRAP:
-               if(*(CK_BBOOL*)attribute.pValue == CK_TRUE){
-                  return CKR_ATTRIBUTE_READ_ONLY;
-               }
-               break;
-      }
-   }
-
-   switch(attribute.type){
-
-        case CKA_ENCRYPT:
-           {
-              CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_encrypt = btemp; }
-           }
-           break;
-
-        case CKA_VERIFY:
-           {
-              CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_verify = btemp; }
-           }
-           break;
-
-        case CKA_VERIFY_RECOVER:
-           {
-              CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_verifyRecover = btemp; }
-           }
-           break;
-
-        case CKA_WRAP:
-           {
-              CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_wrap = btemp; }
-           }
-           break;
-
-        case CKA_SUBJECT:
-           if(this->_subject != NULL_PTR){
-              delete this->_subject;
-           }
-           this->_subject = StorageObject::ReadU1ArrayFromAttribute(attribute);
-           break;
-
-        default:
-           return KeyObject::SetAttribute(attribute,objCreation);
-   }
-
-   return rv;
-}
-
-void PublicKeyObject::Serialize(std::vector<u1> *to)
-{
-   KeyObject::Serialize(to);
-
-   Util::PushBBoolInVector(to,this->_encrypt);
-
-   Util::PushBBoolInVector(to,this->_verify);
-
-   Util::PushBBoolInVector(to,this->_verifyRecover);
-
-   Util::PushBBoolInVector(to,this->_wrap);
-
-   Util::PushByteArrayInVector(to,this->_subject);
-
-   // serialize the extra fields
-   Util::PushBBoolInVector(to,this->_ctrIndex);
-
-   Util::PushBBoolInVector(to,this->_keySpec);
-}
-
-void PublicKeyObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-   KeyObject::Deserialize(from,idx);
-
-   this->_encrypt = Util::ReadBBoolFromVector(from,idx);
-
-   this->_verify = Util::ReadBBoolFromVector(from,idx);
-
-   this->_verifyRecover = Util::ReadBBoolFromVector(from,idx);
-
-   this->_wrap = Util::ReadBBoolFromVector(from,idx);
-
-   this->_subject = Util::ReadByteArrayFromVector(from,idx);
-
-   // deserialize extra fields
-   this->_ctrIndex = Util::ReadBBoolFromVector(from,idx);
-
-   this->_keySpec = Util::ReadBBoolFromVector(from,idx);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,56 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_publickeyobject_h
-#define _include_publickeyobject_h
-
-#include "keyobject.h"
-
-class PublicKeyObject : public KeyObject
-{
-
-public:
-    u1Array*     _subject;
-    CK_BBOOL     _encrypt;
-    CK_BBOOL     _verify;
-    CK_BBOOL     _verifyRecover;
-    CK_BBOOL     _wrap;
-    CK_BBOOL     _trusted;
-
-    // extra fields which are not part of PKCS#11
-    // but are needed as extra information in card
-    CK_BYTE     _ctrIndex;
-    CK_BYTE     _keySpec;
-
-public:
-    PublicKeyObject();
-    virtual ~PublicKeyObject();
-
-    virtual CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    virtual CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    virtual CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    virtual void Serialize(vector<u1>* to);
-    virtual void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,15 +0,0 @@
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by PKCS11Module.rc
-//
-
-// Next default values for new objects
-//
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        101
-#define _APS_NEXT_COMMAND_VALUE         40001
-#define _APS_NEXT_CONTROL_VALUE         1001
-#define _APS_NEXT_SYMED_VALUE           101
-#endif
-#endif

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,282 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "rsaprivatekeyobject.h"
-
-RSAPrivateKeyObject :: RSAPrivateKeyObject() : PrivateKeyObject()
-{
-    this->_modulus        = NULL_PTR;
-    this->_publicExponent = NULL_PTR;
-    this->_d              = NULL_PTR;
-    this->_p              = NULL_PTR;
-    this->_q              = NULL_PTR;
-    this->_dp             = NULL_PTR;
-    this->_dq             = NULL_PTR;
-    this->_inverseQ       = NULL_PTR;
-
-    this->_keyType        = CKK_RSA;
-
-}
-
-RSAPrivateKeyObject :: ~RSAPrivateKeyObject()
-{
-    if(this->_modulus != NULL_PTR){
-        delete this->_modulus;
-    }
-
-    if(this->_publicExponent != NULL_PTR){
-        delete this->_publicExponent;
-    }
-
-    if(this->_d != NULL_PTR){
-        delete this->_d;
-    }
-
-    if(this->_p != NULL_PTR){
-        delete this->_p;
-    }
-
-    if(this->_q != NULL_PTR){
-        delete this->_q;
-    }
-
-    if(this->_dp != NULL_PTR){
-        delete this->_dp;
-    }
-
-    if(this->_dq != NULL_PTR){
-        delete this->_dq;
-    }
-
-    if(this->_inverseQ != NULL_PTR){
-        delete this->_inverseQ;
-    }
-}
-
-CK_BBOOL RSAPrivateKeyObject ::Compare(CK_ATTRIBUTE attribute)
-{
-    switch(attribute.type){
-
-        case CKA_MODULUS:
-            return Util::CompareU1Arrays(this->_modulus,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_PUBLIC_EXPONENT:
-            return Util::CompareU1Arrays(this->_publicExponent,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_PRIVATE_EXPONENT:
-            return Util::CompareU1Arrays(this->_d,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_PRIME_1:
-            return Util::CompareU1Arrays(this->_p,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_PRIME_2:
-            return Util::CompareU1Arrays(this->_q,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_EXPONENT_1:
-            return Util::CompareU1Arrays(this->_dp,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_EXPONENT_2:
-            return Util::CompareU1Arrays(this->_dq,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_COEFFICIENT:
-            return Util::CompareU1Arrays(this->_inverseQ,attribute.pValue,attribute.ulValueLen);
-
-        default:
-            return PrivateKeyObject::Compare(attribute);
-    }
-}
-
-CK_RV RSAPrivateKeyObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-    if(objCreation == CK_FALSE){
-        switch(attribute.type){
-            case CKA_PUBLIC_EXPONENT:
-            case CKA_MODULUS:
-            case CKA_PRIVATE_EXPONENT:
-            case CKA_PRIME_1:
-            case CKA_PRIME_2:
-            case CKA_EXPONENT_1:
-            case CKA_EXPONENT_2:
-            case CKA_COEFFICIENT:
-                return CKR_ATTRIBUTE_READ_ONLY;
-        }
-    }
-
-    switch(attribute.type){
-
-         case CKA_MODULUS:
-            if(this->_modulus != NULL_PTR){
-                delete this->_modulus;
-            }
-            this->_modulus = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-         case CKA_PUBLIC_EXPONENT:
-            if(this->_publicExponent != NULL_PTR){
-                delete this->_publicExponent;
-            }
-            this->_publicExponent = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-         case CKA_PRIVATE_EXPONENT:
-            if(this->_d != NULL_PTR){
-                delete this->_d;
-            }
-            this->_d = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-         case CKA_EXPONENT_1:
-            if(this->_dp != NULL_PTR){
-                delete this->_dp;
-            }
-            this->_dp = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-
-         case CKA_EXPONENT_2:
-            if(this->_dq != NULL_PTR){
-                delete this->_dq;
-            }
-            this->_dq = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-
-         case CKA_PRIME_1:
-            if(this->_p != NULL_PTR){
-                delete this->_p;
-            }
-            this->_p = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-
-         case CKA_PRIME_2:
-            if(this->_q != NULL_PTR){
-                delete this->_q;
-            }
-            this->_q = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-
-         case CKA_COEFFICIENT:
-            if( this->_inverseQ != NULL_PTR )
-            {
-                delete this->_inverseQ;
-            }
-            this->_inverseQ = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-         default:
-             return PrivateKeyObject::SetAttribute(attribute,objCreation);
-
-    }
-
-    return CKR_OK;
-}
-
-CK_RV RSAPrivateKeyObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-    switch(attribute->type){
-
-        case CKA_MODULUS:
-            return StorageObject::PutU1ArrayInAttribute(this->_modulus,attribute);
-
-        case CKA_PUBLIC_EXPONENT:
-            return StorageObject::PutU1ArrayInAttribute(this->_publicExponent,attribute);
-
-        case CKA_PRIVATE_EXPONENT:
-            if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-                attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-                return CKR_ATTRIBUTE_SENSITIVE;
-            }
-            return StorageObject::PutU1ArrayInAttribute(this->_d,attribute);
-
-        case CKA_PRIME_1:
-            if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-                attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-                return CKR_ATTRIBUTE_SENSITIVE;
-            }
-            return StorageObject::PutU1ArrayInAttribute(this->_p,attribute);
-
-        case CKA_PRIME_2:
-            if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-                attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-                return CKR_ATTRIBUTE_SENSITIVE;
-            }
-            return StorageObject::PutU1ArrayInAttribute(this->_q,attribute);
-
-        case CKA_EXPONENT_1:
-            if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-                attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-                return CKR_ATTRIBUTE_SENSITIVE;
-            }
-            return StorageObject::PutU1ArrayInAttribute(this->_dp,attribute);
-
-        case CKA_EXPONENT_2:
-            if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-                attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-                return CKR_ATTRIBUTE_SENSITIVE;
-            }
-            return StorageObject::PutU1ArrayInAttribute(this->_dq,attribute);
-
-        case CKA_COEFFICIENT:
-            if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-                attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-                return CKR_ATTRIBUTE_SENSITIVE;
-            }
-            return StorageObject::PutU1ArrayInAttribute(this->_inverseQ,attribute);
-
-        default:
-            return PrivateKeyObject::GetAttribute(attribute);
-    }
-}
-
-void RSAPrivateKeyObject::Serialize(std::vector<u1> *to)
-{
-    PrivateKeyObject::Serialize(to);
-
-    // since keys will reside in the key container we are not going
-    // to marshal the key values except modulus and public exponent
-
-    Util::PushByteArrayInVector(to,this->_modulus);
-
-    Util::PushByteArrayInVector(to,this->_publicExponent);
-}
-
-void RSAPrivateKeyObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-    PrivateKeyObject::Deserialize(from,idx);
-
-    this->_modulus = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_publicExponent = Util::ReadByteArrayFromVector(from,idx);
-}
-
-
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,53 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_rsaprivatekeyobject_h
-#define _include_rsaprivatekeyobject_h
-
-#include "privatekeyobject.h"
-
-class RSAPrivateKeyObject : public PrivateKeyObject
-{
-
-public:
-    u1Array*    _publicExponent;
-    u1Array*    _modulus;
-    u1Array*    _d;
-    u1Array*    _p;
-    u1Array*    _q;
-    u1Array*    _dp;
-    u1Array*    _dq;
-    u1Array*    _inverseQ;
-
-public:
-     RSAPrivateKeyObject();
-    virtual ~RSAPrivateKeyObject();
-
-    CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    void Serialize(vector<u1>* to);
-    void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,152 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "rsapublickeyobject.h"
-
-RSAPublicKeyObject :: RSAPublicKeyObject() : PublicKeyObject()
-{
-   this->_modulus    = NULL_PTR;
-   this->_modulusLen = 0;
-   this->_exponent   = NULL_PTR;
-
-   this->_keyType        = CKK_RSA;
-}
-
-RSAPublicKeyObject :: ~RSAPublicKeyObject()
-{
-   if(this->_modulus != NULL_PTR)
-      delete this->_modulus;
-
-   if(this->_exponent != NULL_PTR)
-      delete this->_exponent;
-}
-
-CK_BBOOL RSAPublicKeyObject ::Compare(CK_ATTRIBUTE attribute)
-{
-   switch(attribute.type){
-
-        case CKA_MODULUS:
-           return Util::CompareU1Arrays(this->_modulus,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_MODULUS_BITS:
-           return (this->_modulusLen == *(CK_ULONG*)attribute.pValue);
-
-        case CKA_PUBLIC_EXPONENT:
-           return Util::CompareU1Arrays(this->_modulus,attribute.pValue,attribute.ulValueLen);
-
-        default:
-           return PublicKeyObject::Compare(attribute);
-   }
-}
-
-CK_RV RSAPublicKeyObject ::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-   switch(attribute->type){
-
-        case CKA_MODULUS:
-           return StorageObject::PutU1ArrayInAttribute(this->_modulus,attribute);
-
-        case CKA_MODULUS_BITS:
-           return StorageObject::PutULongInAttribute(this->_modulusLen,attribute);
-
-        case CKA_PUBLIC_EXPONENT:
-           return StorageObject::PutU1ArrayInAttribute(this->_exponent,attribute);
-
-        default:
-           return PublicKeyObject::GetAttribute(attribute);
-   }
-}
-
-CK_RV RSAPublicKeyObject ::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-   CK_RV rv = CKR_OK;
-
-   if(objCreation == CK_FALSE){
-      switch(attribute.type){
-            case CKA_PUBLIC_EXPONENT:
-            case CKA_MODULUS:
-            case CKA_MODULUS_BITS:
-               return CKR_ATTRIBUTE_READ_ONLY;
-      }
-   }
-
-   switch(attribute.type){
-
-        case CKA_MODULUS:
-           if(this->_modulus != NULL_PTR){
-              delete this->_modulus;
-           }
-           this->_modulus = StorageObject::ReadU1ArrayFromAttribute(attribute);
-           this->_modulusLen = _modulus->GetLength()*8;
-           break;
-
-        case CKA_PUBLIC_EXPONENT:
-           if(this->_exponent != NULL_PTR){
-              delete this->_exponent;
-           }
-           this->_exponent = StorageObject::ReadU1ArrayFromAttribute(attribute);
-           break;
-
-        case CKA_MODULUS_BITS:
-           {
-              CK_ULONG utemp = StorageObject::ReadULongFromAttribute(attribute,&rv);
-              if(rv == CKR_OK){ this->_modulusLen = utemp;}
-           }
-           break;
-
-        default:
-           return PublicKeyObject::SetAttribute(attribute,objCreation);
-   }
-
-   return rv;
-}
-
-void RSAPublicKeyObject ::Serialize(std::vector<u1> *to)
-{
-   PublicKeyObject::Serialize(to);
-
-   Util::PushByteArrayInVector(to,this->_modulus);
-
-   Util::PushByteArrayInVector(to,this->_exponent);
-
-   Util::PushULongInVector(to,this->_modulusLen);
-}
-
-void RSAPublicKeyObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-   PublicKeyObject::Deserialize(from,idx);
-
-   this->_modulus = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_exponent = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_modulusLen = Util::ReadULongFromVector(from,idx);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,49 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_rsapublickeyobject_h
-#define _include_rsapublickeyobject_h
-
-#include "publickeyobject.h"
-
-class RSAPublicKeyObject : public PublicKeyObject
-{
-
-public:
-    u1Array*    _modulus;
-    CK_ULONG    _modulusLen;
-    u1Array*    _exponent;
-
-public:
-    RSAPublicKeyObject();
-    virtual ~RSAPublicKeyObject();
-
-    CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    void Serialize(vector<u1>* to);
-    void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,4813 +0,0 @@
-
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include <stdexcept>
-#include "cardmoduleservice.h"
-#include <Except.h>
-#include <string>
-#include <list>
-#include <vector>
-#include <map>
-#include <memory>
-#include "session.h"
-#include "symmalgo.h"
-#include "tdes.h"
-#include "util.h"
-#include "zlib.h"
-#include "x509cert.h"
-#include "attrcert.h"
-#include "dataobject.h"
-#include "secretkeyobject.h"
-#include "transaction.h"
-#include "cardcache.h"
-#include "error.h"
-#include "timer.h"
-#include "md5.h"
-#include "log.h"
-
-
-#ifdef WIN32
-#include "BioMan.h"
-#else
-#define SCARD_CTL_CODE(code) (0x42000000 + (code))
-#endif
-
-// Helper functions to manage contents of cmapfile
-
-static void CMapFileClear(u1Array & file, u1 index);
-static void CMapFileSetName(u1Array & file, u1 index, string const & name);
-static u1 CMapFileGetFlag(u1Array const & file, u1 index);
-static void CMapFileSetFlag(u1Array & file, u1 index, u1 flag);
-static u2 CMapFileGetSignSize(u1Array const & file, u1 index);
-static void CMapFileSetSignSize(u1Array & file, u1 index, u2 size);
-static u2 CMapFileGetExchSize(u1Array const & file, u1 index);
-static void CMapFileSetExchSize(u1Array & file, u1 index, u2 size);
-
-// software RSA specific inclusion [they would be refined once I go and re-factor RSA algo as per Cryptoki naming convention]
-//#include "crypto_public.h"
-//#include "cr_rsa.h"
-
-#include "sctoken.h"
-
-#define BITS_0_7(l)  ((BYTE)(l & 0xff))
-#define BITS_8_15(l) ((BYTE)(((WORD)l & 0xff00) >> 8))
-
-#define MAX_RETRY 2
-
-#define CARD_PROPERTY_PIN_INFO_EX 0x87
-#define CARD_PROPERTY_PIN_INFO 0x07
-#define CARD_PROPERTY_EXTERNAL_PIN 0x01
-#define CARD_PROPERTY_NO_PIN 0x03
-#define CARD_PROPERTY_PIN_POLICY 0x80
-#define CARD_ROLE_USER 0x01
-#define CARD_SERIAL_NUMBER 0x06
-
-#define CM_IOCTL_GET_FEATURE_REQUEST SCARD_CTL_CODE(3400)
-//#define FEATURE_VERIFY_PIN_START 0x01
-//#define FEATURE_VERIFY_PIN_FINISH 0x02
-//#define FEATURE_MODIFY_PIN_START 0x03
-//#define FEATURE_MODIFY_PIN_FINISH 0x04
-//#define FEATURE_GET_KEY_PRESSED 0x05
-#define FEATURE_VERIFY_PIN_DIRECT 0x06
-//#define FEATURE_MODIFY_PIN_DIRECT 0x07
-//#define FEATURE_MCT_READERDIRECT 0x08
-//#define FEATURE_MCT_UNIVERSAL 0x09
-//#define FEATURE_IFD_PIN_PROP 0x0A
-//#define FEATURE_ABORT 0x0B
-
-#define UVM_PIN_ONLY 1
-#define UVM_FP_ONLY 2
-#define UVM_PIN_OR_FP 3
-#define UVM_PIN_AND_FP 4
-
-#define PIN_TYPE_REGULAR 0
-#define PIN_TYPE_EXTERNAL 1
-
-#define AUTHENTICATE_ERROR 0
-#define AUTHENTICATE_REGULAR 1
-#define AUTHENTICATE_PINPAD 2
-#define AUTHENTICATE_BIO 3
-
-#define LOW_FREE_MEMORY_ALLOWED 25000
-
-#pragma pack(push, mdnet, 1)
-
-typedef struct PIN_VERIFY_STRUCTURE
-{
-   BYTE bTimerOut;                  /* timeout is seconds (00 means use default timeout) */
-   BYTE bTimerOut2;                 /* timeout in seconds after first key stroke */
-   BYTE bmFormatString;             /* formatting options */
-   BYTE bmPINBlockString;           /* bits 7-4 bit size of PIN length in APDU,
-                                    * bits 3-0 PIN block size in bytes after
-                                    * justification and formatting */
-   BYTE bmPINLengthFormat;          /* bits 7-5 RFU,
-                                    * bit 4 set if system units are bytes, clear if
-                                    * system units are bits,
-                                    * bits 3-0 PIN length position in system units
-                                    */
-   BYTE bPINMaxExtraDigit1;         /* Max PIN size*/
-   BYTE bPINMaxExtraDigit2;         /* Min PIN size*/
-   BYTE bEntryValidationCondition;  /* Conditions under which PIN entry should
-                                    * be considered complete */
-   BYTE bNumberMessage;             /* Number of messages to display for PIN
-                                    verification */
-   USHORT wLangId;                  /* Language for messages */
-   BYTE bMsgIndex;                  /* Message index (should be 00) */
-   BYTE bTeoPrologue[3];            /* T=1 block prologue field to use (fill with 00) */
-   ULONG ulDataLength;              /* length of Data to be sent to the ICC */
-   BYTE abData[13];                 /* Data to send to the ICC */
-} PIN_VERIFY_STRUCTURE;
-
-#pragma pack(pop, mdnet)
-
-// Try/catch macros for all public methods
-#define TOKEN_TRY try
-#define TOKEN_CATCH(rv) \
-   catch(CkError & err) { rv = err.Error(); } \
-   catch(PcscError & ) { rv = CKR_FUNCTION_FAILED; } \
-   catch(Marshaller::Exception & exc) { rv = CkError::CheckMarshallerException(exc); } \
-   catch(...) { rv = CKR_GENERAL_ERROR; } \
-   if(rv==CKR_USER_NOT_LOGGED_IN || rv==CKR_PIN_INCORRECT || rv==CKR_PIN_LOCKED) \
-   _roleLogged = CKU_NONE; \
-
-namespace {
-   class CardTransaction
-   {
-   private:
-      Token * _token;
-
-   public:
-      CardTransaction(Token * token) : _token(token)
-      {
-         _token->CardBeginTransaction();
-      }
-
-      ~CardTransaction() throw()
-      {
-         try
-         {
-            _token->CardEndTransaction();
-         }
-         catch(...) {}
-      }
-   };
-}
-
-Token::Token(std::string* reader) : _mscm(0),
-_supportGarbageCollection(true),
-_cardCache(0),
-_fPinChanged(false),
-_fContainerChanged(false),
-_fFileChanged(false),
-_version(0)
-{
-   //Log::begin( "Token::Token" );
-
-   m_dwIoctlVerifyPIN = 0;
-
-   m_sReaderName = "";
-   if( NULL != reader )
-   {
-      m_sReaderName = (*reader).c_str( );
-   }
-
-   std::string svcname("MSCM");
-   _mscm = new CardModuleService( reader, 5, &svcname );
-
-   _mscm->DoSCardTransact(false);  // Turn off transaction handling since it is performed at application level
-
-   // Transact card
-   CardTransaction ct(this);
-
-   _cardCache = new CardCache(_mscm);
-
-   // Get seed for RNG from card. This is the first command to
-   // card. If it fails, assume the card is not a .NET card.
-   try
-   {
-      auto_ptr<u1Array> challenge(_mscm->GetChallenge( ));
-      Util::SeedRandom(*challenge);
-   }
-   catch(...)
-   {
-      Log::error( "Token::Token", "GetChallenge - CKR_TOKEN_NOT_RECOGNIZED" );
-      throw CkError(CKR_TOKEN_NOT_RECOGNIZED);
-   }
-
-   this->_roleLogged   = CKU_NONE;
-
-   // flush TokenInfo
-   memset(&this->_tokenInfo, 0x00, sizeof(this->_tokenInfo));
-
-   this->_tokenInfo.ulMaxSessionCount      = CK_EFFECTIVELY_INFINITE;
-   this->_tokenInfo.ulSessionCount         = CK_UNAVAILABLE_INFORMATION;
-   this->_tokenInfo.ulMaxRwSessionCount    = CK_EFFECTIVELY_INFINITE;
-   this->_tokenInfo.ulRwSessionCount       = CK_UNAVAILABLE_INFORMATION;
-   this->_tokenInfo.ulMaxPinLen            = MAX_PIN_LEN;
-   this->_tokenInfo.ulMinPinLen            = MIN_PIN_LEN;
-
-   this->_tokenInfo.ulTotalPublicMemory    = CK_UNAVAILABLE_INFORMATION;
-   this->_tokenInfo.ulTotalPrivateMemory   = CK_UNAVAILABLE_INFORMATION;
-   this->_tokenInfo.ulFreePrivateMemory    = CK_UNAVAILABLE_INFORMATION;
-   this->_tokenInfo.ulFreePublicMemory     = CK_UNAVAILABLE_INFORMATION;
-
-   // Version of the Card Operating system
-   this->_tokenInfo.hardwareVersion.major  = 2;
-   this->_tokenInfo.hardwareVersion.minor  = 0;
-
-   // (TBD) Version of Card Module application
-   // there is mess which have been created by reading it from file etc ?
-   this->_tokenInfo.firmwareVersion.major  = 2;
-   this->_tokenInfo.firmwareVersion.minor  = 0;
-
-   this->_tokenInfo.flags  = CKF_RNG | CKF_LOGIN_REQUIRED | CKF_TOKEN_INITIALIZED | CKF_USER_PIN_INITIALIZED;
-
-   // Check if the smart card is in SSO mode
-   m_bIsSSO = isSSO( );
-
-   // Check if PinPad device is supported
-   m_bIsPinPadSupported = isPinPadSupported( );
-
-   // Get the card configuration (mode, PIN type)
-   m_bCardMode = UVM_PIN_ONLY;
-   m_bTypePIN = PIN_TYPE_REGULAR;
-   getCardConfiguration( m_bCardMode, m_bTypePIN );
-   
-   m_bIsNoPinSupported = false;
-   if( m_bTypePIN == 0x03 )
-   {
-      m_bIsNoPinSupported = true;
-   }
-
-   bool bIsAuthenticated = this->isAuthenticated( );
-
-   Log::log( "Token::Token - PIN type <%ld> (0 = regular ; 1 = external ; 2 = challenge/response ; 3 = no pin)", m_bTypePIN );
-   Log::log( "Token::Token - Card mode <%ld> (1 = pin only ; 2 = fp only ; 3 = fp or pin ; 4 = fp and pin)", m_bCardMode );
-   Log::log( "Token::Token - IsNoPinSupported <%d>", m_bIsNoPinSupported );
-   Log::log( "Token::Token - IsSSO <%d>", m_bIsSSO );
-   Log::log( "Token::Token - IsAuthenticated <%d>", bIsAuthenticated );
-
-   // Is login required ?
-   if(   ( true == m_bIsNoPinSupported ) 
-      || ( ( true == m_bIsSSO ) && ( true == bIsAuthenticated ) )
-      )
-   {
-      this->_tokenInfo.flags &= ~CKF_LOGIN_REQUIRED;
-      Log::log( "Token::Token - No login required" );
-   }
-
-   // Check if the CKF_PROTECTED_AUTHENTICATION_PATH flag must be raised
-   if( ( m_bTypePIN == PIN_TYPE_EXTERNAL ) && ( ( ( m_bCardMode == UVM_PIN_ONLY ) && m_bIsPinPadSupported ) || ( m_bCardMode != UVM_PIN_ONLY ) ) )
-   {
-      Log::log( "Token::Token - Enable CKF_PROTECTED_AUTHENTICATION_PATH" );
-      this->_tokenInfo.flags  |= CKF_PROTECTED_AUTHENTICATION_PATH;
-   }
-
-   // we need to check if token is initialized or not.
-   // Initialization would essentially mean that we create
-   // the necessary file structure.
-
-   // Get current value of \cardcf file
-   std::string sCardcf("cardcf");
-
-   //Log::log( "Token::Token - ReadFile ..." );
-   auto_ptr<u1Array> fileData(_mscm->ReadFile(&sCardcf,0));
-   //Log::log( "Token::Token - ReadFile ..." );
-
-   if(fileData->GetLength() < 6)
-   {
-      Log::error( "Token::Token", " (fileData->GetLength() < 6) - CKR_TOKEN_NOT_RECOGNIZED" );
-      throw CkError(CKR_TOKEN_NOT_RECOGNIZED);
-   }
-   CK_ULONG cardCf = LittleEndianToInt<CK_ULONG>(fileData->GetBuffer()+2);
-
-   //Log::log( "Token::Token - get serial number" );
-   //m_u1aSerialNumber = _mscm->GetCardProperty( CARD_SERIAL_NUMBER, 0 );
-
-   this->_initialized  = this->IsInitialized();
-
-   if(_initialized)
-   {
-      //Log::log( "Token::Token - DeserializeTokenInfo ..." );
-      this->DeserializeTokenInfo();
-      //Log::log( "Token::Token - DeserializeTokenInfo ok" );
-   }
-   else
-   {
-      //Log::log( "Token::Token - PopulateDefaultTokenInfo ..." );
-      // fill up the tokenInfo
-      this->PopulateDefaultTokenInfo();
-      //Log::log( "Token::Token - PopulateDefaultTokenInfo ok" );
-   }
-
-   // Set current values unequal to the stored to force the initial syncronization
-   _cardCfTimer = 0;
-   _cardCf = cardCf;
-   _publCardCf = ~cardCf;
-   _privCardCf = ~cardCf;
-   _cacheCardCf = ~cardCf;
-
-   //printf( "\nToken::Token - ManageGC( true )\n" );
-   //ManageGC( true );
-
-   //Log::end( "Token::Token" );
-}
-
-Token::~Token()
-{
-   Log::begin( "Token::~Token" );
-
-   ManageGC( true );
-
-   delete _cardCache;
-   
-   delete this->_mscm;
-   
-   //if( NULL != m_u1aSerialNumber )
-   //{
-   //   delete m_u1aSerialNumber;
-   //}
-
-   Clear();
-
-   Log::end( "Token::~Token" );
-}
-
-
-
-void Token::ManageGC( bool bForceGarbage )
-{
-   if(!_supportGarbageCollection)
-      return;
-   try
-   {
-      if( true == bForceGarbage )
-      {
-         //printf( "\nToken::ManageGC - ForceGarbageCollector (true)\n" );
-
-         Log::log( "Token::ManageGC - ForceGarbageCollector" );
-         _mscm->ForceGarbageCollector( );
-      }
-      else
-      {
-         s4 freeMemory = _mscm->GetMemory( );
-         if( freeMemory < LOW_FREE_MEMORY_ALLOWED )
-         {
-            //printf( "\nToken::ManageGC - ForceGarbageCollector\n" );
-
-            Log::log( "Token::ManageGC - ForceGarbageCollector (low)" );
-            _mscm->ForceGarbageCollector( );
-         }
-      }
-   }
-   catch(...)
-   {
-      _supportGarbageCollection = false;
-   }
-}
-
-
-void Token::Clear()
-{
-   for(size_t i=0;i<_objects.size();i++)
-      delete _objects[i];
-   _objects.clear( );
-}
-
-
-void Token::BeginTransaction()
-{
-   // To improve performance, avoid checking cardcf unless there could possibly
-   // have been an update by external application, based on the time it was last
-   // known to be up-do-date, which means at end of previous transaction.
-
-   static const unsigned long maximumCardCfCheckInterval = 100;  // 100 milliseconds.
-
-   CardBeginTransaction();
-   try
-   {
-      _fPinChanged = false;
-      _fContainerChanged = false;
-      _fFileChanged = false;
-
-      unsigned long tick = CTimer::ClockTicks();
-
-      // First check d.t possible timer wrap around every ~50 days.
-      if(_cardCfTimer > tick || _cardCfTimer + maximumCardCfCheckInterval < tick)
-      {
-         // Read cache file.
-         std::string sCardcf("cardcf");
-         auto_ptr<u1Array> fileData(_mscm->ReadFile(&sCardcf,0));
-         //ManageGC( );
-         if(fileData->GetLength() < 6)
-            throw CkError(CKR_TOKEN_NOT_RECOGNIZED);
-
-         _cardCf = LittleEndianToInt<CK_ULONG>(fileData->GetBuffer()+2);
-      }
-
-      if(   ( _publCardCf != _cardCf ) 
-         || (    ( _privCardCf != _cardCf ) 
-              && (    ( CKU_USER == _roleLogged )
-                   || ( true == m_bIsNoPinSupported ) 
-                   || ( ( true == m_bIsSSO ) && ( true == this->isAuthenticated( ) ) )
-                  )
-             )
-         )
-      //if((_publCardCf != _cardCf) ||
-      //   ((_privCardCf != _cardCf) && (_roleLogged == CKU_USER)))
-      {
-         // Card changed, so re-synchronize
-         Resynchronize();
-      }
-   }
-   catch(...)
-   {
-      CardEndTransaction();
-      throw;
-   }
-}
-
-void Token::EndTransaction( )
-{
-   try
-   {
-      // Update \cardcf if card has changed.
-      if(_fPinChanged || _fContainerChanged || _fFileChanged)
-      {
-         //  cardcf format:
-         //  typedef struct _CARD_CACHE_FILE_FORMAT
-         //  {
-         //      BYTE bVersion;
-         //      BYTE bPinsFreshness;
-         //      WORD wContainersFreshness;
-         //      WORD wFilesFreshness;
-         //  } CARD_CACHE_FILE_FORMAT, *PCARD_CACHE_FILE_FORMAT;
-
-         //  Read cache file.
-         std::string sCardCf("cardcf");
-         auto_ptr<u1Array> fileData(_mscm->ReadFile(&sCardCf,0));
-
-         BYTE bPinsFreshness = fileData->ReadU1At(1);
-         WORD wContainersFreshness = LittleEndianToInt<WORD>(fileData->GetBuffer(),2);
-         WORD wFilesFreshness = LittleEndianToInt<WORD>(fileData->GetBuffer(),4);
-
-         if(_fPinChanged)
-            bPinsFreshness++;
-         if(_fContainerChanged)
-            wContainersFreshness++;
-         if(_fFileChanged)
-            wFilesFreshness++;
-
-         fileData->SetU1At(1, bPinsFreshness);
-         IntToLittleEndian<WORD>(wContainersFreshness, fileData->GetBuffer(),2);
-         IntToLittleEndian<WORD>(wFilesFreshness, fileData->GetBuffer(),4);
-
-
-         // Write cache file back
-         _mscm->WriteFile(&sCardCf, fileData.get());
-
-         ManageGC( );
-
-         // As a result of own update, our own cache is still valid
-         // as long as it was valid before.
-         CK_ULONG newCardCf = LittleEndianToInt<CK_ULONG>(fileData->GetBuffer()+2);
-
-         if(_publCardCf == _cardCf)
-            _publCardCf = newCardCf;
-         if(_privCardCf == _cardCf)
-            _privCardCf = newCardCf;
-         if(_cacheCardCf == _cardCf)
-            _cacheCardCf = newCardCf;
-
-         _cardCf = newCardCf;
-         _cardCfTimer = CTimer::ClockTicks();
-      }
-      else
-         _cardCfTimer = CTimer::ClockTicks();
-   }
-   catch( CkError x )
-   {
-      CK_RV rv = x.Error( );
-      Log::log( "## Error ## Token::EndTransaction - WriteFile failed <%ld>\n", rv );
-   }
-   catch( ... )
-   {
-   }
-
-   CardEndTransaction( );
-}
-
-void Token::Resynchronize()
-{
-   //printf( "\nToken::Resynchronize\n" );
-
-   // To be called at initial creation and also whenever
-   // it is detected that card has been changed.
-   // When re-sync, one have to maintain the object handles
-   // of the objects that have not been deleted. Therefore,
-   // build a new object list and compare with the existing.
-
-   if(_cacheCardCf != _cardCf)
-   {
-      _cardCache->ClearAll();
-      _cacheCardCf = _cardCf;
-   }
-
-   map<int, ContainerInfo> contMap;
-   BuildContainerInfoMap(contMap);
-
-   vector<StorageObject*> newObjects;
-   vector<string> toDelete;
-
-   SynchronizePublicObjects(newObjects, toDelete, contMap);
-   SynchronizeCertificates(newObjects, contMap);
-
-   _publCardCf = _cardCf;
-
-   if(   ( CKU_USER == _roleLogged )
-      || ( true == m_bIsNoPinSupported ) 
-      || ( ( true == m_bIsSSO ) && ( true == this->isAuthenticated( ) ) )
-      )
-   {
-      CK_RV rv = CKR_OK;
-      TOKEN_TRY
-      {
-         SynchronizePrivateObjects(newObjects, toDelete, contMap);
-         SynchronizePrivateKeys(newObjects, contMap);
-         _privCardCf = _cardCf;
-      }
-      TOKEN_CATCH(rv);
-   }
-
-   // Build the new list with new objects occupying the
-   // position as the old objects. StorageObject::IsEqual
-   // is used to compare two objects.
-   vector<StorageObject*> objects(_objects.size(), 0);
-   for(size_t iobj = 0; iobj<_objects.size(); ++iobj)
-   {
-      if(!_objects[iobj])
-         continue;
-      for(size_t inew = 0; inew < newObjects.size(); ++inew)
-      {
-         if(newObjects[inew] && newObjects[inew]->IsEqual(_objects[iobj]))
-         {
-            // Transfer ownership
-            objects[iobj] = newObjects[inew];
-            newObjects[inew] = 0;
-            break;
-         }
-      }
-   }
-
-   // Add the potential new objects, which are those left in
-   // newObjects. Add them to the end of the list
-   for(size_t inew = 0; inew < newObjects.size(); ++inew)
-   {
-      if(newObjects[inew])
-         objects.push_back(newObjects[inew]);
-   }
-
-   // Delete the objects in the old object list
-   for(size_t iobj = 0; iobj<_objects.size(); ++iobj)
-      delete _objects[iobj];
-
-   // Store the new list as current
-   _objects = objects;
-
-   // Store the list of files to delete, then delete these if logged in.
-   _toDelete = toDelete;
-
-   if(   ( CKU_USER == _roleLogged )
-      || ( true == m_bIsNoPinSupported ) 
-      || ( ( true == m_bIsSSO ) && ( true == this->isAuthenticated( ) ) )
-      )
-   //if(   ( CKU_USER == _roleLogged )
-   {
-      PerformDeferredDelete();
-   }
-}
-
-u1Array* Token::ComputeCryptogram(u1Array* challenge,u1Array* pin)
-{
-
-   // time to prepare the master key.
-   // Only accept correct length, otherwise
-   // return a zero valued response that is
-   // sure to fail authentication.
-
-   CK_BYTE expectedCryptogram[8];
-   memset(expectedCryptogram,0x00,8);  // Default
-
-   if(pin->GetLength() == 24)
-   {
-      // compute the response
-      CK_BYTE iv[8];
-      memset(iv,0,8);
-
-      CTripleDES tdes;
-
-      tdes.SetEncryptMode(ENCRYPT);
-      tdes.SetIV(iv);
-      tdes.SetCipherMode(CIPHER_MODE_ECB);
-      tdes.SetPaddingMode(PADDING_MODE_NONE);
-      tdes.SetKey(pin->GetBuffer(),24);
-      tdes.TransformFinalBlock(challenge->GetBuffer(),0,8,expectedCryptogram,0);
-   }
-   u1Array* response = new u1Array(8);
-   response->SetBuffer(expectedCryptogram);
-
-   return response;
-}
-
-CK_RV Token::DoPINValidityChecks(u1Array* pin, bool fCheckCharaceters){
-
-   if((pin->GetLength() < MIN_PIN_LEN) || (pin->GetLength() > MAX_PIN_LEN)){
-      return CKR_PIN_LEN_RANGE;
-   }
-
-   if(fCheckCharaceters)
-   {
-      // check if pin is valid
-      for (u4 i = 0; i < pin->GetLength(); i++){
-         if ((pin->GetBuffer()[i] < 0x20) ||
-            (pin->GetBuffer()[i] > 0x7D) ||
-            (pin->GetBuffer()[i] == 0x24)||
-            (pin->GetBuffer()[i] == 0x40)||
-            (pin->GetBuffer()[i] == 0x60))
-         {
-            return CKR_PIN_INVALID;
-         }
-      }
-   }
-   return CKR_OK;
-}
-
-CK_RV Token::InitPIN(u1Array* soPIN,u1Array* userPIN)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      rv = Token::DoPINValidityChecks(userPIN);
-
-      if(rv != CKR_OK){
-         throw CkError(rv);
-      }
-
-      auto_ptr<u1Array> challenge(_mscm->GetChallenge());
-      auto_ptr<u1Array> cryptogram(ComputeCryptogram(challenge.get(), soPIN));
-
-      try{
-
-         this->_mscm->ChangeReferenceData(MODE_UNBLOCK_PIN,CARD_ROLE_USER,cryptogram.get(),userPIN,MAX_USER_PIN_TRIES);
-         this->RegisterPinUpdate();
-
-         // Log in user to update token info
-         this->_mscm->VerifyPin(CARD_ROLE_USER, userPIN);
-
-         if(_initialized)
-            DeserializeTokenInfo();
-         else
-            Initialize();
-
-         // Save User PIN Initialized flag, the other PIN flags are not stored
-         this->_tokenInfo.flags |= CKF_USER_PIN_INITIALIZED;
-         SerializeTokenInfo();
-         this->_mscm->LogOut(CARD_ROLE_USER);
-
-         // Reset some User PIN flags
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-
-      }
-      catch(Marshaller::RemotingException&){
-         rv = CKR_TOKEN_NOT_PRESENT;
-      }
-      catch(Marshaller::UnauthorizedAccessException&){
-
-         // incorrect pin
-         s4 triesRemaining = this->_mscm->GetTriesRemaining(CARD_ROLE_ADMIN);
-
-         // blocked
-         if(triesRemaining == 0){
-            // update tokeninfo flahs
-            this->_tokenInfo.flags |= CKF_SO_PIN_LOCKED;
-            this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-            this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-         }else if(triesRemaining == 1){
-            this->_tokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
-            this->_tokenInfo.flags |= CKF_SO_PIN_FINAL_TRY;
-            this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-         }else if(triesRemaining < MAX_SO_PIN_TRIES){
-            this->_tokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
-            this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-            this->_tokenInfo.flags |= CKF_SO_PIN_COUNT_LOW;
-         }
-
-         rv = CKR_PIN_INCORRECT;
-
-      }
-      catch(std::runtime_error&){
-         rv = CKR_DEVICE_ERROR;
-      }
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::SetPIN(u1Array* oldPIN,u1Array* newPIN)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-
-      bool fCheckCharacters = (_roleLogged != CKU_SO);
-      rv = Token::DoPINValidityChecks(newPIN, fCheckCharacters);
-
-      if(rv != CKR_OK){
-         throw CkError(rv);
-      }
-
-      CK_BYTE  role       = 0;
-      s4 maxTries         = 0;
-
-      auto_ptr<u1Array> oldPINTemp;
-      auto_ptr<u1Array> newPINTemp;
-
-      if(this->_roleLogged == CKU_SO){
-
-         role = CARD_ROLE_ADMIN;
-         maxTries = MAX_SO_PIN_TRIES;
-
-         u1Array* challenge = this->_mscm->GetChallenge();
-
-         oldPINTemp = auto_ptr<u1Array>(this->ComputeCryptogram(challenge,oldPIN));
-
-         delete challenge;
-
-         // new PIN has to be 24 bytes
-         // if not we just pad rest of bytes as zeros
-         newPINTemp = auto_ptr<u1Array>(new u1Array(24));
-         memset(newPINTemp->GetBuffer(),0,24);
-         memcpy(newPINTemp->GetBuffer(),newPIN->GetBuffer(),newPIN->GetLength());
-
-      }else{
-
-         role = CARD_ROLE_USER;
-         maxTries = MAX_USER_PIN_TRIES;
-
-         oldPINTemp = auto_ptr<u1Array>(new u1Array(oldPIN->GetLength()));
-         oldPINTemp->SetBuffer(oldPIN->GetBuffer());
-
-         newPINTemp = auto_ptr<u1Array>(new u1Array(newPIN->GetLength()));
-         newPINTemp->SetBuffer(newPIN->GetBuffer());
-      }
-
-      try{
-         this->_mscm->ChangeReferenceData(MODE_CHANGE_PIN,role,oldPINTemp.get(),newPINTemp.get(),maxTries);
-         this->RegisterPinUpdate();
-      }
-      catch(Marshaller::RemotingException&){
-         rv = CKR_TOKEN_NOT_PRESENT;
-      }
-      catch(Marshaller::UnauthorizedAccessException&){
-
-         // incorrect pin
-         s4 triesRemaining = this->_mscm->GetTriesRemaining(role);
-
-         if(role == CARD_ROLE_ADMIN){
-
-            // blocked
-            if(triesRemaining == 0){
-               // update tokeninfo flahs
-               this->_tokenInfo.flags |= CKF_SO_PIN_LOCKED;
-               this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-               this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-            }else if(triesRemaining == 1){
-               this->_tokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
-               this->_tokenInfo.flags |= CKF_SO_PIN_FINAL_TRY;
-               this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-            }else if(triesRemaining < MAX_SO_PIN_TRIES){
-               this->_tokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
-               this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-               this->_tokenInfo.flags |= CKF_SO_PIN_COUNT_LOW;
-            }
-
-         }else{
-
-            // blocked
-            if(triesRemaining == 0){
-               // update tokeninfo flahs
-               this->_tokenInfo.flags |= CKF_USER_PIN_LOCKED;
-               this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-               this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-            }else if(triesRemaining == 1){
-               this->_tokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
-               this->_tokenInfo.flags |= CKF_USER_PIN_FINAL_TRY;
-               this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-            }else if(triesRemaining < MAX_USER_PIN_TRIES){
-               this->_tokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
-               this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-               this->_tokenInfo.flags |= CKF_USER_PIN_COUNT_LOW;
-            }
-         }
-
-         rv = triesRemaining ? CKR_PIN_INCORRECT : CKR_PIN_LOCKED;
-
-
-      }
-      catch(std::runtime_error&){
-         rv = CKR_DEVICE_ERROR;
-      }
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::InitToken(u1Array* pin,u1Array* label)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-
-      // Check that label does not contain null-characters
-      PKCS11_ASSERT(label->GetLength() == 32);
-      for(u4 i = 0; i<label->GetLength(); ++i)
-      {
-         if(!label->ReadU1At(i))
-            throw CkError(CKR_ARGUMENTS_BAD);
-      }
-
-      // first check if pin is locked or not
-      s4 triesRemaining = this->_mscm->GetTriesRemaining(CARD_ROLE_ADMIN);
-
-      // blocked
-      if(triesRemaining == 0){
-         throw CkError(CKR_PIN_LOCKED);
-      }
-
-      // Change User PIN to random
-      R_RANDOM_STRUCT & randomStruc = Util::RandomStruct();
-      u1Array randomPin(MAX_PIN_LEN);
-      R_GenerateBytes(randomPin.GetBuffer(), MAX_PIN_LEN, &randomStruc);
-      // Make a number to comply with rules in DoPINValidityChecks
-      for(u4 i = 0; i < MAX_PIN_LEN; ++i)
-         randomPin.SetU1At(i, '0' + randomPin.ReadU1At(i)%10);   // Not 100% random any more....
-
-      rv = InitPIN(pin, &randomPin);
-      if(rv != CKR_OK)
-         throw CkError(rv);
-
-      // actual authentication
-      rv = this->AuthenticateAdmin(pin);
-      if(rv != CKR_OK){
-         throw CkError(rv);
-      }
-
-      // this seems strange the reason,
-      // I am doing this is to use DeleteObject
-      // method which expects the user to be logged
-      // in
-      this->_roleLogged = CKU_USER;
-
-      // TODO: InitToken should not care to do the regular token initialization
-      // in particular if it needs to clean up a token that will not load.....
-      // It should delete files directly as well as containers.
-      BeginTransaction();
-      try
-      {
-         if(!_initialized)
-            Initialize();
-
-         //Log::log("Deleting all token objects....");
-
-         // destroy all the token objects
-         for(size_t t=0; t<_objects.size(); t++){
-            if(this->_objects[t] != NULL_PTR){
-               // what if DeleteObject has failed for any reason ?
-               this->DeleteObject(CO_TOKEN_OBJECT | static_cast<CK_OBJECT_HANDLE>(t+1));
-            }
-         }
-
-         // Update the token's label and flags attribute.
-         // Re-fetch first to be sure _tokenInfo is valid
-         DeserializeTokenInfo();
-         _tokenInfo.flags |= CKF_TOKEN_INITIALIZED;
-         _tokenInfo.flags &= ~CKF_USER_PIN_INITIALIZED;
-         memcpy(_tokenInfo.label, label->GetBuffer(), 32);
-         SerializeTokenInfo();
-
-         _mscm->LogOut(CARD_ROLE_ADMIN);
-         _roleLogged = CKU_NONE;
-      }
-      catch(...)
-      {
-         _roleLogged = CKU_NONE;
-         try { _mscm->LogOut(CARD_ROLE_ADMIN); } catch(...) {}
-         EndTransaction();
-         throw;
-      }
-      EndTransaction();
-
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-bool Token::IsInitialized()
-{
-   bool result = false;
-
-   // the way we determine that token is not initialized
-   // is to check for the existence of p11 directory in the root
-   // since GetFiles() does not return directory I have base my judgement
-   // on the IOException or DirectoryNotFoundException for tinfo
-   std::string tinfo("p11\\tinfo");
-
-   try{
-      //ManageGC( );
-      _cardCache->ReadFile(tinfo);
-      result = true;
-   }
-   catch(...){}
-
-   return result;
-
-}
-
-void Token::CreateDirIfNotPresent(std::string* /*parent*/,std::string* dir,u1Array* acls)
-{
-
-   try{
-      this->_mscm->CreateDirectory(dir,acls);
-   }
-   catch(std::runtime_error&){
-      // ignore the exception as the directory may already be present
-      // TBD : May it more robust
-   }
-}
-
-void Token::Initialize()
-{
-   PKCS11_ASSERT(!_initialized);
-
-   std::string root("");
-   std::string p11("p11");
-
-   u1Array acls(3);
-   acls.GetBuffer()[0] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // admin acl
-   acls.GetBuffer()[1] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // usr acl
-   acls.GetBuffer()[2] = CARD_PERMISSION_READ; // everyone acl
-
-   // create p11 directory
-   this->CreateDirIfNotPresent(&root,&p11,&acls);
-
-   // create token info
-   std::string tinfo("p11\\tinfo");
-   _cardCache->ClearFileList("p11");
-   this->_mscm->CreateFile(&tinfo,&acls,0);
-
-   // Serialize default token Info
-   this->SerializeTokenInfo();
-
-   this->RegisterFileUpdate();
-
-   this->_initialized = true;
-
-}
-
-void Token::ReadAndPopulateObjects(vector<StorageObject*> & objects, vector<string> & toDelete,
-                                   string const & prefix, map<int, ContainerInfo> & contMap)
-{
-
-   CK_ULONG cls;
-
-   vector<string> files(_cardCache->FileList("p11"));
-
-   for(u4 i=0;i<files.size();i++)
-   {
-      std::string aFile(files[i]);
-
-      if(aFile.find(prefix) != 0) // Must start with <prefix>
-         continue;
-
-      std::string filePath("p11\\");
-
-      filePath.append(aFile);
-      const u1Array & fileData = _cardCache->ReadFile(filePath);
-
-      if (aFile.substr(prefix.size(), 3) == "dat")
-      {
-         cls = CKO_DATA;
-      }
-      //else if (aFile.substr(prefix.size(), 3) == "cer")
-      //{
-      //    cls = CKO_CERTIFICATE;
-      //}
-      else if (aFile.substr(prefix.size(), 3) == "kxc")
-      {
-         cls = CKO_CERTIFICATE;
-      }
-      else if (aFile.substr(prefix.size(), 3) == "ksc")
-      {
-         cls = CKO_CERTIFICATE;
-      }
-      else if (aFile.substr(prefix.size(), 3) == "puk")
-      {
-         cls = CKO_PUBLIC_KEY;
-      }
-      else if (aFile.substr(prefix.size(), 3) == "prk")
-      {
-         cls = CKO_PRIVATE_KEY;
-      }
-      else if (aFile.substr(prefix.size(), 3) == "sec")
-      {
-         cls = CKO_SECRET_KEY;
-      }
-      else
-      {
-         cls = CKO_VENDOR_DEFINED;
-      }
-
-      StorageObject* object = NULL_PTR;
-
-      switch(cls){
-
-            case CKO_DATA:
-               object = new DataObject();
-               break;
-
-            case CKO_PUBLIC_KEY:
-               object = new RSAPublicKeyObject();
-               break;
-
-            case CKO_PRIVATE_KEY:
-               object = new RSAPrivateKeyObject();
-               break;
-
-            case CKO_SECRET_KEY:
-               object = new SecretKeyObject();
-               break;
-
-            case CKO_CERTIFICATE:
-               object = new X509PubKeyCertObject();
-               ((X509PubKeyCertObject*)object)->_certName = aFile.substr(prefix.size(), aFile.size()-prefix.size());
-               break;
-
-            default:
-               continue;
-      }
-
-      vector<u1> from;
-      for(u4 u=0;u<fileData.GetLength();u++){
-         from.push_back(fileData.GetBuffer()[u]);
-      }
-
-      CK_ULONG idx = 0;
-
-      object->Deserialize(from,&idx);
-
-      // put the fileName for the object
-      // as it is not deserialized
-      object->_fileName = filePath;
-
-      bool fAddObject = true;
-
-      // For CKO_PRIVATE_KEY and CKO_CERTIFICATE, check that the objects
-      // actually exists in the container. If they don't, flag that the
-      // file shall be deleted.
-      if(cls == CKO_PRIVATE_KEY)
-      {
-         PrivateKeyObject * privKey = static_cast<PrivateKeyObject*>(object);
-         map<int, ContainerInfo>::iterator icont = contMap.find(privKey->_ctrIndex);
-         if(icont != contMap.end() && icont->second._cmapEntry)
-         {
-            KeyPair & keyPair = (privKey->_keySpec == KEYSPEC_KEYEXCHANGE) ?
-               icont->second._exchKP : icont->second._signKP;
-            if(keyPair._checkValue == privKey->_checkValue)
-            {
-               // Object exist in the container. Flag that there exists a P11 private
-               // key for this key pair so that it will not be instantiated twice.
-               keyPair._fP11PrivKeyExists = true;
-            }
-            else
-               fAddObject = false;
-         }
-         else
-            fAddObject = false;
-      }
-      else if(cls == CKO_CERTIFICATE)
-      {
-         X509PubKeyCertObject * cert = static_cast<X509PubKeyCertObject*>(object);
-         map<int, ContainerInfo>::iterator icont = contMap.find(cert->_ctrIndex);
-         if(icont != contMap.end() && icont->second._cmapEntry)
-         {
-            u1Array certValue;
-            KeyPair & keyPair = (cert->_keySpec == KEYSPEC_KEYEXCHANGE) ?
-               icont->second._exchKP : icont->second._signKP;
-
-            certValue = keyPair._cert;
-            if(certValue.GetLength())
-            {
-               u8 checkValue = 0;
-               try
-               {
-                  X509Cert x509cert(certValue.GetBuffer(), certValue.GetLength());
-                  BEROctet::Blob modulus(x509cert.Modulus());
-                  checkValue = Util::MakeCheckValue(modulus.data(), static_cast<unsigned int>(modulus.size()));
-                  if(cert->_checkValue == checkValue)
-                  {
-                     // Correct certificate! Assign the value and register it.
-                     // Flag that there exists a P11 certificate object for this
-                     // key pair so that it will not be instantiated twice.
-                     cert->_value = new u1Array();
-                     *cert->_value = certValue;
-                     keyPair._fP11CertExists = true;
-                  }
-                  else
-                     fAddObject = false;
-               }
-               catch(...)
-               {
-                  // Not valid X509 certificate, ignore it.
-                  fAddObject = false;
-               }
-            }
-            else
-               fAddObject = false;
-         }
-         else
-            fAddObject = false;
-      }
-
-      if(fAddObject)
-         objects.push_back(object);
-      else
-      {
-         delete object;
-         toDelete.push_back(filePath);
-      }
-   }
-}
-
-void Token::SynchronizePublicObjects(vector<StorageObject*> & objects, vector<string> & toDelete, map<int, ContainerInfo> & contMap)
-{
-   //Log::log("Synchrnoizing Public Objects...");
-
-   if(!_initialized){
-      //Log::log("Token not initialized, hence no objects.");
-      return;
-   }
-
-   ReadAndPopulateObjects(objects, toDelete, "pub", contMap);
-   //ManageGC();
-}
-
-void Token::SynchronizePrivateObjects(vector<StorageObject*> & objects, vector<string> & toDelete, map<int, ContainerInfo> & contMap)
-{
-   //Log::log("Synchronizing Private Objects...");
-
-   if(!_initialized){
-      //Log::log("Token not initialized, hence no objects.");
-      return;
-   }
-
-   ReadAndPopulateObjects(objects, toDelete, "pri", contMap);
-   //ManageGC();
-}
-
-void Token::BuildContainerInfoMap(map<int, ContainerInfo> & contMap)
-{
-   contMap.clear();
-
-   // Step 1: Populate map from existence of files named mscp\kxc## and mscp\ksc##
-   string mscpDir("mscp");
-   vector<string> mscpFiles(_cardCache->FileList(mscpDir));
-
-   for(u4 ifile = 0; ifile < mscpFiles.size(); ++ifile)
-   {
-      std::string aFile(mscpFiles[ifile]);
-      if(aFile.size() != 5 || aFile[0] != 'k' || aFile[2] != 'c')
-         continue;
-
-      u1 keySpec;
-      if(aFile[1] == 'x')
-         keySpec = KEYSPEC_KEYEXCHANGE;
-      else if(aFile[1] == 's')
-         keySpec = KEYSPEC_SIGNATURE;
-      else
-         continue;
-
-      int ctrIndex;
-      if(sscanf(aFile.substr(3, 2).c_str(), "%d", &ctrIndex) != 1)
-         continue;
-      if(ctrIndex <0)
-         continue;
-
-      // Read certificate file
-
-      std::string aFilePath = mscpDir + "\\" + aFile;
-
-      auto_ptr<u1Array> value(ReadCertificateFile(aFilePath));
-
-      if(keySpec == KEYSPEC_SIGNATURE)
-      {
-         contMap[ctrIndex]._signKP._cert = *value;
-         contMap[ctrIndex]._signKP._certName = aFile;
-      }
-      else
-      {
-         contMap[ctrIndex]._exchKP._cert = *value;
-         contMap[ctrIndex]._exchKP._certName = aFile;
-      }
-   }
-
-   // Step 2: Update map from valid cmapfile entries
-
-   std::string nameCMapFile("mscp\\cmapfile");
-   const u1Array & fileData = _cardCache->ReadFile(nameCMapFile);
-   u4 contentLen = fileData.GetLength();
-   s4 entries = contentLen / SIZE_CONTAINERMAPRECORD;
-
-   vector<ContainerInfo> vContInfo;
-   for(int ctrIndex = 0; ctrIndex < entries; ++ctrIndex)
-   {
-      if(!(CMapFileGetFlag(fileData, ctrIndex) & 0x01))
-         continue;       // Skip not valid containers.
-
-      // Valid cmapfile entry for this ctrIndex
-      contMap[ctrIndex]._cmapEntry = true;
-
-      if(CMapFileGetSignSize(fileData, ctrIndex) || CMapFileGetExchSize(fileData, ctrIndex))
-      {
-         // Exchange
-         const CardCache::Container & cont = _cardCache->ReadContainer(ctrIndex);
-         u4 modulusLength = cont.exchModulus.GetLength();
-         if(modulusLength && CMapFileGetExchSize(fileData, ctrIndex) == modulusLength*8)
-         {
-            contMap[ctrIndex]._exchKP._modulus = cont.exchModulus;
-            contMap[ctrIndex]._exchKP._publicExponent = cont.exchPublicExponent;
-            contMap[ctrIndex]._exchKP._checkValue = Util::MakeCheckValue(cont.exchModulus.GetBuffer(), modulusLength);
-         }
-
-         // Signature
-         modulusLength = cont.signModulus.GetLength();
-         if(modulusLength && CMapFileGetSignSize(fileData, ctrIndex) == modulusLength*8)
-         {
-            contMap[ctrIndex]._signKP._modulus = cont.signModulus;
-            contMap[ctrIndex]._signKP._publicExponent = cont.signPublicExponent;
-            contMap[ctrIndex]._signKP._checkValue = Util::MakeCheckValue(cont.signModulus.GetBuffer(), modulusLength);
-         }
-      }
-   }
-}
-
-void Token::SynchronizeCertificates(vector<StorageObject*> & objects, map<int, ContainerInfo> & contMap)
-{
-   //Log::log("Synchronizing  Certificates...");
-
-   // Look for certificates in mscp that are not represented by P11 objects
-   for(map<int, ContainerInfo>::const_iterator icont = contMap.begin(); icont != contMap.end(); ++icont)
-   {
-      if(!icont->second._cmapEntry)
-         continue;   // Not corresponding to a valid cmapfile entry, ignore it.
-
-      u1 ctrIndex = static_cast<u1>(icont->first);
-
-      for(int ikeySpec = 0; ikeySpec < 2; ++ikeySpec)
-      {
-         u1 keySpec = (ikeySpec == 0) ? KEYSPEC_KEYEXCHANGE : KEYSPEC_SIGNATURE;
-         const KeyPair & keyPair = (ikeySpec == 0) ? icont->second._exchKP : icont->second._signKP;
-
-         // Certificates that have already been represented by object
-         // stored under p11 directory shall not be instantiated again.
-         if(keyPair._fP11CertExists)
-            continue;
-
-         if(keyPair._cert.GetLength())
-         {
-            if(!FindCertificate(objects, ctrIndex, keySpec))
-            {
-               //Log::log("Handling enrollement done from CSP...");
-
-               u8 checkValue = 0;
-               string strLabel;
-               BEROctet::Blob blId;
-               try
-               {
-                  CAttributedCertificate attrCert(keyPair._cert.GetBuffer(), keyPair._cert.GetLength());
-
-                  strLabel = attrCert.DerivedName();
-                  blId = attrCert.DerivedId();
-
-                  BEROctet::Blob modulus(attrCert.Modulus());
-                  checkValue = Util::MakeCheckValue(modulus.data(), static_cast<unsigned int>(modulus.size()));
-               }
-               catch(...)
-               {
-                  // Not valid X509 certificate, ignore it
-                  continue;
-               }
-
-               X509PubKeyCertObject* cert = new X509PubKeyCertObject();
-               cert->_value = new u1Array();
-               *cert->_value = keyPair._cert;
-               cert->_checkValue = checkValue;
-               cert->_certName = keyPair._certName;
-               cert->_keySpec = keySpec;
-               cert->_ctrIndex = ctrIndex;
-
-               cert->_tokenObject = CK_TRUE;
-               cert->_private = CK_FALSE;
-
-               cert->_label = new u1Array(static_cast<s4>(strLabel.size()));
-               cert->_label->SetBuffer(reinterpret_cast<const u1*>(strLabel.c_str()));
-
-               // If there is already a corresponding private key, assign
-               // the same id attribute, otherwise use the one derived from cert.
-               RSAPrivateKeyObject * priv = static_cast<RSAPrivateKeyObject*>(FindPrivateKey(objects, ctrIndex, keySpec));
-               if(priv && priv->_id->GetLength())
-               {
-                  cert->_id = new u1Array();
-                  *cert->_id = *priv->_id;
-               }
-               else
-               {
-                  cert->_id = new u1Array(static_cast<s4>(blId.size()));
-                  cert->_id->SetBuffer(reinterpret_cast<const u1*>(blId.c_str()));
-               }
-
-               // prepare object attributes from the parsed certificate
-               this->PrepareCertAttributesFromRawData(cert);
-
-               // Register this object
-               objects.push_back(cert);
-            }
-         }
-      }
-   }
-}
-
-void Token::SynchronizePrivateKeys(vector<StorageObject*> & objects, map<int, ContainerInfo> & contMap)
-{
-   //Log::log("Synchronizing  Private Keys...");
-
-   // Look for private keys in cmapfile that are not represented by P11 objects
-   for(map<int, ContainerInfo>::const_iterator icont = contMap.begin(); icont != contMap.end(); ++icont)
-   {
-      if(!icont->second._cmapEntry)
-         continue;   // Not corresponding to a valid cmapfile entry, ignore it.
-
-      u1 ctrIndex = static_cast<u1>(icont->first);
-
-      for(int ikeySpec = 0; ikeySpec < 2; ++ikeySpec)
-      {
-         u1 keySpec = (ikeySpec == 0) ? KEYSPEC_KEYEXCHANGE : KEYSPEC_SIGNATURE;
-         const KeyPair & keyPair = (ikeySpec == 0) ? icont->second._exchKP :  icont->second._signKP;
-
-         // Private keys that have already been represented by object
-         // stored under p11 directory shall not be instantiated again.
-         if(keyPair._fP11PrivKeyExists)
-            continue;
-
-         if(keyPair._checkValue)
-         {
-            if(!FindPrivateKey(objects, ctrIndex, keySpec))
-            {
-               //Log::log("Handling enrollement done from CSP...");
-
-               RSAPrivateKeyObject* priv = new RSAPrivateKeyObject();
-
-               // If there is a corresponding certificate, use its label, id and subject attribute
-
-               // TODO: Should check type before cast, however since there
-               // are no other certificate types than X509 here, this is safe
-               X509PubKeyCertObject * cert = static_cast<X509PubKeyCertObject*>(FindCertificate(objects, ctrIndex, keySpec));
-               if(cert)
-               {
-                  // If cert exist, inherit label and id from cert
-                  priv->_label = new u1Array();
-                  *priv->_label = *cert->_label;
-                  priv->_id = new u1Array();
-                  *priv->_id = *cert->_id;
-                  priv->_subject = new u1Array();
-                  *priv->_subject = *cert->_subject;
-               }
-               else
-               {
-                  BEROctet::Blob blId(CAttributedCertificate::DerivedId(keyPair._modulus.GetBuffer(),
-                     keyPair._modulus.GetLength()));
-                  priv->_id = new u1Array(static_cast<s4>(blId.size()));
-                  priv->_id->SetBuffer(blId.c_str());
-               }
-
-               priv->_ctrIndex = ctrIndex;
-               priv->_keySpec  = keySpec;
-               priv->_tokenObject = CK_TRUE;
-               priv->_private = CK_TRUE;
-               priv->_decrypt = CK_TRUE;
-               priv->_unwrap = CK_TRUE;
-               priv->_derive = CK_FALSE;
-               priv->_sign = CK_TRUE;
-               priv->_signRecover = CK_FALSE;
-               priv->_publicExponent = new u1Array();
-               *priv->_publicExponent = keyPair._publicExponent;
-               priv->_modulus = new u1Array();
-               *priv->_modulus = keyPair._modulus;
-               priv->_checkValue = keyPair._checkValue;
-
-               // add this in the token object list
-               objects.push_back(priv);
-            }
-         }
-      }
-   }
-}
-
-void Token::PrepareCertAttributesFromRawData(X509PubKeyCertObject* certObject)
-{
-
-   u1*           pCertValue = NULL;
-   unsigned long dwCertLen = 0;
-   u1Array*      sernbP = NULL;
-   u1Array*      issuerP = NULL;
-   u1Array*      subjectP = NULL;
-
-   pCertValue = certObject->_value->GetBuffer();
-   dwCertLen  = certObject->_value->GetLength();
-
-   // Parse Certifcate to extract SerNB, Issuer & Subject
-   // Create check value from modulus
-
-   try {
-      X509Cert x509cert(pCertValue, dwCertLen);
-
-      BEROctet::Blob blSerNum(x509cert.SerialNumber());
-      BEROctet::Blob blIssuer(x509cert.Issuer());
-      BEROctet::Blob blSubject(x509cert.Subject());
-      BEROctet::Blob modulus(x509cert.Modulus());
-
-      sernbP   = new u1Array(static_cast<s4>(blSerNum.size()));
-      sernbP->SetBuffer(const_cast<u1*>(blSerNum.data()));
-
-      issuerP  = new u1Array(static_cast<s4>(blIssuer.size()));
-      issuerP->SetBuffer(const_cast<u1*>(blIssuer.data()));
-
-      subjectP = new u1Array(static_cast<s4>(blSubject.size()));
-      subjectP->SetBuffer(const_cast<u1*>(blSubject.data()));
-
-      certObject->_serialNumber = sernbP;
-      certObject->_issuer       = issuerP;
-      certObject->_subject      = subjectP;
-   }
-   catch(...) {} // On parse error, these attributes can't be set.
-
-}
-
-
-CK_RV Token::AuthenticateUser(Marshaller::u1Array *pin)
-{
-   CK_RV rv = CKR_FUNCTION_NOT_SUPPORTED;
-
-   try
-   {
-      // first check if pin is locked or not
-      s4 triesRemaining = this->_mscm->GetTriesRemaining(CARD_ROLE_USER);
-
-      // blocked
-      if(triesRemaining == 0)
-      {
-         // update tokeninfo flahs
-         this->_tokenInfo.flags |= CKF_USER_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-
-         return CKR_PIN_LOCKED;
-      }
-
-      int iCase = howToAuthenticate( pin->GetLength( ) );
-      switch( iCase )
-      {
-      case AUTHENTICATE_REGULAR:
-         Log::log( "Token::AuthenticateUser - Normal login" );
-         this->_mscm->VerifyPin( CARD_ROLE_USER, pin );
-         rv = CKR_OK;
-         break;
-
-      case AUTHENTICATE_PINPAD:
-         Log::log( "Token::AuthenticateUser - PinPad" );
-         rv = verifyPinWithPinPad( );
-         break;
-
-      case AUTHENTICATE_BIO:
-#ifdef WIN32
-         Log::log( "Token::AuthenticateUser - BIO" );
-         rv = verifyPinWithBio( /*pin*/ );
-#else
-      Log::log( "Token::AuthenticateUser - BIO not supported !!" );
-      rv = CKR_FUNCTION_NOT_SUPPORTED;
-#endif
-         break;
-
-      default:
-         Log::log( "Token::AuthenticateUser - Unknown !!" );
-         rv = CKR_FUNCTION_NOT_SUPPORTED;
-         break;
-      }
-   }
-   catch(Marshaller::RemotingException&)
-   {
-      rv = CKR_TOKEN_NOT_PRESENT;
-   }
-   catch(Marshaller::UnauthorizedAccessException&)
-   {
-      rv = CKR_PIN_INCORRECT;
-   }
-   catch(std::runtime_error&)
-   {
-      rv = CKR_DEVICE_ERROR;
-   }
-
-   if( CKR_OK == rv )
-   {
-      this->_tokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
-      this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-      this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-      this->_roleLogged = CKU_USER;
-   }
-   else
-   {
-      // incorrect pin
-      s4 triesRemaining = this->_mscm->GetTriesRemaining(CARD_ROLE_USER);
-
-      // blocked
-      if(triesRemaining == 0)
-      {
-         // update tokeninfo flahs
-         this->_tokenInfo.flags |= CKF_USER_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-      }
-      else if(triesRemaining == 1)
-      {
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
-         this->_tokenInfo.flags |= CKF_USER_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_COUNT_LOW;
-      }
-      else if(triesRemaining < MAX_USER_PIN_TRIES)
-      {
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_USER_PIN_FINAL_TRY;
-         this->_tokenInfo.flags |= CKF_USER_PIN_COUNT_LOW;
-      }
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-BYTE Token::howToAuthenticate( BYTE bPinLen )
-{
-   BYTE bRet = AUTHENTICATE_REGULAR;
-
-   // Get the card mode (1=PIN, 2=FingerPrint, 3=PIN or FP, 4=PIN and FP)
-   // The default mode is PIN
-   //BYTE bCardMode = UVM_PIN_ONLY;
-   //BYTE bTypePIN = PIN_TYPE_REGULAR;
-   //getCardConfiguration( bCardMode, bTypePIN );
-   Log::log( "Token::AuthenticateUser - PIN type <%ld> (0 = regular ; 1 = external)", m_bTypePIN );
-   Log::log( "Token::AuthenticateUser - Card mode <%ld> (1 = pin only ; 2 = fp only ; 3 = fp or pin ; 4 = fp and pin)", m_bCardMode );
-   Log::log( "Token::AuthenticateUser - PIN len <%ld>", bPinLen );
-
-   if( PIN_TYPE_EXTERNAL == m_bTypePIN )
-   {
-      if( UVM_PIN_ONLY == m_bCardMode )
-      {
-         if( true == m_bIsPinPadSupported )
-         {
-            if( 0 == bPinLen )
-            {
-               Log::log( "Token::AuthenticateUser - External PIN && UVM1 && PINpad support && null len -> PIN pad" );
-               bRet = AUTHENTICATE_PINPAD;
-            }
-            else
-            {
-               Log::log( "Token::AuthenticateUser - External PIN && UVM1 && PINpad support && valid len -> PIN normal" );
-               bRet = AUTHENTICATE_REGULAR;
-            }
-         }
-         else
-         {
-            Log::log( "Token::AuthenticateUser - External PIN && UVM1 && NO PINpad support -> ERROR !!!" );
-            bRet = AUTHENTICATE_ERROR;
-         }
-      }
-      else
-      {
-         Log::log( "Token::AuthenticateUser - External PIN && (UVM2 || UVM3 || UVM4) -> Bio" );
-         bRet = AUTHENTICATE_BIO;
-      }
-   }
-   else
-   {
-      if( ( 0 != bPinLen ) && ( ( UVM_PIN_ONLY == m_bCardMode ) || ( UVM_PIN_OR_FP == m_bCardMode ) ) )
-      {
-         Log::log( "Token::AuthenticateUser - Regular PIN && (UVM1 || UVM3)  && valid len -> PIN normal" );
-         bRet = AUTHENTICATE_REGULAR;
-      }
-      else
-      {
-         Log::log( "Token::AuthenticateUser - Regular PIN && (UVM2 || UVM4)  && NO valid len -> ERROR !!!" );
-         bRet = AUTHENTICATE_ERROR;
-      }
-   }
-
-   return bRet;
-}
-
-
-CK_RV Token::AuthenticateAdmin(Marshaller::u1Array *pin)
-{
-   //Log::log("Logging as Admin...");
-
-   CK_RV rv = CKR_OK;
-
-   u1Array* challenge = NULL_PTR;
-   u1Array* response = NULL_PTR;
-
-   try{
-
-      // first check if pin is locked or not
-      s4 triesRemaining = this->_mscm->GetTriesRemaining(CARD_ROLE_ADMIN);
-
-      // blocked
-      if(triesRemaining == 0){
-         // update tokeninfo flahs
-         this->_tokenInfo.flags |= CKF_SO_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-
-         return CKR_PIN_LOCKED;
-      }
-
-      challenge = this->_mscm->GetChallenge();
-
-      response = this->ComputeCryptogram(challenge,pin);
-
-      this->_mscm->ExternalAuthenticate(response);
-
-      this->_roleLogged = CKU_SO;
-   }
-   catch(Marshaller::RemotingException&){
-      rv = CKR_TOKEN_NOT_PRESENT;
-   }
-   catch(Marshaller::UnauthorizedAccessException&){
-
-      // incorrect pin
-      s4 triesRemaining = this->_mscm->GetTriesRemaining(CARD_ROLE_ADMIN);
-
-      // blocked
-      if(triesRemaining == 0){
-         // update tokeninfo flahs
-         this->_tokenInfo.flags |= CKF_SO_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-      }else if(triesRemaining == 1){
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
-         this->_tokenInfo.flags |= CKF_SO_PIN_FINAL_TRY;
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_COUNT_LOW;
-      }else if(triesRemaining < MAX_SO_PIN_TRIES){
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_LOCKED;
-         this->_tokenInfo.flags &= ~CKF_SO_PIN_FINAL_TRY;
-         this->_tokenInfo.flags |= CKF_SO_PIN_COUNT_LOW;
-      }
-
-      return CKR_PIN_INCORRECT;
-
-   }
-   catch(std::runtime_error&)
-   {
-      rv = CKR_DEVICE_ERROR;
-   }
-
-   if(challenge != NULL_PTR)
-      delete challenge;
-
-   if(response != NULL_PTR)
-      delete response;
-
-   return rv;
-}
-
-CK_RV Token::Logout()
-{
-   CK_RV rv = CKR_OK;
-   
-   if(   ( true == m_bIsNoPinSupported ) 
-      || ( ( true == m_bIsSSO ) && ( true == this->isAuthenticated( ) ) )
-      )
-   {
-      this->_roleLogged = CKU_NONE;
-      return rv;
-   }
-
-   TOKEN_TRY
-   {
-      if(this->_roleLogged == CKU_NONE)
-      {
-         throw CkError(CKR_USER_NOT_LOGGED_IN);
-      }
-
-      this->_roleLogged = CKU_NONE;
-
-      u1 role = (this->_roleLogged == CKU_USER) ? CARD_ROLE_USER : CARD_ROLE_ADMIN;
-
-      try
-      {
-         // For the user
-         if( CARD_ROLE_USER == role )
-         {
-            // We log out if the SSO mode is not activated
-            if( false == m_bIsSSO )
-            {
-               this->_mscm->LogOut( role );
-            }
-         }
-         // For the admin
-         else
-         {
-            // We always log out
-            this->_mscm->LogOut( role );
-         }
-
-         //this->_roleLogged = CKU_NONE;
-      }
-      catch(Marshaller::RemotingException&)
-      {
-         rv = CKR_TOKEN_NOT_PRESENT;
-      }
-      catch(std::runtime_error&)
-      {
-         rv = CKR_DEVICE_ERROR;
-      }
-
-   }
-   TOKEN_CATCH(rv)
-
-      return rv;
-}
-
-CK_RV Token::Login(CK_ULONG userType,u1Array* pin)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      if(userType == CKU_USER){
-         if((this->_tokenInfo.flags & CKF_USER_PIN_INITIALIZED) != CKF_USER_PIN_INITIALIZED){
-            throw CkError(CKR_USER_PIN_NOT_INITIALIZED);
-         }
-
-         if(this->_roleLogged == CKU_SO){
-            throw CkError(CKR_USER_ANOTHER_ALREADY_LOGGED_IN);
-         }else if(this->_roleLogged == CKU_USER){
-            throw CkError(CKR_USER_ALREADY_LOGGED_IN);
-         }
-
-         rv =  AuthenticateUser(pin);
-
-      }else if(userType == CKU_SO){
-
-         if(this->_roleLogged == CKU_SO){
-            throw CkError(CKR_USER_ALREADY_LOGGED_IN);
-         }else if(this->_roleLogged == CKU_USER){
-            throw CkError(CKR_USER_ANOTHER_ALREADY_LOGGED_IN);
-         }
-
-         rv = AuthenticateAdmin(pin);
-      }
-      else
-         rv = CKR_USER_TYPE_INVALID;
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-
-/* SerializeTokenInfo
-*/
-void Token::SerializeTokenInfo()
-{
-
-   vector<u1> dataToSerialize;
-
-   // Version
-   Util::PushBBoolInVector(&dataToSerialize, _version);
-
-   // label
-   u1Array* label = new u1Array(32);
-   label->SetBuffer(this->_tokenInfo.label);
-   Util::PushByteArrayInVector(&dataToSerialize,label);
-   delete label;
-
-   // manufacturerId
-   u1Array* manuId = new u1Array(32);
-   manuId->SetBuffer(this->_tokenInfo.manufacturerID);
-   Util::PushByteArrayInVector(&dataToSerialize,manuId);
-   delete manuId;
-
-   // model
-   u1Array* model = new u1Array(16);
-   model->SetBuffer(this->_tokenInfo.model);
-   Util::PushByteArrayInVector(&dataToSerialize,model);
-   delete model;
-
-   // serial Number
-   u1Array* serialNumber = new u1Array(16);
-   serialNumber->SetBuffer(this->_tokenInfo.serialNumber);
-   Util::PushByteArrayInVector(&dataToSerialize,serialNumber);
-   delete serialNumber;
-
-   // rest of the tokenInfo struct (flags)
-   CK_FLAGS flags;
-
-   flags = this->_tokenInfo.flags;
-   flags &= ~CKF_PROTECTED_AUTHENTICATION_PATH;
-
-   Util::PushULongInVector(&dataToSerialize, flags);
-
-   std::string tinfo("p11\\tinfo");
-
-   u1Array objData((s4)dataToSerialize.size());
-
-   for(u4 i=0;i<dataToSerialize.size();i++){
-      objData.SetU1At(i,dataToSerialize.at(i));
-   }
-
-   //ManageGC( );
-
-   try
-   {
-      _cardCache->WriteFile(tinfo,objData);
-      RegisterFileUpdate();
-   }
-   catch( CkError x )
-   {
-      CK_RV rv = x.Error( );
-      Log::log( "## Error ## Token::SerializeTokenInfo - WriteFile failed <%ld>\n", rv );
-      throw;
-   }
-}
-
-void Token::DeserializeTokenInfo()
-{
-   std::string tinfo("p11\\tinfo");
-
-   const u1Array & fileData = this->_cardCache->ReadFile(tinfo);
-
-   vector<u1> from;
-   for(u4 u=0;u<fileData.GetLength();u++){
-      from.push_back(fileData.GetBuffer()[u]);
-   }
-
-   CK_ULONG idx = 0;
-
-   // Format version. Shall be 0 for this version
-   _version = Util::ReadBBoolFromVector(from,&idx);
-
-   // label
-   u1Array* label = Util::ReadByteArrayFromVector(from,&idx);
-   memcpy(this->_tokenInfo.label,label->GetBuffer(),label->GetLength());
-   delete label;
-
-   // manuid
-   u1Array* manuId = Util::ReadByteArrayFromVector(from,&idx);
-   memcpy(this->_tokenInfo.manufacturerID,manuId->GetBuffer(),manuId->GetLength());
-   delete manuId;
-
-   // model
-   u1Array* model = Util::ReadByteArrayFromVector(from,&idx);
-   memcpy(this->_tokenInfo.model,model->GetBuffer(),model->GetLength());
-   delete model;
-
-   // serial number
-   u1Array* serialNum = Util::ReadByteArrayFromVector(from,&idx);
-   memcpy(this->_tokenInfo.serialNumber,serialNum->GetBuffer(),serialNum->GetLength());
-
-   // Check MSCM's serial number. If this is larger than 8 bytes, do not
-   // use stored value since serial number may already have been truncated
-   // if the card was P11 enabled prior to this fix in revision 548361.
-
-   //Log::log( "Token::DeserializeTokenInfo - get serial numner" );
-   //u1Array* serialNumber = NULL;
-   //serialNumber = _mscm->GetCardProperty( CARD_SERIAL_NUMBER, 0 );
-   ////auto_ptr<u1Array> serialNumber(_mscm->get_SerialNumber());
-
-   //if(m_u1aSerialNumber->GetLength() > 8)
-   if(serialNum->GetLength() > 8)
-   {
-      CMD5 md5;
-      CK_BYTE hash[16];
-      md5.HashCore(serialNum->GetBuffer(), 0, serialNum->GetLength());
-      md5.HashFinal(hash);
-      Util::ConvAscii(hash, 8, _tokenInfo.serialNumber);
-   }
-
-   delete serialNum;
-   
-   //if( NULL != serialNumber )
-   //{
-   //   delete serialNumber;
-   //}
-
-   // flags
-   CK_FLAGS flags;
-
-   flags = this->_tokenInfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH;
-
-   this->_tokenInfo.flags = Util::ReadULongFromVector(from,&idx);
-
-   this->_tokenInfo.flags |= flags;
-}
-
-void Token::PopulateDefaultTokenInfo()
-{
-   CK_ULONG idx;
-
-   // initialize the token information
-
-   this->_version = 0;
-
-   for(idx=0;idx<32;idx++){
-      this->_tokenInfo.label[idx] = ' ';
-   }
-
-   this->_tokenInfo.label[0] = 'C';
-   this->_tokenInfo.label[1] = 'F';
-   this->_tokenInfo.label[2] = '.';
-   this->_tokenInfo.label[3] = 'N';
-   this->_tokenInfo.label[4] = 'E';
-   this->_tokenInfo.label[5] = 'T';
-   this->_tokenInfo.label[6] = ' ';
-   this->_tokenInfo.label[7] = 'P';
-   this->_tokenInfo.label[8] = '1';
-   this->_tokenInfo.label[9] = '1';
-
-   this->_tokenInfo.manufacturerID[0] = 'G';
-   this->_tokenInfo.manufacturerID[1] = 'e';
-   this->_tokenInfo.manufacturerID[2] = 'm';
-   this->_tokenInfo.manufacturerID[3] = 'a';
-   this->_tokenInfo.manufacturerID[4] = 'l';
-   this->_tokenInfo.manufacturerID[5] = 't';
-   this->_tokenInfo.manufacturerID[6] = 'o';
-
-   for(idx=7;idx<32;idx++){
-      this->_tokenInfo.manufacturerID[idx] = ' ';
-   }
-
-   this->_tokenInfo.model[0] = '.';
-   this->_tokenInfo.model[1] = 'N';
-   this->_tokenInfo.model[2] = 'E';
-   this->_tokenInfo.model[3] = 'T';
-   this->_tokenInfo.model[4] = ' ';
-   this->_tokenInfo.model[5] = 'C';
-   this->_tokenInfo.model[6] = 'a';
-   this->_tokenInfo.model[7] = 'r';
-   this->_tokenInfo.model[8] = 'd';
-
-   for(idx=9;idx<16;idx++){
-      this->_tokenInfo.model[idx] = ' ';
-   }
-
-   for(idx=0;idx<16;idx++){
-      this->_tokenInfo.serialNumber[idx] = ' ';
-   }
-
-   // If serial number length is too big to fit in 16 (hex) digit field,
-   // then use the 8 first bytes of MD5 hash of the original serial number.
-   Log::log( "Token::PopulateDefaultTokenInfo - get serial numner" );
-   u1Array* u1aSerialNumber = 0;
-   // Try first to load the serial number in a V2+ way
-   try
-   {
-      u1aSerialNumber = _mscm->GetCardProperty( CARD_SERIAL_NUMBER, 0 );
-   }
-   catch( ... )
-   {
-      u1aSerialNumber = 0;
-   }
-   // Try at last to get the serial number in a old V2 way
-   if( 0 == u1aSerialNumber )
-   {
-      u1aSerialNumber = _mscm->get_SerialNumber( );
-   }
-
-   //auto_ptr<u1Array> serialNumber(_mscm->get_SerialNumber());
-   if(u1aSerialNumber->GetLength() > 8)
-   {
-      CMD5 md5;
-      CK_BYTE hash[16];
-      md5.HashCore(u1aSerialNumber->GetBuffer(), 0, u1aSerialNumber->GetLength());
-      md5.HashFinal(hash);
-      Util::ConvAscii(hash, 8, _tokenInfo.serialNumber);
-   }
-   else
-      Util::ConvAscii(u1aSerialNumber->GetBuffer(),u1aSerialNumber->GetLength(),this->_tokenInfo.serialNumber);
-
-   if( NULL != u1aSerialNumber )
-   {
-      delete u1aSerialNumber;
-   }
-}
-
-CK_RV Token::GenerateRandom(CK_BYTE_PTR randomData,CK_ULONG len)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      // usng the challenge as the random data
-      u1Array* random = NULL_PTR;
-
-      random = this->_mscm->GetChallenge();
-
-      // now requested length can be more or less than the
-      // 8 bytes which challenge generates.
-      CK_ULONG minLen = len < 8 ? len : 8;
-      memcpy(randomData,random->GetBuffer(),minLen);
-
-      // lets put soft ramdom as the rest of the bytes
-      unsigned int uSeed;
-
-      memcpy((BYTE *)&uSeed, random->GetBuffer(), sizeof(unsigned int));
-      srand(uSeed);
-
-      if(len > 8)
-      {
-         for(u4 i=8;i<len;i++)
-         {
-            randomData[i] = (BYTE)(rand() % RAND_MAX);
-         }
-      }
-
-      delete random;
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_ULONG Token::FindObjects(Session* session,CK_OBJECT_HANDLE_PTR phObject,
-                            CK_ULONG ulMaxObjectCount,CK_ULONG_PTR  pulObjectCount)
-{
-   CK_RV rv = CKR_OK;
-   CK_ULONG idx = 0;
-   TOKEN_TRY
-   {
-
-      for(s4 i=0;(i < static_cast<s4>(_objects.size())) && (idx < ulMaxObjectCount);i++){
-
-         if(this->_objects[i] == NULL_PTR){
-            continue;
-         }
-
-         if(session->_tokenObjectsReturnedInSearch[i+1]){
-            continue;
-         }
-
-         if( this->_objects[ i ]->_private == CK_TRUE )
-         {
-            if( false == m_bIsNoPinSupported )
-            {
-               if(   ( CKU_USER != _roleLogged )
-                  && ( ( true == m_bIsSSO ) && ( false == isAuthenticated( ) ) )
-                  )
-               {
-                  continue;
-               }
-            }
-         }
-         //if((this->_objects[i]->_private == CK_TRUE) &&
-         //   (this->_roleLogged != CKU_USER))
-         //{
-         //   continue;
-         //}
-
-         if(session->_searchTempl == NULL_PTR){
-            phObject[idx++] = CO_TOKEN_OBJECT | (i+1);
-            *pulObjectCount = *pulObjectCount + 1;
-            session->_tokenObjectsReturnedInSearch[i+1] = true;
-         }
-         else{
-            CK_BBOOL match = CK_TRUE;
-
-            vector<CK_ATTRIBUTE> attributes = session->_searchTempl->_attributes;
-            for(CK_ULONG a=0;a<attributes.size();a++){
-               if(this->_objects[i]->Compare(attributes.at(a)) == CK_FALSE){
-                  match = CK_FALSE;
-                  break;
-               }
-            }
-
-            if(match == CK_TRUE){
-               phObject[idx++] = CO_TOKEN_OBJECT | (i+1);
-               *pulObjectCount = *pulObjectCount + 1;
-               session->_tokenObjectsReturnedInSearch[i+1] = true;
-            }
-         }
-      }
-   }
-   TOKEN_CATCH(rv)
-      return idx;
-}
-
-
-string Token::FindFreeFileName(StorageObject* object)
-{
-   std::string fileName(object->_private ? "pri" : "pub");
-
-   switch(object->_class){
-        case CKO_DATA:
-           fileName.append("dat");
-           break;
-
-        case CKO_PUBLIC_KEY:
-           fileName.append("puk");
-           break;
-
-        case CKO_PRIVATE_KEY:
-           fileName.append("prk");
-           break;
-
-        case CKO_CERTIFICATE:
-           fileName.append(((X509PubKeyCertObject*)object)->_certName);
-           break;
-
-        case CKO_SECRET_KEY:
-           fileName.append("sec");
-           break;
-
-        default:
-           throw CkError(CKR_FUNCTION_FAILED);
-   }
-
-   if(object->_class != CKO_CERTIFICATE)
-   {
-
-
-      // Find free name
-      map<CK_LONG, bool> occupied;
-
-      if(_initialized)
-      {
-         // get the file names in above dir
-         vector<string> files(_cardCache->FileList("p11"));
-
-         for(u4 i=0;i<files.size();i++)
-         {
-            std::string fn(files[i]);
-            if(fn.find(fileName) == 0)
-            {
-               CK_LONG idx = atoi(fn.substr(fileName.size(), 2).c_str());
-               occupied[idx] = true;
-            }
-         }
-      }
-
-      s4 i = 0;
-      while(occupied.find(i) != occupied.end())
-         i++;
-      fileName.append(Util::MakeIntString(i, 2));
-   }
-
-   return fileName;
-
-}
-
-
-/* WriteObject
-*/
-CK_RV Token::WriteObject( StorageObject* object )
-{
-   //ManageGC( );
-
-   CK_RV rv = CKR_OK;
-
-   std::string fileName( "p11\\" + FindFreeFileName( object ) );
-
-   // This object is stored under p11 directory, assign a unique ID for future identification.
-   object->_uniqueId = Util::MakeUniqueId( );
-
-   vector<u1> to;
-   object->Serialize( &to );
-
-   u1Array objData( (s4)to.size( ) );
-   for( u4 i = 0 ; i < to.size( ) ; i++ )
-   {
-      objData.SetU1At( i, to.at( i ) );
-   }
-
-   u1Array acls( 3 );
-   acls.GetBuffer( )[ 0 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // admin acl
-   acls.GetBuffer( )[ 1 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // usr acl
-
-   if( object->_private )
-   {
-      acls.GetBuffer( )[ 2 ] = 0; // everyone acl
-   }
-   else
-   {
-      // public objects can be written or read by everyone provide the session is correct
-
-      // NOTE: Breaking PKCS#11 Compliance
-      // In the card you can not create public objects unless you are logged in
-      // even for R/W Pulblic session
-
-      acls.GetBuffer( )[ 2 ] = CARD_PERMISSION_READ; // everyone acl
-   }
-
-   if( !_initialized )
-   {
-      Initialize( );
-   }
-
-   _cardCache->ClearFileList( "p11" );
-
-   // No try/catch. It is managed by the calling method.
-   //ManageGC( );
-   this->_mscm->CreateFile( &fileName, &acls, 0 );
-
-   try
-   {
-      //ManageGC( );
-      this->_cardCache->WriteFile( fileName, objData );
-
-      RegisterFileUpdate( );
-      object->_fileName = fileName;
-   }
-   catch( CkError x )
-   {
-      rv = x.Error( );
-      Log::log( "## ERROR ## Token::WriteObject - WriteFile failed <%ld>\n", rv );
-   }
-
-   if( CKR_OK != rv )
-   {
-      try
-      {
-         _mscm->DeleteFile( &fileName );
-      }
-      catch( ... )
-      {
-         Log::log( "## ERROR ## Token::WriteObject - DeleteFile failed\n" );
-      }
-   }
-
-   return rv;
-}
-
-
-CK_RV Token::AddObject(auto_ptr<StorageObject> & stobj, CK_OBJECT_HANDLE_PTR phObject)
-{
-   //ManageGC();
-
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      CK_RV rv = WriteObject(stobj.get());
-      if(rv == CKR_OK)
-      {
-         *phObject = CO_TOKEN_OBJECT | RegisterStorageObject(stobj.get());
-         stobj.release();
-      }
-   }
-   TOKEN_CATCH(rv)
-   //ManageGC( true );
-      return rv;
-}
-
-
-/* AddPrivateKeyObject
-*/
-CK_RV Token::AddPrivateKeyObject( auto_ptr< StorageObject > &stobj, CK_OBJECT_HANDLE_PTR phObject )
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      RSAPrivateKeyObject *object = static_cast< RSAPrivateKeyObject* >( stobj.get( ) );
-      if( !object->_private )
-      {
-         throw CkError( CKR_ATTRIBUTE_VALUE_INVALID );
-      }
-
-      // Public key modulus is mandatory, so unless provided by the template,
-      // see if there is a public key with matching CKA_ID. Otherwise return
-      // CKR_TEMPLATE_INCOMPLETE.
-
-      RSAPublicKeyObject* rsaPub = NULL_PTR;
-      if( !object->_modulus )
-      {
-         // Search for corresponding public key to make criteria that is used here is to match the CKA_ID
-         CK_BBOOL foundPub = CK_FALSE;
-         for( s4 i = 0 ; i < static_cast< s4 >( _objects.size( ) ) ; i++ )
-         {
-            if( this->_objects[ i ] != NULL_PTR )
-            {
-               if( this->_objects[ i ]->_class == CKO_PUBLIC_KEY )
-               {
-                  rsaPub = (RSAPublicKeyObject*)this->_objects[ i ];
-                  foundPub = Util::CompareByteArrays( rsaPub->_id->GetBuffer( ), object->_id->GetBuffer( ), rsaPub->_id->GetLength( ) );
-                  if( foundPub == CK_TRUE )
-                  {
-                     break;
-                  }
-               }
-            }
-         }
-
-         if( !foundPub )
-         {
-            throw CkError(CKR_TEMPLATE_INCOMPLETE); // Sorry, now other choice...
-         }
-      }
-
-      u1Array publExp;
-      u4 modLength = 0;
-      if( object->_modulus != NULL_PTR )
-      {
-         publExp = *object->_publicExponent;
-         modLength = object->_modulus->GetLength( );
-         object->_checkValue = Util::MakeCheckValue( object->_modulus->GetBuffer( ), modLength );
-      }
-      else
-      {
-         PKCS11_ASSERT( rsaPub );
-         publExp = *rsaPub->_exponent;
-         modLength = rsaPub->_modulus->GetLength();
-         object->_checkValue = Util::MakeCheckValue(rsaPub->_modulus->GetBuffer(), modLength);
-      }
-      if(publExp.GetLength() < 1 || publExp.GetLength() > 4)
-         throw CkError(CKR_ATTRIBUTE_VALUE_INVALID);
-
-      if( (modLength*8 < RSA_KEY_MIN_LENGTH) ||
-         (modLength*8 > RSA_KEY_MAX_LENGTH) )
-         throw CkError(CKR_ATTRIBUTE_VALUE_INVALID);
-
-      if(publExp.GetLength() < 4)
-      {
-         // Pad with zeros in the front since big endian
-         u1Array exp(4);
-         memset(exp.GetBuffer(), 0, exp.GetLength());
-         size_t i = 4 - publExp.GetLength();
-         memcpy(exp.GetBuffer()+i, publExp.GetBuffer(), publExp.GetLength());
-         publExp = exp;
-      }
-
-      // Look for existing matching certificate
-      // First, read the container map record file
-      std::string  nameCMapFile("mscp\\cmapfile");
-      const u1Array & fileData(_cardCache->ReadFile(nameCMapFile));
-
-      object->_keySpec = KEYSPEC_KEYEXCHANGE;   // Default
-
-      // NOTE: If it finds a matching certificate, the keySpec
-      // will be modified to match that of the certificate.
-      CK_BYTE ctrIdx = GetContainerForPrivateKey(fileData, object->_checkValue, &object->_keySpec);
-      if(ctrIdx > 99)
-      {
-         Log::error( "Token::AddPrivateKeyObject", "ctrIdx > 99 - Return CKR_DEVICE_MEMORY" );
-         throw CkError(CKR_DEVICE_MEMORY);
-      }
-      object->_ctrIndex = ctrIdx;
-
-      auto_ptr<u1Array> keyValue;
-
-      if( ( object->_modulus->GetLength( ) / 2 ) != object->_inverseQ->GetLength( ) )
-      {
-         // Pad with zeros in the front since big endian
-         u1Array val( (s4)( object->_modulus->GetLength( ) / 2 ) );
-         memset( val.GetBuffer( ), 0, val.GetLength( ) );
-         size_t i = val.GetLength( )- object->_inverseQ->GetLength( );
-         memcpy( val.GetBuffer( ) + i, object->_inverseQ->GetBuffer(), object->_inverseQ->GetLength( ) );
-         *(object->_inverseQ) = val;
-      }
-
-      // compute the total length;
-      s4 keyLength = object->_p->GetLength() +
-         object->_q->GetLength() +
-         object->_inverseQ->GetLength() +
-         object->_dp->GetLength() +
-         object->_dq->GetLength() +
-         object->_d->GetLength();
-
-      if(object->_modulus != NULL_PTR){
-         keyLength += object->_modulus->GetLength();
-         //keyLength += object->_publicExponent->GetLength();
-         keyLength += 4; // public exponent expected by card is on 4 bytes
-      }else{
-         keyLength += rsaPub->_modulus->GetLength();
-         //keyLength += rsaPub->_exponent->GetLength();
-         keyLength += 4; // public exponent expected by card is on 4 bytes
-      }
-
-      s4 offset = 0;
-
-      // Prepare the keyValue
-      keyValue = auto_ptr<u1Array>(new u1Array(keyLength));
-      memset(keyValue->GetBuffer(),0,keyValue->GetLength()); // let's zeroed it
-
-      memcpy(keyValue->GetBuffer(),object->_p->GetBuffer(),object->_p->GetLength());
-
-      offset += object->_p->GetLength();
-
-      memcpy((u1*)&keyValue->GetBuffer()[offset],object->_q->GetBuffer(),object->_q->GetLength());
-
-      offset += object->_q->GetLength();
-
-      memcpy((u1*)&keyValue->GetBuffer()[offset],object->_inverseQ->GetBuffer(),object->_inverseQ->GetLength());
-
-      offset += object->_inverseQ->GetLength();
-
-      memcpy((u1*)&keyValue->GetBuffer()[offset],object->_dp->GetBuffer(),object->_dp->GetLength());
-
-      offset += object->_dp->GetLength();
-
-      memcpy((u1*)&keyValue->GetBuffer()[offset],object->_dq->GetBuffer(),object->_dq->GetLength());
-
-      offset += object->_dq->GetLength();
-
-      memcpy((u1*)&keyValue->GetBuffer()[offset],object->_d->GetBuffer(),object->_d->GetLength());
-
-      offset += object->_d->GetLength();
-
-      u4 modulusLen = 0;
-
-      string contName;
-      if(object->_modulus != NULL_PTR){
-
-         memcpy((u1*)&keyValue->GetBuffer()[offset],object->_modulus->GetBuffer(),object->_modulus->GetLength());
-
-         offset += object->_modulus->GetLength();
-
-         memcpy((u1*)&keyValue->GetBuffer()[offset],publExp.GetBuffer(),publExp.GetLength());
-
-         modulusLen = object->_modulus->GetLength();
-
-         contName = CAttributedCertificate::DerivedUniqueName(object->_modulus->GetBuffer(),
-            object->_modulus->GetLength());
-
-      }else{
-
-         memcpy((u1*)&keyValue->GetBuffer()[offset],rsaPub->_modulus->GetBuffer(),rsaPub->_modulus->GetLength());
-
-         offset += rsaPub->_modulus->GetLength();
-
-         memcpy((u1*)&keyValue->GetBuffer()[offset],publExp.GetBuffer(),publExp.GetLength());
-
-         modulusLen = rsaPub->_modulus->GetLength();
-
-         contName = CAttributedCertificate::DerivedUniqueName(rsaPub->_modulus->GetBuffer(),
-            rsaPub->_modulus->GetLength());
-
-      }
-
-      //try
-      //{
-      this->_cardCache->ClearContainer(ctrIdx);  // Invalidate cache
-      //this->_mscm->CreateCAPIContainer(ctrIdx,CK_TRUE,object->_keySpec,(modulusLen*8),keyValue.get());
-      int ntry = 0;
-      while( ntry < MAX_RETRY )
-      {
-         try
-         {
-            //ManageGC( );
-            ntry++;
-            this->_mscm->CreateCAPIContainer(ctrIdx,CK_TRUE,object->_keySpec,(modulusLen*8),keyValue.get());
-            break;
-         }
-         catch( Marshaller::Exception & x )
-         {
-            CK_RV rv = CkError::CheckMarshallerException( x );
-            if( CKR_DEVICE_MEMORY == rv )
-            {
-               Log::error( "Token::AddPrivateKeyObject", "ForceGarbageCollector" );
-               _mscm->ForceGarbageCollector( );
-               if( ntry >= MAX_RETRY )
-               {
-                  Log::error( "Token::AddPrivateKeyObject", "Throw Exception CKR_DEVICE_MEMORY" );
-                  throw CkError( rv );
-               }
-            }
-            else
-            {
-               throw CkError( rv );
-            }
-         }
-      }
-
-      this->RegisterContainerUpdate();
-      /*}
-      catch(...)
-      {
-      Log::error( "Token::AddPrivateKeyObject", "ctrIdx > 99 - Return CKR_DEVICE_MEMORY" );
-
-      throw CkError(CKR_DEVICE_MEMORY);
-      }*/
-
-      object->_ctrIndex = ctrIdx;
-
-      rv = this->AddObject(stobj,phObject);
-      if(rv == CKR_OK)
-      {
-         try
-         {
-            auto_ptr<u1Array> newCMap( UpdateCMap( ctrIdx, fileData, (modulusLen*8), object->_keySpec, CK_TRUE, contName ) );
-            this->_cardCache->WriteFile( nameCMapFile, *newCMap );
-            this->RegisterFileUpdate( );
-         }
-         catch( CkError x )
-         {
-            rv = x.Error( );
-            Log::log( "## Error ## Token::AddPrivateKeyObject - WriteFile <%ld>\n", rv );
-
-            try
-            {
-               DeleteObject( *phObject );
-            }
-            catch( ... )
-            {
-            }
-
-            throw CkError( rv );
-         }
-      }
-   }
-   TOKEN_CATCH( rv )
-   //ManageGC( true );
-
-      return rv;
-}
-
-
-/* DeleteCMapRecord
-*/
-void Token::DeleteCMapRecord( CK_BYTE ctrIndex )
-{
-   // Read the container map record file
-   std::string nameCMapFile( "mscp\\cmapfile" );
-
-   try
-   {
-      u1Array fileData( _cardCache->ReadFile( nameCMapFile ) );
-
-      s4 entries = ( fileData.GetLength( ) / SIZE_CONTAINERMAPRECORD );
-      if( ctrIndex >= entries )
-      {
-         return; // Silently ignore if doesn't exist
-      }
-
-      // Nullify the entries at ctrIndex
-      CMapFileClear( fileData, ctrIndex );
-
-      // Set default container
-      SetDefaultContainer( fileData, 0xFF );
-
-      //ManageGC( );
-
-      // Write the updated content back to cmap
-      this->_cardCache->WriteFile( nameCMapFile, fileData );
-      this->RegisterFileUpdate( );
-   }
-   catch( CkError x )
-   {
-      /*CK_RV rv =*/ x.Error( );
-      Log::error( "Token::DeleteCMapRecord", "WriteFile failed" );
-      throw;
-   }
-   /*
-   catch(Marshaller::RemotingException&){
-   // TBD
-   }
-   catch(Marshaller::UnauthorizedAccessException&){
-   // TBD
-   }
-   catch(std::runtime_error&){
-   // TBD
-   }
-   */
-}
-
-void Token::RemoveKeyFromCMapRecord(CK_BYTE ctrIndex, u1 keySpec)
-{
-
-   try{
-      // read the container map record file
-      std::string nameCMapFile("mscp\\cmapfile");
-      u1Array fileData(_cardCache->ReadFile(nameCMapFile));
-
-      s4 entries = (fileData.GetLength() / SIZE_CONTAINERMAPRECORD);
-      if(ctrIndex >= entries)
-      {
-         PKCS11_ASSERT(0);
-         return; // Silently ignore if doesn't exist
-      }
-
-      // Clear the key size corresponding to keyspec
-      if(keySpec == KEYSPEC_KEYEXCHANGE)
-         CMapFileSetExchSize(fileData, ctrIndex, 0);
-      else if(keySpec == KEYSPEC_SIGNATURE)
-         CMapFileSetSignSize(fileData, ctrIndex, 0);
-      else
-         return;  // unknown key spec
-
-      //ManageGC();
-
-      // now write the updated content back to cmap
-      this->_cardCache->WriteFile(nameCMapFile,fileData);
-      this->RegisterFileUpdate();
-
-   }
-   catch( CkError x )
-   {
-      /*CK_RV rv =*/ x.Error( );
-      Log::error( "Token::RemoveKeyFromCMapRecord", "WriteFile failed" );
-   }
-   /*
-   catch(Marshaller::RemotingException&){
-   // TBD
-   }
-   catch(Marshaller::UnauthorizedAccessException&){
-   // TBD
-   }
-   catch(std::runtime_error&){
-   // TBD
-   }
-   */
-}
-
-void Token::SetDefaultContainer(u1Array & contents, CK_BYTE ctrIndex)
-{
-
-   s4 entries = (contents.GetLength() / SIZE_CONTAINERMAPRECORD);
-
-   if(ctrIndex == 0xFF)
-   {
-      for (s4 i=0;i<entries;i++)
-      {
-         if((CMapFileGetFlag(contents, i) & 0x03) == 0x03)
-            return;  // A valid container already default, finished
-      }
-
-      // Find first best suitable. Look for one with keys
-      for (s4 i=0;i<entries;i++)
-      {
-         u1 flags = CMapFileGetFlag(contents, i);
-         if((flags & 0x01) && (CMapFileGetExchSize(contents, i) || CMapFileGetSignSize(contents, i)))
-         {
-            CMapFileSetFlag(contents, i, (flags | 0x02));
-            return;
-         }
-      }
-
-      // If no container with keys, then assign any valid container as default
-      for (s4 i=0;i<entries;i++)
-      {
-         u1 flags = CMapFileGetFlag(contents, i);
-         if(flags & 0x01)
-         {
-            CMapFileSetFlag(contents, i, (flags | 0x02));
-            return;
-         }
-      }
-   }
-   else
-   {
-      // Assign specific container as default
-      PKCS11_ASSERT(ctrIndex < entries);
-      if(ctrIndex >= entries)
-         return;
-      // Remove existing default container
-      for (s4 i=0;i<entries;i++)
-      {
-         u1 flags = CMapFileGetFlag(contents, i);
-         CMapFileSetFlag(contents, i, (flags & ~0x02));
-      }
-      CMapFileSetFlag(contents, ctrIndex, CMapFileGetFlag(contents, ctrIndex) | 0x02);
-   }
-}
-
-CK_RV Token::AddCertificateObject(auto_ptr<StorageObject> & stobj, CK_OBJECT_HANDLE_PTR phObject)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      X509PubKeyCertObject * object = static_cast<X509PubKeyCertObject*>(stobj.get());
-
-      if(object->_private)
-         throw CkError(CKR_ATTRIBUTE_VALUE_INVALID);
-
-      //CheckAvailableSpace();
-
-      // Make check value and look for possibly existing private key(s)
-
-      BEROctet::Blob modulus;
-      try
-      {
-         X509Cert x509cert(object->_value->GetBuffer(), object->_value->GetLength());
-         modulus =x509cert.Modulus();
-      }
-      catch(...)
-      {
-         throw CkError(CKR_ATTRIBUTE_VALUE_INVALID);
-      }
-
-      object->_checkValue   = Util::MakeCheckValue(modulus.data(), static_cast<unsigned int>(modulus.size()));
-      string contName(CAttributedCertificate::DerivedUniqueName(modulus));
-
-      std::string nameCMapFile("mscp\\cmapfile");
-      const u1Array & fileData(_cardCache->ReadFile(nameCMapFile));
-
-      object->_keySpec = KEYSPEC_KEYEXCHANGE;   // Default
-
-      // NOTE: If it finds a matching private key, the keySpec
-      // will be modified to match that of the private key.
-      CK_BYTE ctrIdx = GetContainerForCert(fileData, object->_checkValue, &object->_keySpec);
-      if(ctrIdx > 99)
-      {
-         Log::error( "Token::AddCertificateObject", "ctrIdx > 99 - Return CKR_DEVICE_MEMORY" );
-
-         throw CkError(CKR_DEVICE_MEMORY);
-      }
-      object->_ctrIndex = ctrIdx;
-
-      if(object->_keySpec == KEYSPEC_KEYEXCHANGE)
-         object->_certName = "kxc";
-      else
-         object->_certName = "ksc";
-      object->_certName.append(Util::MakeIntString(ctrIdx, 2));
-
-      string fileName("mscp\\");
-      fileName.append(object->_certName);
-
-      unsigned long ccLen = object->_value->GetLength();
-      autoarray<u1> cc(new u1[ccLen+4]);
-
-      cc[0] = 0x01;
-      cc[1] = 0x00;
-      cc[2] = BITS_0_7(ccLen);
-      cc[3] = BITS_8_15(ccLen);
-
-      // compress the certificate
-      //         compress((u1*)&cc[4],&ccLen,object->_value->GetBuffer(),ccLen);
-      compress2((u1*)&cc[4],&ccLen,object->_value->GetBuffer(),ccLen, 6); // Set level=6, same as Minidriver
-
-      auto_ptr<u1Array> compressedCert(new u1Array((ccLen + 4)));
-      compressedCert->SetBuffer(cc.get());
-
-      auto_ptr<u1Array> acls(new u1Array(3));
-      acls->GetBuffer()[0] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // admin acl
-      acls->GetBuffer()[1] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // usr acl
-      acls->GetBuffer()[2] = CARD_PERMISSION_READ; // everyone acl
-
-      //ManageGC();
-
-      _cardCache->ClearFileList("mscp");
-      this->_mscm->CreateFile(&fileName,acls.get(),0);
-      try
-      {
-         this->_cardCache->WriteFile(fileName,*compressedCert);
-         this->RegisterFileUpdate();
-      }
-      catch( CkError x )
-      {
-         rv = x.Error( );
-         Log::error( "Token::AddCertificateObject", "WriteFile failed" );
-      }
-
-      if( CKR_OK != rv )
-      {
-         try
-         {
-            _mscm->DeleteFile( &fileName );
-         }
-         catch( ... )
-         {
-         }
-
-         throw CkError( rv );
-      }
-
-      rv = AddObject(stobj ,phObject);
-      if(rv == CKR_OK)
-      {
-         //ManageGC();
-
-         try
-         {
-            auto_ptr<u1Array> newCMap(UpdateCMap(ctrIdx,fileData, contName));
-            _cardCache->WriteFile(nameCMapFile,*newCMap);
-            RegisterFileUpdate();
-         }
-         catch( CkError x )
-         {
-            rv = x.Error( );
-            Log::error( "Token::AddCertificateObject", "WriteFile 2 failed" );
-         }
-
-         if( CKR_OK != rv )
-         {
-            try
-            {
-               _mscm->DeleteFile( &fileName );
-            }
-            catch( ... )
-            {
-            }
-
-            try
-            {
-               DeleteObject( *phObject );
-            }
-            catch( ... )
-            {
-            }
-
-            throw CkError( rv );
-         }
-      }
-   }
-   TOKEN_CATCH(rv)
-   
-      //ManageGC( true );
-      return rv;
-}
-
-CK_RV Token::DeleteObject( CK_OBJECT_HANDLE hObject )
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      StorageObject * obj = GetObject(hObject);
-
-      // some more checks
-      if( CK_TRUE == obj->_private )
-      {
-         if( false == m_bIsNoPinSupported )
-         {
-            if(   ( CKU_USER != _roleLogged )
-               && ( ( true == m_bIsSSO ) && ( false == isAuthenticated( ) ) )
-               )
-            {
-               throw CkError(CKR_USER_NOT_LOGGED_IN);
-            }
-         }
-      }
-      //if((this->_roleLogged != CKU_USER) && (obj->_private == CK_TRUE)){
-      //   throw CkError(CKR_USER_NOT_LOGGED_IN);
-      //}
-
-      if(obj->_class == CKO_CERTIFICATE){
-
-         //Log::log("Deleting the certificate.");
-
-         CertificateObject * cert = static_cast<CertificateObject*>(obj);
-         CK_BYTE ctrIdx = cert->_ctrIndex;
-
-         if(ctrIdx != 0xFF){
-
-            // Delete the file under mscp
-
-            string fileName("mscp\\");
-            fileName.append(cert->_certName);
-            _cardCache->ClearFile(fileName);
-            try
-            {
-               _cardCache->ClearFileList("mscp");
-               _mscm->DeleteFile(&fileName);
-               RegisterFileUpdate();
-            }
-            catch(FileNotFoundException &) {}
-
-            // Check if there exist private key(s) or other
-            // certificate (with different key spec) in the container
-            u1 otherKeySpec = (cert->_keySpec == KEYSPEC_KEYEXCHANGE) ? KEYSPEC_SIGNATURE : KEYSPEC_KEYEXCHANGE;
-
-            bool fOtherCertExist = (FindCertificate(_objects, ctrIdx, otherKeySpec) != 0);
-
-            bool fPrivKeysExist = false;
-            if(FindPrivateKey(_objects, ctrIdx, KEYSPEC_KEYEXCHANGE) || FindPrivateKey(_objects, ctrIdx, KEYSPEC_SIGNATURE))
-               fPrivKeysExist = true;
-
-            // If there are no longer any objects associated with this
-            // container, then free this CMap record
-            if(!fOtherCertExist && !fPrivKeysExist)
-            {
-               //Log::log("Deleting container ",ctrIdx);
-               DeleteCMapRecord(ctrIdx);
-            }
-         }
-      }
-      if(obj->_class == CKO_PRIVATE_KEY){
-
-         //Log::log("Deleting the private key.");
-
-         RSAPrivateKeyObject * privKey = static_cast<RSAPrivateKeyObject*>(obj);
-         CK_BYTE ctrIdx = privKey->_ctrIndex;
-
-         if(ctrIdx != 0xFF){
-
-
-            // Check if there exist certificate(s) or other
-            // private key (with different key spec) in the container
-            u1 otherKeySpec = (privKey->_keySpec == KEYSPEC_KEYEXCHANGE) ? KEYSPEC_SIGNATURE : KEYSPEC_KEYEXCHANGE;
-
-            bool fOtherKeyExist = (FindPrivateKey(_objects, ctrIdx, otherKeySpec) != 0);
-
-            bool fCertsExist = false;
-            if(FindCertificate(_objects, ctrIdx, KEYSPEC_KEYEXCHANGE) || FindCertificate(_objects, ctrIdx, KEYSPEC_SIGNATURE))
-               fCertsExist = true;
-
-            if(fOtherKeyExist)
-            {
-               // To not delete the other key, overwrite this one with dummy data
-               // TODO
-               // this->_mscm->CreateCAPIContainer(ctrIdx,.....);
-               RegisterContainerUpdate();
-            }
-            else
-            {
-               _cardCache->ClearContainer(ctrIdx);   // Invalidate cache
-               _mscm->DeleteCAPIContainer(ctrIdx);
-               RegisterContainerUpdate();
-            }
-
-            // Check if the record in cmapfile shall be cleared,
-            // depending on if there are other keys in it.
-            // empty the corresponding record in cmapfile
-
-            if(fOtherKeyExist || fCertsExist)
-            {
-               //Log::log("Removing key from container ",ctrIdx);
-               RemoveKeyFromCMapRecord(ctrIdx, privKey->_keySpec);
-            }
-            else
-            {
-               //Log::log("Deleting container ",ctrIdx);
-               DeleteCMapRecord(ctrIdx);
-            }
-         }
-      }
-
-      // delete the file from card
-      if(!obj->_fileName.empty())
-      {
-         _cardCache->ClearFile(obj->_fileName);
-         try
-         {
-            _cardCache->ClearFileList("p11");
-            this->_mscm->DeleteFile(&obj->_fileName);
-            this->RegisterFileUpdate();
-         }
-         catch(FileNotFoundException &) {}
-      }
-
-      UnregisterStorageObject(obj);
-      delete obj;
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::GetAttributeValue(CK_OBJECT_HANDLE hObject,
-                               CK_ATTRIBUTE_PTR pTemplate,
-                               CK_ULONG ulCount)
-{
-   CK_RV rv  = CKR_OK;
-   CK_RV arv = CKR_OK;
-   TOKEN_TRY
-   {
-
-      //Log::log("Get Attributes of token object..");
-
-      StorageObject * obj = GetObject(hObject);
-
-      if( CK_TRUE == obj->_private )
-      {
-         if( false == m_bIsNoPinSupported )
-         {
-            if(   ( CKU_USER != _roleLogged )
-               && ( ( true == m_bIsSSO ) && ( false == isAuthenticated( ) ) )
-               )
-            {
-               for(u4 i=0;i<ulCount;i++)
-               {
-                  pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-               }
-               throw CkError(CKR_USER_NOT_LOGGED_IN);
-            }
-         }
-      }
-      //if((this->_roleLogged != CKU_USER) && (obj->_private == CK_TRUE))
-      //{
-      //   for(u4 i=0;i<ulCount;i++){
-      //      pTemplate[i].ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-      //   }
-      //   throw CkError(CKR_USER_NOT_LOGGED_IN);
-      //}
-
-      for(u4 i=0;i<ulCount;i++){
-         rv = obj->GetAttribute(&pTemplate[i]);
-         if(rv != CKR_OK){
-            arv = rv;
-         }
-      }
-   }
-   TOKEN_CATCH(arv)
-      return arv;
-}
-
-
-CK_RV Token::SetAttributeValue( CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount )
-{
-   CK_RV rv = CKR_OK;
-   CK_RV arv = CKR_OK;
-   TOKEN_TRY
-   {
-      StorageObject* pObj = GetObject( hObject );
-      // ??? pObj == NULL_PTR
-
-      // Check if we have a proper session
-      if( CK_TRUE == pObj->_private )
-      {
-         if( false == m_bIsNoPinSupported )
-         {
-            if(   ( CKU_USER != _roleLogged )
-               && ( ( true == m_bIsSSO ) && ( false == isAuthenticated( ) ) )
-               )
-            {
-               throw CkError(CKR_USER_NOT_LOGGED_IN);
-            }
-         }
-      }
-      // if( ( this->_roleLogged != CKU_USER ) && ( pObj->_private == CK_TRUE ) )
-      //{
-      //   throw CkError( CKR_USER_NOT_LOGGED_IN );
-      //}
-
-      if( pObj->_modifiable == CK_FALSE )
-      {
-         throw CkError(CKR_ATTRIBUTE_READ_ONLY);
-      }
-
-      for( u4 i = 0 ; i < ulCount ; i++ )
-      {
-         rv = pObj->SetAttribute( pTemplate[ i ], CK_FALSE );
-         if( rv != CKR_OK )
-         {
-            arv = rv;
-         }
-      }
-
-      if( arv == CKR_OK )
-      {
-         // If the object is not yet represented by a file under
-         // "p11" directory, this file must be created first.
-
-         bool fCreate = false;
-
-         // The object is represented by a P11 file if and only if
-         // the _uniqueId has been assigned a value.
-         if( pObj->_uniqueId == 0 )
-         {
-            fCreate = true;
-            if(!_initialized)
-               Initialize();
-
-            u1Array acls(3);
-            acls.GetBuffer( )[ 0 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // admin acl
-            acls.GetBuffer( )[ 1 ] = CARD_PERMISSION_READ | CARD_PERMISSION_WRITE;  // usr acl
-
-            if(pObj->_private)
-               acls.GetBuffer()[2] = 0; // everyone acl
-            else
-               acls.GetBuffer()[2] = CARD_PERMISSION_READ; // everyone acl
-
-            string fileName("p11\\" + FindFreeFileName(pObj));
-            _cardCache->ClearFileList("p11");
-            _mscm->CreateFile(&fileName,&acls,0);
-            RegisterFileUpdate();
-            pObj->_fileName = fileName;
-            pObj->_uniqueId = Util::MakeUniqueId();
-         }
-
-         // marshall this object back to the card
-         vector<u1> to;
-         pObj->Serialize(&to);
-
-         u1Array objData((s4)to.size());
-
-         for(u4 i=0;i<to.size();i++){
-            objData.SetU1At(i,to.at(i));
-         }
-
-         //ManageGC();
-
-         try
-         {
-            this->_cardCache->WriteFile(pObj->_fileName,objData);
-            this->RegisterFileUpdate();
-         }
-         catch( CkError x )
-         {
-            arv = x.Error( );
-            Log::error( "Token::SetAttributeValue", "WriteFile failed" );
-         }
-
-         if( CKR_OK != arv )
-         {
-            if(fCreate)   // Restore state of object prior to update attempt.
-            {
-               pObj->_fileName.clear();
-               pObj->_uniqueId = 0;
-            }
-         }
-      }
-   }
-   TOKEN_CATCH(arv)
-      return arv;
-}
-
-
-CK_BYTE Token::GetAvailableContainerIndex(u1Array const & cmapContents)
-{
-   u4  contentLen = cmapContents.GetLength();
-
-   // cmap file does not contain anything
-   // so index is 0
-   if(contentLen == 0){
-      return 0;
-   }
-
-   s4 entries = contentLen / SIZE_CONTAINERMAPRECORD;
-
-   for(s4 i=0;i<entries;i++){
-      // lets find out which entry has all zeros
-      // which denotes available index
-
-      // as per minidriver specification
-      // if bit 0 of flags should be set for it to be
-      // a valid entry
-      if((CMapFileGetFlag(cmapContents, i) & 0x01) != 0x01){
-         return i;
-      }
-   }
-
-   // reaching here means that cmap file has entries
-   // which are all occupied, in that the available
-   // index would be entries
-   return entries;
-}
-
-CK_BYTE Token::GetContainerForCert(u1Array const & cmapContents, u8 checkValue, u1 * keySpec)
-{
-   // Look for existing matching private key
-   vector <PrivateKeyObject*> vPriv(FindPrivateKeys(_objects, checkValue));
-   for(size_t ipriv = 0; ipriv < vPriv.size(); ++ipriv)
-   {
-      // See it the corresponding container/keyspec is already occupied by a certificate.
-      // If it isn't, this is free for use.
-      if(!FindCertificate(_objects, vPriv[ipriv]->_ctrIndex, vPriv[ipriv]->_keySpec))
-      {
-         *keySpec = vPriv[ipriv]->_keySpec;
-         return vPriv[ipriv]->_ctrIndex;
-      }
-   }
-   // No matching private key, find new container
-
-   return GetAvailableContainerIndex(cmapContents);
-}
-
-CK_BYTE Token::GetContainerForPrivateKey(u1Array const & cmapContents, u8 checkValue, u1 * keySpec)
-{
-   // Look for existing matching certificate
-   vector <CertificateObject*> vCert(FindCertificates(_objects, checkValue));
-   for(size_t icert = 0; icert < vCert.size(); ++icert)
-   {
-      // See it the corresponding container/keyspec is already occupied by a key.
-      // If it isn't, this is free for use.
-      if(!FindPrivateKey(_objects, vCert[icert]->_ctrIndex, vCert[icert]->_keySpec))
-      {
-         *keySpec = vCert[icert]->_keySpec;
-         return vCert[icert]->_ctrIndex;
-      }
-   }
-   // No matching certificate, find new container
-
-   return GetAvailableContainerIndex(cmapContents);
-}
-
-auto_ptr<u1Array> Token::UpdateCMap(CK_BYTE ctrIdx, u1Array const & contents, string const & contName )
-{
-   u4  contentLen = contents.GetLength();
-   s4 entries = contentLen / SIZE_CONTAINERMAPRECORD;
-
-   u4 newCMapSize = SIZE_CONTAINERMAPRECORD * entries;
-
-   if(ctrIdx >= entries){
-      entries = ctrIdx + 1;
-      newCMapSize = entries * SIZE_CONTAINERMAPRECORD;
-   }
-
-   //autoarray<u1> updatedContents(new u1[newCMapSize]);
-
-   auto_ptr<u1Array> updatedContents(new u1Array(newCMapSize));
-
-   memset(updatedContents->GetBuffer(), 0, newCMapSize);
-   memcpy(updatedContents->GetBuffer(), contents.GetBuffer(), contentLen);
-
-   u1 flags = CMapFileGetFlag(*updatedContents, ctrIdx);
-   if(!(flags & 0x01))
-   {
-      // Container record is new, set container Name (UNICODE string)
-      CMapFileSetName(*updatedContents, ctrIdx, contName);
-      CMapFileSetFlag(*updatedContents, ctrIdx, flags | 0x01);
-   }
-
-   SetDefaultContainer(*updatedContents, 0xFF);
-
-   return updatedContents;
-}
-
-auto_ptr<u1Array> Token::UpdateCMap(CK_BYTE ctrIdx,u1Array const & contents,u4 keySize,u1 keySpec,CK_BBOOL isDefault, string const & contName)
-{
-   u4  contentLen = contents.GetLength();
-   s4 entries = contentLen / SIZE_CONTAINERMAPRECORD;
-
-   u4 newCMapSize = SIZE_CONTAINERMAPRECORD * entries;
-
-   if(ctrIdx >= entries){
-      entries = ctrIdx + 1;
-      newCMapSize = entries * SIZE_CONTAINERMAPRECORD;
-   }
-
-   auto_ptr<u1Array> updatedContents(new u1Array(newCMapSize));
-
-   memset(updatedContents->GetBuffer(), 0, newCMapSize);
-   memcpy(updatedContents->GetBuffer(), contents.GetBuffer(), contentLen);
-
-   u1 flags = CMapFileGetFlag(*updatedContents, ctrIdx);
-   if(!(flags & 0x01))
-   {
-      // Container record is new, set container Name (UNICODE string)
-      CMapFileSetName(*updatedContents, ctrIdx, contName);
-      CMapFileSetFlag(*updatedContents, ctrIdx, flags | 0x01);
-   }
-
-   // Default container
-   SetDefaultContainer(*updatedContents, isDefault ? ctrIdx : 0xFF);
-
-   // Container Key Size
-   if (keySpec == KEYSPEC_SIGNATURE){
-      CMapFileSetSignSize(*updatedContents, ctrIdx, keySize);
-   }else{
-      CMapFileSetExchSize(*updatedContents, ctrIdx, keySize);
-   }
-
-   return updatedContents;
-}
-
-vector <PrivateKeyObject*> Token::FindPrivateKeys(vector<StorageObject*> const & objects, u8 checkValue)
-{
-   // checkValue is derived from the modulus and is sufficiently
-   // long (8 bytes) to be a unique handle to the key pair / certificate
-   vector <PrivateKeyObject*> vPriv;
-
-   for(s4 i = 0; i < static_cast<s4>(objects.size()); i++){
-      if(objects[i] && objects[i]->_class == CKO_PRIVATE_KEY){
-         PrivateKeyObject * privObject = (PrivateKeyObject*)objects[i];
-         if(privObject->_checkValue == checkValue)
-            vPriv.push_back(privObject);
-      }
-   }
-   return vPriv;
-}
-
-PrivateKeyObject * Token::FindPrivateKey(vector<StorageObject*> const & objects, CK_BYTE ctrdIdx, u1 keySpec)
-{
-   vector <PrivateKeyObject*> vPriv;
-
-   for(s4 i = 0; i < static_cast<s4>(objects.size()); i++)
-   {
-      if(objects[i] && objects[i]->_class == CKO_PRIVATE_KEY)
-      {
-         PrivateKeyObject * privObject = (PrivateKeyObject*)objects[i];
-         if(privObject->_ctrIndex == ctrdIdx && privObject->_keySpec == keySpec)
-            return privObject;  // Is supposed to be only one.
-      }
-   }
-   return 0;
-}
-
-vector <CertificateObject*> Token::FindCertificates(vector<StorageObject*> const & objects, u8 checkValue)
-{
-   // checkValue is derived from the modulus and is sufficiently
-   // long (8 bytes) to be a unique handle to the key pair / certificate
-   vector <CertificateObject*> vCert;
-
-   for(s4 i = 0; i < static_cast<s4>(objects.size()); i++)
-   {
-      if(objects[i] && objects[i]->_class == CKO_CERTIFICATE)
-      {
-         CertificateObject * certObject = (CertificateObject*)objects[i];
-         if(certObject->_checkValue == checkValue)
-            vCert.push_back(certObject);
-      }
-   }
-   return vCert;
-}
-
-CertificateObject * Token::FindCertificate(vector<StorageObject*> const & objects, CK_BYTE ctrdIdx, u1 keySpec)
-{
-   for(s4 i = 0; i < static_cast<s4>(objects.size()); i++)
-   {
-      if(objects[i] && objects[i]->_class == CKO_CERTIFICATE)
-      {
-         CertificateObject * certObject = (CertificateObject*)objects[i];
-         if(certObject->_ctrIndex == ctrdIdx && certObject->_keySpec == keySpec)
-            return certObject;
-      }
-   }
-   return 0;
-}
-
-CK_RV Token::GenerateKeyPair(auto_ptr<StorageObject> & stobjRsaPub, auto_ptr<StorageObject> & stobjRsaPriv,
-                             CK_OBJECT_HANDLE_PTR phPubKey,CK_OBJECT_HANDLE_PTR phPrivKey)
-{
-
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      RSAPublicKeyObject * rsaPubObject = static_cast<RSAPublicKeyObject*>(stobjRsaPub.get());
-      RSAPrivateKeyObject * rsaPrivObject = static_cast<RSAPrivateKeyObject*>(stobjRsaPriv.get());
-
-      if( (rsaPubObject->_modulusLen < RSA_KEY_MIN_LENGTH) ||
-         (rsaPubObject->_modulusLen > RSA_KEY_MAX_LENGTH) )
-         throw CkError(CKR_ATTRIBUTE_VALUE_INVALID);
-
-      //CheckAvailableSpace(); // HACK !!
-
-      //Log::log("Generating KeyPair on the smartcard...");
-
-      std::string nameCMapFile;
-
-      // TBD (Start a pc/sc transaction here)
-
-      // let's first read the container record file to
-      // see which container is available.
-      // No need to search for matching certificate,
-      // since this can not exist one yet!! ;)
-      nameCMapFile = "mscp\\cmapfile";
-      const u1Array & fileData = this->_cardCache->ReadFile(nameCMapFile);
-
-      CK_BYTE ctrIdx = this->GetAvailableContainerIndex(fileData);
-      if(ctrIdx == 0xFF)
-         throw CkError(CKR_DEVICE_MEMORY);
-
-      // create a capi container.
-      // KEYSPEC_KEYEXCHANGE by default.
-      this->_cardCache->ClearContainer(ctrIdx);   // Invalidate cache
-      //this->_mscm->CreateCAPIContainer(ctrIdx,CK_FALSE,KEYSPEC_KEYEXCHANGE,rsaPubObject->_modulusLen,NULL_PTR);
-      int ntry = 0;
-      while( ntry < MAX_RETRY )
-      {
-         try
-         {
-            ntry++;
-            this->_mscm->CreateCAPIContainer(ctrIdx,CK_FALSE,KEYSPEC_KEYEXCHANGE,rsaPubObject->_modulusLen,NULL_PTR);
-            //ManageGC( );
-            break;
-         }
-         catch( Marshaller::Exception & x )
-         {
-            CK_RV rv = CkError::CheckMarshallerException( x );
-            if( CKR_DEVICE_MEMORY == rv )
-            {
-               Log::error( "Token::GenerateKeyPair", "ForceGarbageCollector" );
-               _mscm->ForceGarbageCollector( );
-               if( ntry >= MAX_RETRY )
-               {
-                  Log::error( "Token::GenerateKeyPair", "Throw Exception CKR_DEVICE_MEMORY" );
-                  throw CkError( rv );
-               }
-            }
-            else
-            {
-               throw CkError( rv );
-            }
-         }
-      }
-
-      this->RegisterContainerUpdate();
-
-      rsaPubObject->_ctrIndex = ctrIdx;
-      rsaPubObject->_keySpec = KEYSPEC_KEYEXCHANGE;
-
-      rsaPrivObject->_ctrIndex = ctrIdx;
-      rsaPrivObject->_keySpec = KEYSPEC_KEYEXCHANGE;
-
-      // populate these objects with the key material
-      const CardCache::Container & cont = _cardCache->ReadContainer(ctrIdx);
-
-      rsaPubObject->_exponent = new u1Array();
-      *rsaPubObject->_exponent = cont.exchPublicExponent;
-      rsaPubObject->_modulus = new u1Array();
-      *rsaPubObject->_modulus = cont.exchModulus;
-      rsaPubObject->_local = CK_TRUE;
-
-
-      // Copy these modulus and exponent in the private key component also
-      rsaPrivObject->_publicExponent = new u1Array();
-      *rsaPrivObject->_publicExponent = cont.exchPublicExponent;
-
-      rsaPrivObject->_modulus = new u1Array();
-      *rsaPrivObject->_modulus = cont.exchModulus;
-      rsaPrivObject->_checkValue = Util::MakeCheckValue(cont.exchModulus.GetBuffer(),
-         cont.exchModulus.GetLength());
-      rsaPrivObject->_local = CK_TRUE;
-
-      string contName(CAttributedCertificate::DerivedUniqueName(cont.exchModulus.GetBuffer(),
-         cont.exchModulus.GetLength()));
-
-      // now its time to add the corresponding objects to
-      // the card (as files)
-
-      // The public key may be a session object, in that case, don't save it.
-
-      if( rsaPubObject->_tokenObject )
-      {
-         rv = this->AddObject( stobjRsaPub, phPubKey );
-      }
-
-      if( CKR_OK == rv )
-      {
-         rv = this->AddObject( stobjRsaPriv, phPrivKey );
-
-         if( CKR_OK == rv )
-         {
-            try
-            {
-               auto_ptr<u1Array> newCMap( UpdateCMap( ctrIdx, fileData, rsaPubObject->_modulusLen, KEYSPEC_KEYEXCHANGE, CK_TRUE, contName ) );
-               _cardCache->WriteFile( nameCMapFile, *newCMap );
-               RegisterFileUpdate( );
-            }
-            catch( CkError x )
-            {
-               rv = x.Error( );
-               Log::error( "Token::SetAttributeValue", "WriteFile failed" );
-            }
-
-            if( CKR_OK != rv )
-            {
-               if( rsaPubObject->_tokenObject )
-               {
-                  DeleteObject( *phPubKey );
-                  // ???
-               }
-               DeleteObject( *phPrivKey );
-
-               throw CkError( rv );
-            }
-         }
-         else if( rsaPubObject->_tokenObject )
-         {
-            DeleteObject( *phPubKey );
-         }
-      }
-   }
-   TOKEN_CATCH(rv)
-   //printf( "\nToken::GenerateKeyPair - ManageGC( true )\n" );
-      ManageGC( true );
-      return rv;
-}
-
-
-CK_RV Token::GetObject(CK_OBJECT_HANDLE hObject,StorageObject** object)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      *object = GetObject(hObject);
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::Encrypt(StorageObject* pubObj,u1Array* dataToEncrypt,CK_ULONG mechanism,CK_BYTE_PTR pEncryptedData)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      RSAPublicKeyObject* object = (RSAPublicKeyObject*)pubObj;
-
-      if(mechanism == CKM_RSA_PKCS){
-         // first do the length checks
-         if(dataToEncrypt->GetLength() > (object->_modulus->GetLength() - 11)){
-            throw CkError(CKR_DATA_LEN_RANGE);
-         }
-
-         rsaPublicKey_t key;
-
-         key.modulus = object->_modulus->GetBuffer() ;
-         key.modulusLength = object->_modulus->GetLength() * 8 ;
-         key.publicExponent = object->_exponent->GetBuffer();
-         key.publicExponentLength =  object->_exponent->GetLength() * 8;
-
-         u4 outLength = object->_modulus->GetLength();
-
-         DWORD rv ;
-         DWORD size ;
-         DWORD pubSize ;
-         R_RSA_PUBLIC_KEY	rsaKeyPublic ;
-
-         rsaKeyPublic.bits = key.modulusLength ;
-
-         size = (key.modulusLength + 7) / 8 ;
-         memcpy(rsaKeyPublic.modulus, key.modulus, size) ;
-
-         pubSize = (key.publicExponentLength + 7) / 8 ;
-         memset(rsaKeyPublic.exponent, 0, size) ;
-         memcpy(&rsaKeyPublic.exponent[size - pubSize], key.publicExponent, pubSize) ;
-
-         R_RANDOM_STRUCT & randomStruct = Util::RandomStruct();
-
-         rv = RSAPublicEncrypt(
-            pEncryptedData,
-            &outLength,
-            dataToEncrypt->GetBuffer(),
-            dataToEncrypt->GetLength(),
-            &rsaKeyPublic,
-            &randomStruct);
-
-      }else{
-
-         u4 modulusLen = object->_modulus->GetLength();
-
-         if(dataToEncrypt->GetLength() > (modulusLen)){
-            throw CkError(CKR_DATA_LEN_RANGE);
-         }
-
-         // pre-pad with zeros
-         u1Array* messageToEncrypt = new u1Array(modulusLen);
-         memset(messageToEncrypt->GetBuffer(),0,modulusLen);
-
-         s4 offsetMsgToEncrypt = modulusLen - dataToEncrypt->GetLength();
-
-         for(u4 i=0,j=offsetMsgToEncrypt;i<dataToEncrypt->GetLength();i++,j++){
-            messageToEncrypt->GetBuffer()[j] = dataToEncrypt->GetBuffer()[i];
-         }
-
-         // just block transform now
-         s4 size ;
-         s4 pubSize ;
-         R_RSA_PUBLIC_KEY	rsaKeyPublic ;
-
-         //Build the RSA public key context
-         rsaKeyPublic.bits = object->_modulus->GetLength() * 8;
-
-         size = (rsaKeyPublic.bits  + 7) / 8 ;
-         memcpy(rsaKeyPublic.modulus,object->_modulus->GetBuffer(),size) ;
-
-         pubSize = ((object->_exponent->GetLength() * 8) + 7) / 8 ;
-         memset(rsaKeyPublic.exponent, 0, size) ;
-         memcpy(&rsaKeyPublic.exponent[size - pubSize], object->_exponent->GetBuffer(), pubSize) ;
-
-         u4 outputLen = size;
-
-         rv = RSAPublicBlock(pEncryptedData,&outputLen,messageToEncrypt->GetBuffer(),size,&rsaKeyPublic);
-      }
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::Decrypt(StorageObject* privObj,u1Array* dataToDecrypt,CK_ULONG mechanism,CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      u1Array* data = NULL_PTR;
-
-      RSAPrivateKeyObject * rsaKey = static_cast<RSAPrivateKeyObject*>(privObj);
-
-      //data = this->_mscm->PrivateKeyDecrypt(rsaKey->_ctrIndex, rsaKey->_keySpec, dataToDecrypt);
-      int ntry = 0;
-      while( ntry < MAX_RETRY )
-      {
-         try
-         {
-            ntry++;
-            data = this->_mscm->PrivateKeyDecrypt( rsaKey->_ctrIndex, rsaKey->_keySpec, dataToDecrypt );
-            //ManageGC( );
-            break;
-         }
-         catch( Marshaller::Exception & x )
-         {
-            CK_RV rv = CkError::CheckMarshallerException( x );
-            if( CKR_DEVICE_MEMORY == rv )
-            {
-               Log::error( "Token::Decrypt", "ForceGarbageCollector" );
-               _mscm->ForceGarbageCollector( );
-               if( ntry >= MAX_RETRY )
-               {
-                  throw CkError( rv );
-               }
-            }
-            else
-            {
-               throw CkError( rv );
-            }
-         }
-      }
-
-
-
-
-
-      if(mechanism == CKM_RSA_PKCS){
-
-         u1* decryptedMessage = (u1*)data->GetBuffer();
-
-#define PKCS_EMEV15_PADDING_TAG   0x2
-
-         if ((decryptedMessage[0] != 0x00) || (decryptedMessage[1] != PKCS_EMEV15_PADDING_TAG))
-         {
-            // TBD: Lookup correct error message
-            // invalid message padding
-            rv = CKR_ENCRYPTED_DATA_INVALID;
-         }else{
-
-            // seach message padding separator
-            u4 mPos = 2 + 8;
-            while ((decryptedMessage[mPos] != 0x00) && (mPos < data->GetLength()))
-            {
-               mPos++;
-            }
-
-            // point on message itself.
-            mPos++;
-            u1Array* finalDecryptedMessage = new u1Array(data->GetLength() - mPos);
-            memcpy(finalDecryptedMessage->GetBuffer(),(u1*)&decryptedMessage[mPos],finalDecryptedMessage->GetLength());
-
-            delete data;
-
-            data = finalDecryptedMessage;
-         }
-      }
-      // else... CKM_RSA_X_509: Ignore padding
-
-      if(data){
-         if(*pulDataLen >= data->GetLength())
-            memcpy(pData,data->GetBuffer(),data->GetLength());
-         else
-            rv = CKR_BUFFER_TOO_SMALL;
-         *pulDataLen = data->GetLength();
-         delete data;
-      }
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::Verify(StorageObject* pubObj,u1Array* dataToVerify,CK_ULONG mechanism,u1Array* signature)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      RSAPublicKeyObject* object = (RSAPublicKeyObject*)pubObj;
-
-      if(((mechanism == CKM_RSA_PKCS) && (dataToVerify->GetLength() > (object->_modulus->GetLength() - 11))) ||
-         ((mechanism == CKM_RSA_X_509) && (dataToVerify->GetLength() > object->_modulus->GetLength())))
-      {
-         throw CkError(CKR_DATA_LEN_RANGE);
-      }
-
-      if(signature->GetLength() != object->_modulus->GetLength()){
-         throw CkError(CKR_SIGNATURE_LEN_RANGE);
-      }
-
-      s4 size ;
-      s4 pubSize ;
-      R_RSA_PUBLIC_KEY	rsaKeyPublic ;
-
-      //Build the RSA public key context
-      rsaKeyPublic.bits = object->_modulus->GetLength() * 8;
-
-      size = (rsaKeyPublic.bits  + 7) / 8 ;
-      memcpy(rsaKeyPublic.modulus,object->_modulus->GetBuffer(),size) ;
-
-      pubSize = ((object->_exponent->GetLength() * 8) + 7) / 8 ;
-      memset(rsaKeyPublic.exponent, 0, size) ;
-      memcpy(&rsaKeyPublic.exponent[size - pubSize], object->_exponent->GetBuffer(), pubSize) ;
-
-      u4 messageToVerifyLen = size;
-      u1Array* messageToVerify = new u1Array(messageToVerifyLen);
-
-      RSAPublicBlock(messageToVerify->GetBuffer(),&messageToVerifyLen,signature->GetBuffer(),size,&rsaKeyPublic);
-
-      switch(mechanism){
-
-            case CKM_RSA_PKCS:
-               rv = VerifyRSAPKCS1v15(messageToVerify,dataToVerify,size);
-               break;
-
-            case CKM_RSA_X_509:
-               rv = VerifyRSAX509(messageToVerify,dataToVerify,size);
-               break;
-
-
-            case CKM_SHA1_RSA_PKCS:
-               rv = VerifyHash(messageToVerify,dataToVerify,size,CKM_SHA_1);
-               break;
-
-            case CKM_SHA256_RSA_PKCS:
-               rv = VerifyHash(messageToVerify,dataToVerify,size,CKM_SHA256);
-               break;
-
-            case CKM_MD5_RSA_PKCS:
-               rv = VerifyHash(messageToVerify,dataToVerify,size,CKM_MD5);
-               break;
-
-            default:
-               PKCS11_ASSERT(CK_FALSE);
-               rv = CKR_GENERAL_ERROR;
-               break;
-      }
-
-      delete messageToVerify;
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-CK_RV Token::VerifyHash(u1Array* messageToVerify,u1Array* dataToVerify,u4 modulusLen,CK_ULONG hashAlgo)
-{
-   u1 DER_SHA1_Encoding[]   = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
-   u1 DER_SHA256_Encoding[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
-   u1 DER_MD5_Encoding[]    = {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00,0x04,0x10};
-
-   s4  DER_Encoding_Len = 0;
-
-   switch(hashAlgo){
-        case CKM_SHA_1:
-           DER_Encoding_Len = sizeof(DER_SHA1_Encoding);
-           break;
-
-        case CKM_SHA256:
-           DER_Encoding_Len = sizeof(DER_SHA256_Encoding);
-           break;
-
-        case CKM_MD5:
-           DER_Encoding_Len = sizeof(DER_MD5_Encoding);
-           break;
-
-   }
-
-   u1* msg  = messageToVerify->GetBuffer();
-   u1* hash = dataToVerify->GetBuffer();
-
-   // Check the decoded value against the expected data.
-   if ((msg[0] != 0x00) || (msg[1] != 0x01)){
-      return CKR_SIGNATURE_INVALID;
-   }
-
-   s4 posn = modulusLen - DER_Encoding_Len - dataToVerify->GetLength();
-
-   for(s4 i = 2; i < (posn - 1); i++)
-   {
-      if(msg[i] != 0xFF){
-         return CKR_SIGNATURE_INVALID;
-      }
-   }
-
-   if(msg[posn - 1] != 0x00){
-      return CKR_SIGNATURE_INVALID;
-   }
-
-   for (u4 i = 0; i < dataToVerify->GetLength(); i++){
-      if (msg[posn + i + DER_Encoding_Len] != hash[i]){
-         return CKR_SIGNATURE_INVALID;
-      }
-   }
-
-   return CKR_OK;
-}
-
-CK_RV Token::VerifyRSAX509(u1Array* messageToVerify,u1Array* dataToVerify,u4 modulusLen)
-{
-   // reach the first non-zero bytes in decrypted signature
-   // and data
-   u4 pos1=0;
-   u4 pos2=0;
-
-   for(;pos1<dataToVerify->GetLength();pos1++){
-      if(dataToVerify->GetBuffer()[pos1] != 0)
-         break;
-   }
-
-   for(;pos2<messageToVerify->GetLength();pos2++){
-      if(messageToVerify->GetBuffer()[pos2] != 0)
-         break;
-   }
-
-   if((dataToVerify->GetLength() - pos1) != (modulusLen - pos2)){
-      return CKR_SIGNATURE_INVALID;
-   }
-
-   for(u4 i=pos1,j=pos2;i<(modulusLen - pos2);i++,j++){
-      if(dataToVerify->GetBuffer()[i] != messageToVerify->GetBuffer()[j]){
-         return CKR_SIGNATURE_INVALID;
-      }
-   }
-
-   return CKR_OK;
-}
-
-CK_RV Token::VerifyRSAPKCS1v15(u1Array* messageToVerify,u1Array* dataToVerify,u4 modulusLen)
-{
-   // skip past the pkcs block formatting data
-   u4 pos = 2;
-   for(;pos<modulusLen;pos++)
-   {
-      if(messageToVerify->GetBuffer()[pos] == 0x00)
-      {
-         pos++;
-         break;
-      }
-   }
-
-   if(dataToVerify->GetLength() != (modulusLen - pos)){
-      return CKR_SIGNATURE_INVALID;
-   }
-
-   for(u4 i=0, j=pos;i< (modulusLen - pos); i++,j++){
-      if(dataToVerify->GetBuffer()[i] != messageToVerify->GetBuffer()[j]){
-         return CKR_SIGNATURE_INVALID;
-      }
-   }
-
-   return CKR_OK;
-}
-
-
-CK_RV Token::Sign(StorageObject* privObj,u1Array* dataToSign,CK_ULONG mechanism,CK_BYTE_PTR pSignature)
-{
-   CK_RV rv = CKR_OK;
-   TOKEN_TRY
-   {
-      u1Array* messageToSign = NULL_PTR;
-
-      // TODO: Should check if cast is safe
-      RSAPrivateKeyObject * rsaKey = static_cast<RSAPrivateKeyObject*>(privObj);
-      CK_ULONG modulusLen = rsaKey->_modulus->GetLength();
-
-      if(((mechanism == CKM_RSA_PKCS) && (dataToSign->GetLength() > modulusLen - 11)) ||
-         ((mechanism == CKM_RSA_X_509) && (dataToSign->GetLength() > modulusLen)))
-      {
-         throw CkError(CKR_DATA_LEN_RANGE);
-      }
-
-      switch(mechanism){
-
-            case CKM_RSA_PKCS:
-               messageToSign = PadRSAPKCS1v15(dataToSign,modulusLen);
-               break;
-
-            case CKM_RSA_X_509:
-               messageToSign = PadRSAX509(dataToSign,modulusLen);
-               break;
-
-            case CKM_SHA1_RSA_PKCS:
-               messageToSign = EncodeHashForSigning(dataToSign,modulusLen,CKM_SHA_1);
-               break;
-
-            case CKM_SHA256_RSA_PKCS:
-               messageToSign = EncodeHashForSigning(dataToSign,modulusLen,CKM_SHA256);
-               break;
-
-            case CKM_MD5_RSA_PKCS:
-               messageToSign = EncodeHashForSigning(dataToSign,modulusLen,CKM_MD5);
-               break;
-      }
-
-      u1Array* signatureData = NULL_PTR;
-
-      //signatureData = this->_mscm->PrivateKeyDecrypt(rsaKey->_ctrIndex, rsaKey->_keySpec, messageToSign);
-
-      int ntry = 0;
-      while( ntry < MAX_RETRY )
-      {
-         try
-         {
-            ntry++;
-            signatureData = this->_mscm->PrivateKeyDecrypt(rsaKey->_ctrIndex, rsaKey->_keySpec, messageToSign);
-            //ManageGC( );
-            break;
-         }
-         catch( Marshaller::Exception & x )
-         {
-            CK_RV rv = CkError::CheckMarshallerException( x );
-            if( CKR_DEVICE_MEMORY == rv )
-            {
-               Log::error( "Token::Sign", "ForceGarbageCollector" );
-               _mscm->ForceGarbageCollector( );
-               if( ntry >= MAX_RETRY )
-               {
-                  throw CkError( rv );
-               }
-            }
-            else
-            {
-               throw CkError( rv );
-            }
-         }
-      }
-
-      memcpy(pSignature,signatureData->GetBuffer(),signatureData->GetLength());
-
-      delete signatureData;
-      delete messageToSign;
-   }
-   TOKEN_CATCH(rv)
-      return rv;
-}
-
-// these methods should be moved to rsa library
-// once we have it
-u1Array* Token::PadRSAPKCS1v15(u1Array* dataToSign,CK_ULONG modulusLen)
-{
-   u1Array* messageToSign = new u1Array(modulusLen);
-   memset(messageToSign->GetBuffer(),0,modulusLen);
-
-   messageToSign->SetU1At(1,1);
-
-   s4 offsetMessageToSign = modulusLen - dataToSign->GetLength() - 3;
-
-   for(s4 i=0;i<offsetMessageToSign;i++){
-      messageToSign->SetU1At(2+i,0xFF);
-   }
-
-   offsetMessageToSign += 3;
-
-   memcpy((u1*)&messageToSign->GetBuffer()[offsetMessageToSign],dataToSign->GetBuffer(),dataToSign->GetLength());
-
-   return messageToSign;
-}
-
-u1Array* Token::PadRSAX509(u1Array* dataToSign,CK_ULONG modulusLen)
-{
-
-   u1Array* messageToSign = new u1Array(modulusLen);
-   memset(messageToSign->GetBuffer(),0,modulusLen);
-
-   s4 offsetMessageToSign = modulusLen - dataToSign->GetLength();
-
-   memcpy((u1*)&messageToSign->GetBuffer()[offsetMessageToSign],dataToSign->GetBuffer(),dataToSign->GetLength());
-
-   return messageToSign;
-}
-
-u1Array* Token::EncodeHashForSigning(u1Array* hashedData,CK_ULONG modulusLen,CK_ULONG hashAlgo)
-{
-   u1 DER_SHA1_Encoding[]   = {0x30,0x21,0x30,0x09,0x06,0x05,0x2B,0x0E,0x03,0x02,0x1A,0x05,0x00,0x04,0x14};
-   u1 DER_SHA256_Encoding[] = {0x30,0x31,0x30,0x0d,0x06,0x09,0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,0x05,0x00,0x04,0x20};
-   u1 DER_MD5_Encoding[]    = {0x30,0x20,0x30,0x0C,0x06,0x08,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05,0x05,0x00,0x04,0x10};
-
-   u1* DER_Encoding = NULL_PTR;
-   s4  DER_Encoding_Len = 0;
-
-   switch(hashAlgo){
-        case CKM_SHA_1:
-           DER_Encoding_Len = sizeof(DER_SHA1_Encoding);
-           DER_Encoding = new u1[DER_Encoding_Len]; //(u1*)malloc(DER_Encoding_Len);
-           memcpy(DER_Encoding,DER_SHA1_Encoding,DER_Encoding_Len);
-           break;
-
-        case CKM_SHA256:
-           DER_Encoding_Len = sizeof(DER_SHA256_Encoding);
-           DER_Encoding = new u1[DER_Encoding_Len]; //(u1*)malloc(DER_Encoding_Len);
-           memcpy(DER_Encoding,DER_SHA256_Encoding,DER_Encoding_Len);
-           break;
-
-        case CKM_MD5:
-           DER_Encoding_Len = sizeof(DER_MD5_Encoding);
-           DER_Encoding = new u1[DER_Encoding_Len]; //(u1*)malloc(DER_Encoding_Len);
-           memcpy(DER_Encoding,DER_MD5_Encoding,DER_Encoding_Len);
-           break;
-
-   }
-
-   u1Array* messageToSign = new u1Array(modulusLen);
-   memset(messageToSign->GetBuffer(),0,modulusLen);
-
-   messageToSign->SetU1At(1,1);
-
-   // caluclate pos
-   s4 pos = modulusLen - DER_Encoding_Len - hashedData->GetLength();
-
-   for(s4 i=2;i<(pos - 1);i++){
-      messageToSign->SetU1At(i,0xFF);
-   }
-
-   memcpy((u1*)&messageToSign->GetBuffer()[pos],DER_Encoding,DER_Encoding_Len);
-   memcpy((u1*)&messageToSign->GetBuffer()[pos+DER_Encoding_Len],hashedData->GetBuffer(),hashedData->GetLength());
-
-   delete DER_Encoding;
-
-   return messageToSign;
-}
-
-bool Token::PerformDeferredDelete()
-{
-   bool fSync = true;
-   //PKCS11_ASSERT(this->_roleLogged != CKU_NONE);
-
-   if(_toDelete.empty())
-      return fSync;
-
-   _cardCache->ClearFileList("mscp");
-   _cardCache->ClearFileList("p11");
-
-   // Delete files that are pending to be deleted
-   vector<string>::iterator ifile = _toDelete.begin();
-   while(ifile != _toDelete.end())
-   {
-      try
-      {
-         _cardCache->ClearFile(*ifile);
-         _mscm->DeleteFile(&(*ifile));
-         RegisterFileUpdate();
-         ifile = _toDelete.erase(ifile);
-      }
-      catch(FileNotFoundException &)
-      {
-         ifile = _toDelete.erase(ifile);
-      }
-      catch(...)
-      {
-         // Failed to delete, keep it in the list.
-         fSync = false;
-         ++ifile;
-      }
-   }
-   return fSync;
-}
-
-s4 Token::RegisterStorageObject(StorageObject * object)
-{
-   // add this in the token object list
-
-   for(size_t k = 0; k<_objects.size(); k++)
-   {
-      PKCS11_ASSERT(_objects[k] != object);
-   }
-
-
-   size_t t = 0;
-   while(t < _objects.size())
-   {
-      if(!_objects[t])
-      {
-         _objects[t] = object;
-         return static_cast<s4>(t+1);
-      }
-      ++t;
-   }
-   // Expand list
-   _objects.push_back(object);
-   return static_cast<s4>(_objects.size());
-}
-
-void Token::UnregisterStorageObject(StorageObject * object)
-{
-   size_t t = 0;
-   while(t<_objects.size())
-   {
-      if(_objects[t] == object)
-      {
-         _objects[t] = 0;
-         break;
-      }
-      ++t;
-   }
-}
-
-auto_ptr<u1Array> Token::ReadCertificateFile(string const & path)
-{
-   // Read certificate file
-
-   const u1Array & compressedCert = _cardCache->ReadFile(path);
-
-   // Decompress
-   unsigned long origLen = compressedCert.ReadU1At(3) * 256 + compressedCert.ReadU1At(2);
-   autoarray<u1> origData(new u1[origLen]);
-   auto_ptr<u1Array> value(new u1Array(origLen));
-   uncompress(value->GetBuffer(), &origLen, compressedCert.GetBuffer()+4, compressedCert.GetLength() - 4);
-   return value;
-
-}
-
-void Token::RegisterPinUpdate()
-{
-   _fPinChanged = true;
-}
-
-void Token::RegisterContainerUpdate()
-{
-   _fContainerChanged = true;
-}
-
-void Token::RegisterFileUpdate()
-{
-   _fFileChanged = true;
-}
-
-//void Token::CheckAvailableSpace()
-//{
-//   return;
-//
-//   //u4 highWaterMark = 20000;
-//   //auto_ptr<u4Array> freeSpace(_mscm->QueryFreeSpace());
-//
-//   //u4 availSpace = freeSpace->ReadU4At(2);
-//   //if(availSpace < highWaterMark)
-//   //    throw CkError(CKR_DEVICE_MEMORY);
-//
-//}
-
-
-/*
-*/
-bool Token::isAuthenticated( void )
-{
-   bool bRet = false;
-   try
-   {
-      if( NULL != _mscm )
-      {
-         bRet = (bool)(_mscm->IsAuthenticated( CARD_ROLE_USER ));
-      }
-   }
-   catch( ... )
-   {
-      Log::error( "Token::isAuthenticated",  "isAuthenticated" );
-      bRet = false;
-   }
-   return bRet;
-}
-
-
-/*
-*/
-bool Token::isNoPinSupported( void )
-{
-   return m_bIsNoPinSupported;
-/*
-bool bIsNoPinSupported = false;
-
-   u1Array* pinProperties = new u1Array( 0 );
-   try
-   {
-      pinProperties = _mscm->GetCardProperty( CARD_PROPERTY_PIN_INFO, CARD_ROLE_USER );
-
-      if( CARD_PROPERTY_NO_PIN == pinProperties->GetBuffer( )[ 0 ] )
-      {
-         bIsNoPinSupported = true;
-      }
-   }
-   catch( ... )
-   {
-   }
-
-   delete pinProperties;
-
-   return bIsNoPinSupported;
-*/
-}
-
-
-/*
-*/
-bool Token::isSSO( void )
-{
-   bool bRet = false;
-   u1Array* ba = 0;
-   try
-   {
-      ba = _mscm->GetCardProperty( CARD_PROPERTY_PIN_POLICY, 0 );
-   }
-   catch( ... )
-   {
-      bRet = false;
-   }
-   if( 0 != ba )
-   {
-      bRet = (bool)(ba->GetBuffer( )[9]);
-
-      /*
-      log2( "Max Attempts <%d>", ba->GetBuffer( )[0] );
-      log2( "Min Length <%d>", ba->GetBuffer( )[1] );
-      log2( "Max Length <%d>", ba->GetBuffer( )[2] );
-      log2( "Char Set <0x%02X>", ba->GetBuffer( )[3] );
-      log2( "Complexity rule 1 <%d>", ba->GetBuffer( )[4] );
-      log2( "Complexity rule 2 <%d>", ba->GetBuffer( )[5] );
-      log2( "Adjacent allowed <%s>", ba->GetBuffer( )[6] ? "Yes" : "No" );
-      log2( "History <%d>", ba->GetBuffer( )[7] );
-      log2( "Unblock allowed <%s>", ba->GetBuffer( )[8] ? "Yes" : "No" );
-      log2( "SSO allowed <%s>", ba->GetBuffer( )[9] ? "Yes" : "No" );
-
-      std::string s6 = ba->GetBuffer( )[6] ? "YES" : "NO";
-      std::string s8 = ba->GetBuffer( )[8] ? "YES" : "NO";
-      std::string s9 = ba->GetBuffer( )[9] ? "YES" : "NO";
-      std::string s3 = "";
-      translateToHex( ba->GetBuffer( )[3], s3 );
-
-      if( ( ba->GetBuffer( )[0] != m_iMaxAttemps )
-      || ( ba->GetBuffer( )[1] != m_iMinLength )
-      || ( ba->GetBuffer( )[2] != m_iMaxLength )
-      || ( s3 != m_stCharSet )
-      || ( ba->GetBuffer( )[4] != m_iComplexityRule1 )
-      || ( ba->GetBuffer( )[5] != m_iComplexityRule2 )
-      || ( s6 != m_stAdjacentAllowed )
-      || ( ba->GetBuffer( )[7] != m_iHistory )
-      || ( s8 != m_stAllowUnblock )
-      || ( s9 != m_stAllowSSO ) )
-      {
-      bRet = false;
-      error( "check pin policy" );
-      }
-      */
-
-      delete ba;
-   }
-   return bRet;
-}
-
-
-/*
-*/
-void Token::CardBeginTransaction( )
-{
-#ifndef _XCL_
-
-   //Log::begin( "Token::CardBeginTransaction" );
-
-   //Log::log( "Token::CardBeginTransaction - _mscm->GetPcscCardHandle..." );
-   SCARDHANDLE hCard = _mscm->GetPcscCardHandle( );
-   //Log::log( "Token::CardBeginTransaction - hCard <%#02x>", hCard );
-
-   if( !hCard )
-   {
-      Log::error( "Token::CardBeginTransaction",  "CKR_FUNCTION_FAILED" );
-      throw CkError( CKR_FUNCTION_FAILED );
-   }
-
-   LONG hResult = SCardBeginTransaction( hCard );
-   while( SCARD_W_RESET_CARD == hResult )
-   {
-      _roleLogged = CKU_NONE;
-      DWORD dwActiveProtocol;
-
-      //Log::log( "Token::CardBeginTransaction - SCardReconnect..." );
-      LONG hr = SCardReconnect( hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1, SCARD_LEAVE_CARD, &dwActiveProtocol );
-      //Log::log( "Token::CardBeginTransaction - hr <%#02x>", hr );
-      if( SCARD_S_SUCCESS == hr )
-      {
-         //Log::log( "Token::CardBeginTransaction - SCardBeginTransaction..." );
-         hResult = SCardBeginTransaction( hCard );
-         //Log::log( "Token::CardBeginTransaction - hResult <%#02x>", hResult );
-      }
-      else
-      {
-         Log::log( "Token::CardBeginTransaction - ## ERROR ## PcscError <%#02x>", hr );
-         Log::error( "Token::CardBeginTransaction",  "PcscError" );
-         throw PcscError( hr );
-      }
-   };
-
-
-   if( hResult != SCARD_S_SUCCESS )
-   {
-      Log::log( "Token::CardBeginTransaction - ## ERROR ## hResult <%#02x>", hResult );
-      Log::error( "Token::CardBeginTransaction",  "PcscError" );
-      throw PcscError( hResult );
-   }
-
-   //Log::end( "Token::CardBeginTransaction" );
-#endif
-}
-
-
-void Token::CardEndTransaction()
-{
-#ifndef _XCL_
-
-   //Log::begin( "Token::CardEndTransaction" );
-
-   SCARDHANDLE hCard = _mscm->GetPcscCardHandle( );//_mscm->GetSCardHandle();
-   if(!hCard)
-      throw CkError(CKR_FUNCTION_FAILED);
-
-   LONG hResult = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
-#ifdef __APPLE__
-   while((hResult == SCARD_W_RESET_CARD) || (hResult == SCARD_W_REMOVED_CARD))
-#else
-   while(hResult == SCARD_W_RESET_CARD)
-#endif
-   {
-      _roleLogged = CKU_NONE;
-      DWORD dwActiveProtocol;
-      LONG hr = SCardReconnect(hCard, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0|SCARD_PROTOCOL_T1,SCARD_LEAVE_CARD,&dwActiveProtocol);
-      if(hr == SCARD_S_SUCCESS)
-         hResult = SCardEndTransaction(hCard, SCARD_LEAVE_CARD);
-      else
-         throw PcscError(hr);
-   }
-   if(hResult != SCARD_S_SUCCESS && hResult != SCARD_E_NOT_TRANSACTED) // SCARD_E_NOT_TRANSACTED shouldn't occur, still ignore it.
-      throw PcscError(hResult);
-
-   //Log::end( "Token::CardEndTransaction" );
-#endif
-}
-
-StorageObject * Token::GetObject(CK_OBJECT_HANDLE hObject)
-{
-   CK_LONG idx = (CK_LONG)(hObject & CO_OBJECT_HANDLE_MASK);
-
-   if((idx < 1) || (idx > static_cast<CK_LONG>(_objects.size())) || !_objects[idx-1])
-      throw CkError(CKR_OBJECT_HANDLE_INVALID);
-
-   return _objects[idx-1];
-}
-
-
-void CMapFileClear(u1Array & file, u1 index)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD;
-   memset(file.GetBuffer()+idx, 0, SIZE_CONTAINERMAPRECORD);
-}
-
-void CMapFileSetName(u1Array & file, u1 index, string const & name)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_GUID_INFO;
-   memset(file.GetBuffer()+idx, 0, 80);
-   const size_t length = name.size() > 39 ? 39 : name.size();
-   for(size_t i = 0; i<length; i++)
-      file.SetU1At(idx + 2*i, name[i]); // Convert to wchar, little endian.
-}
-
-u1 CMapFileGetFlag(u1Array const & file, u1 index)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_FLAGS;
-   return file.ReadU1At(idx);
-}
-
-void CMapFileSetFlag(u1Array & file, u1 index, u1 flag)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_FLAGS;
-   file.SetU1At(idx, flag);
-}
-
-u2 CMapFileGetSignSize(u1Array const & file, u1 index)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_SIG_KEY_SIZE;
-   return LittleEndianToInt<u2>(file.GetBuffer(), idx);
-}
-
-void CMapFileSetSignSize(u1Array & file, u1 index, u2 size)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_SIG_KEY_SIZE;
-   IntToLittleEndian<u2>(size, file.GetBuffer(), idx);
-}
-
-u2 CMapFileGetExchSize(u1Array const & file, u1 index)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_EXC_KEY_SIZE;
-   return LittleEndianToInt<u2>(file.GetBuffer(), idx);
-}
-
-void CMapFileSetExchSize(u1Array & file, u1 index, u2 size)
-{
-   u4 idx = index * SIZE_CONTAINERMAPRECORD + IDX_EXC_KEY_SIZE;
-   IntToLittleEndian<u2>(size, file.GetBuffer(), idx);
-}
-
-
-/*
-*/
-bool Token::isPinPadSupported( void )
-{
-   // Get Reader Features
-   BYTE  outBuffer[256];
-   memset( outBuffer, 0, sizeof( outBuffer ) );
-   DWORD dwLen = 0;
-   LONG lRet = SCardControl( _mscm->GetPcscCardHandle( ), CM_IOCTL_GET_FEATURE_REQUEST, NULL, 0, outBuffer, sizeof(outBuffer), &dwLen );
-
-   // Search IOCTL of Verify PIN feature
-   int i = 0;
-   bool isVerifyPin = false;
-   m_dwIoctlVerifyPIN = 0;
-   if ( ( SCARD_S_SUCCESS == lRet ) && ( dwLen > 0 ) )
-   {
-      while( ( i + 6 ) <= (int)dwLen )
-      {
-         // Search Verify PIN feature Tag
-         if (  (outBuffer[i] == FEATURE_VERIFY_PIN_DIRECT)
-            &&(outBuffer[i+1] == 4)
-            )
-         {
-            m_dwIoctlVerifyPIN += (outBuffer[i+2] << 24);
-            m_dwIoctlVerifyPIN += (outBuffer[i+3] << 16);
-            m_dwIoctlVerifyPIN += (outBuffer[i+4] << 8);
-            m_dwIoctlVerifyPIN += outBuffer[i+5];
-
-            isVerifyPin = true;
-
-            break;
-         }
-         else
-         {
-            i += (outBuffer[i+1] + 2);
-         }
-      }
-   }
-
-   return (isVerifyPin);
-}
-
-
-///*
-//*/
-//bool Token::isPinExternalSupported( void )
-//{
-//   bool bIsPinExternalSupported = false;
-//
-//   u1Array* pinProperties = new u1Array( 0 );
-//   try
-//   {
-//      pinProperties = _mscm->GetardProperty( CARD_PROPERTY_PIN_INFO, CARD_ROLE_USER );
-//
-//      if( CARD_PROPERTY_EXTERNAL_PIN == pinProperties->GetBuffer( )[ 0 ] )
-//      {
-//         bIsPinExternalSupported = true;
-//      }
-//   }
-//   catch( ... )
-//   {
-//   }
-//
-//   delete pinProperties;
-//
-//   return bIsPinExternalSupported;
-//}
-
-/*
-*/
-CK_RV Token::verifyPinWithPinPad( void )
-{
-   DWORD PinId = CARD_ROLE_USER;
-   LONG                 lRet;
-   BYTE                 offset;
-   DWORD                dwSendLen;
-   PIN_VERIFY_STRUCTURE pin_verify;
-   BYTE                 inBuffer[256];
-   DWORD                dwInLen = 0;
-   BYTE                 outBuffer[256];
-   DWORD                dwOutLen = 0;
-
-   pin_verify.bTimerOut = 30;                               /* Time out between key stroke = max(bTimerOut, bTimerOut2). Must be between 15 and 40 sec.*/
-   pin_verify.bTimerOut2 = 00;
-
-   pin_verify.bmFormatString = 0x82;                        /* Padding V2=0x82 */
-
-   pin_verify.bmPINBlockString = 0x06;
-   pin_verify.bmPINLengthFormat = 0x00;
-   pin_verify.bPINMaxExtraDigit1 = 0x08;                    /* Max */
-   pin_verify.bPINMaxExtraDigit2 = 0x04;                    /* Min */
-   pin_verify.bEntryValidationCondition = 0x02;             /* validation key pressed */
-   pin_verify.bNumberMessage = 0x01;
-   pin_verify.wLangId = 0x0904;
-   pin_verify.bMsgIndex = 0x00;
-   pin_verify.bTeoPrologue[0] = 0x00;
-   pin_verify.bTeoPrologue[1] = 0x00;
-   pin_verify.bTeoPrologue[2] = 0x00;                       /* pin_verify.ulDataLength = 0x00; we don't know the size yet */
-
-   offset = 0;
-   pin_verify.abData[offset++] = 0x00;                      /* CLA */ /*********************************/
-   pin_verify.abData[offset++] = 0x20;                      /* INS: VERIFY */
-   pin_verify.abData[offset++] = 0x00;                      /* P1: always 0 */
-   pin_verify.abData[offset++] = (BYTE)PinId;               /* P2: PIN reference */
-   pin_verify.abData[offset++] = 0x08;                      /* Lc: 8 data bytes */
-
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-   pin_verify.abData[offset++] = 0xFF;                      /* 'FF' */
-
-   pin_verify.ulDataLength = offset;                        /* APDU size */
-   dwSendLen = sizeof(PIN_VERIFY_STRUCTURE);
-
-   // Select MSCM Application
-   inBuffer[0] = 0x00;   //CLA
-   inBuffer[1] = 0xA4;   //INS
-   inBuffer[2] = 0x04;   //P1
-   inBuffer[3] = 0x00;   //P2
-   inBuffer[4] = 0x04;   //Li
-
-   memcpy(&inBuffer[5], "MSCM", 4);
-
-   dwInLen = 5 + inBuffer[4];
-
-   dwOutLen = sizeof(outBuffer);
-   memset(outBuffer, 0x00, sizeof(outBuffer));
-
-   lRet = SCardTransmit(_mscm->GetPcscCardHandle(),
-      SCARD_PCI_T0,
-      inBuffer,
-      dwInLen,
-      NULL,
-      outBuffer,
-      &dwOutLen
-      );
-
-   // Send Verify command to the reader
-   dwOutLen = 0;
-   memset(outBuffer, 0x00, sizeof(outBuffer));
-
-   lRet = SCardControl(_mscm->GetPcscCardHandle(),
-      m_dwIoctlVerifyPIN,
-      (BYTE *)&pin_verify,
-      dwSendLen,
-      outBuffer,
-      sizeof(outBuffer),
-      &dwOutLen
-      );
-
-   Log::log( "Token::verifyPinWithPinPad - sw <%#02x %#02x>", outBuffer[ 0 ], outBuffer[ 1 ] );
-
-   CK_RV rv = CKR_FUNCTION_FAILED;
-   if( ( 0x90 == outBuffer[ 0 ] ) && ( 0x00 == outBuffer[ 1 ] ) )
-   {
-      rv = CKR_OK;
-   }
-   else if( ( 0x63 == outBuffer[ 0 ] ) && ( 0x00 == outBuffer[ 1 ] ) )
-   {
-      rv = CKR_PIN_INCORRECT;
-   }
-   // operation was cancelled by the \x91Cancel\x92 button
-   else if( ( 0x64 == outBuffer[ 0 ] ) && ( 0x01 == outBuffer[ 1 ] ) )
-   {
-      //return SCARD_W_CANCELLED_BY_USER;
-      rv = CKR_FUNCTION_CANCELED;
-   }
-   // operation timed out
-   else if( ( 0x64 == outBuffer[ 0 ] ) && ( 0x00 == outBuffer[ 1 ] ) )
-   {
-      //return SCARD_E_TIMEOUT;
-      rv = CKR_FUNCTION_CANCELED;
-   }
-   // operation timed out
-   else if( ( 0x64 == outBuffer[ 0 ] ) && ( 0x03 == outBuffer[ 1 ] ) )
-   {
-      //return SCARD_E_TIMEOUT;
-      rv = CKR_PIN_INCORRECT;
-   }
-
-   Log::log( "Token::verifyPinWithPinPad - rv <%#02x>", rv );
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Token::verifyPinWithBio( void /*Marshaller::u1Array *pin*/ )
-{
-   Log::log( "Token::verifyPinWithBio - <BEGIN>" );
-
-   CK_RV rv = CKR_GENERAL_ERROR;
-
-#ifdef WIN32
-   // Get the current OS version
-   OSVERSIONINFO osvi;
-   memset( &osvi, 0, sizeof( OSVERSIONINFO ) );
-   osvi.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
-   GetVersionEx(&osvi);
-   // Check if the Os is W7 or W2K8R2
-   if( ( 6 == osvi.dwMajorVersion ) && ( osvi.dwMinorVersion >= 1 ) )
-   {
-      Log::log( "Token::verifyPinWithBio - Os is W7 or W2K8R2" );
-
-      CardEndTransaction( );
-
-      // The OS is W7 or W2K8R2
-      HMODULE hDll = NULL;
-      LRESULT lRes = GSC_OK;
-      LRESULT (WINAPI *ptr_SetUITitles) (WCHAR*, WCHAR*);
-      LRESULT (WINAPI *ptr_AuthenticateUserCard) ();
-
-      // Load DLL
-      hDll = LoadLibraryA("GemSelCert.dll");
-      Log::log( "Token::verifyPinWithBio - load lib" );
-
-      if( 0 != hDll )
-      {
-         // Set UI Titles
-         ptr_SetUITitles = (LRESULT (WINAPI *) (WCHAR*, WCHAR*))GetProcAddress(hDll,"SetUITitles");
-         if( NULL != ptr_SetUITitles )
-         {
-            ptr_SetUITitles(L"Smartcard Security", L"User authentication");
-            Log::log( "Token::verifyPinWithBio - ptr_SetUITitles" );
-
-            // Authenticate Card User
-            ptr_AuthenticateUserCard = (LRESULT (WINAPI *)())GetProcAddress(hDll,"AuthenticateUserCard");
-            if( NULL != ptr_AuthenticateUserCard )
-            {
-               lRes = ptr_AuthenticateUserCard();
-               Log::log( "Token::verifyPinWithBio - ptr_AuthenticateUserCard" );
-
-               switch(lRes)
-               {
-               case GSC_OK:
-                  rv = CKR_OK;
-                  Log::log( "Token::verifyPinWithBio - CKR_OK" );
-                  break;
-
-               case GSC_CANCEL:
-                  rv = CKR_FUNCTION_CANCELED;
-                  Log::log( "Token::verifyPinWithBio - CKR_FUNCTION_CANCELED" );
-                  break;
-
-               case GSC_NO_CERT:
-                  rv = CKR_KEY_NEEDED;
-                  Log::log( "Token::verifyPinWithBio - CKR_KEY_NEEDED" );
-                  break;
-
-               case GSC_NO_CARD:
-                  rv = CKR_TOKEN_NOT_RECOGNIZED;
-                  Log::log( "Token::verifyPinWithBio - CKR_TOKEN_NOT_RECOGNIZED" );
-                  break;
-
-               case GSC_WRONG_PIN:
-                  rv = CKR_PIN_INCORRECT;
-                  Log::log( "Token::verifyPinWithBio - CKR_PIN_INCORRECT" );
-                  break;
-
-               case GSC_READ_CARD:
-                  rv = CKR_FUNCTION_FAILED;
-                  Log::log( "Token::verifyPinWithBio - CKR_FUNCTION_FAILED" );
-                  break;
-
-               case GSC_WRITE_CARD:
-                  rv = CKR_FUNCTION_FAILED;
-                  Log::log( "Token::verifyPinWithBio - CKR_FUNCTION_FAILED" );
-                  break;
-
-               default:
-                  Log::log( "Token::verifyPinWithBio - CKR_FUNCTION_FAILED" );
-                  rv = CKR_FUNCTION_FAILED;
-                  break;
-               }
-            }
-         }
-
-         // Release DLL
-         FreeLibrary(hDll);
-         Log::log( "Token::verifyPinWithBio - FreeLibrary" );
-      }
-
-      CardBeginTransaction( );
-   }
-   // The OS is Vista or XP
-   else
-   {
-      Log::log( "Token::verifyPinWithBio - Os is Vista or XP" );
-
-      CBioMan* pBioMan = NULL;
-      DWORD dwRes = BIO_ERR_NOT_SUPPORTED;
-
-      // Init BioMan helper
-      pBioMan = new CBioMan( );
-      Log::log( "Token::verifyPinWithBio - new" );
-      pBioMan->Connect( this->_mscm );
-      Log::log( "Token::verifyPinWithBio - connect" );
-
-      // Biometrics Verification
-      dwRes = pBioMan->VerifyBio( );
-      Log::log( "Token::verifyPinWithBio - verify bio" );
-
-      delete pBioMan;
-      Log::log( "Token::verifyPinWithBio - delete" );
-
-      // Error ?
-      switch( dwRes )
-      {
-      case BIO_ERR_SUCCESS:
-         Log::log( "Token::verifyPinWithBio - CKR_OK" );
-         rv = CKR_OK;
-         break;
-
-      case BIO_ERR_NO_CARD:
-         Log::log( "Token::verifyPinWithBio - CKR_TOKEN_NOT_PRESENT" );
-         rv = CKR_TOKEN_NOT_PRESENT;
-         break;
-
-      case BIO_ERR_NOT_SUPPORTED:
-      case BIO_ERR_NO_FINGER:
-         Log::log( "Token::verifyPinWithBio - CKR_FUNCTION_NOT_SUPPORTED" );
-         //this->_mscm->VerifyPin( CARD_ROLE_USER, pin );
-         rv = CKR_FUNCTION_NOT_SUPPORTED; //CKR_OK;
-         break;
-
-      case BIO_ERR_BIO_NOT_CHECKED:
-      case BIO_ERR_PIN_NOT_CHECKED:
-         Log::log( "Token::verifyPinWithBio - CKR_PIN_INCORRECT" );
-         rv = CKR_PIN_INCORRECT;
-         break;
-
-      case BIO_ERR_BIO_LAST:
-      case BIO_ERR_PIN_LAST:
-         Log::log( "Token::verifyPinWithBio - CKR_PIN_INCORRECT" );
-         rv = CKR_PIN_INCORRECT;
-         break;
-
-      case BIO_ERR_BLOCKED:
-         Log::log( "Token::verifyPinWithBio - CKR_PIN_INCORRECT" );
-         rv = CKR_PIN_INCORRECT;
-         break;
-
-      case BIO_ERR_ABORT:
-         Log::log( "Token::verifyPinWithBio - CKR_FUNCTION_FAILED" );
-         rv = CKR_FUNCTION_FAILED;
-         break;
-
-      default:
-         Log::log( "Token::verifyPinWithBio - CKR_GENERAL_ERROR" );
-         rv = CKR_GENERAL_ERROR;
-         break;
-      }
-   }
-#endif
-
-   Log::log( "Token::verifyPinWithBio - <END>" );
-
-   return rv;
-}
-
-
-/*
-*/
-void Token::getCardConfiguration( BYTE& a_bMode, BYTE &a_bTypePIN )
-{
-   a_bMode = UVM_PIN_ONLY;
-   a_bTypePIN = PIN_TYPE_REGULAR;
-
-   u1Array* ba = new u1Array( 0 );
-
-   try
-   {
-      ba = _mscm->GetCardProperty( CARD_PROPERTY_PIN_INFO_EX, CARD_ROLE_USER );
-
-      DWORD dwFlagsEx = (DWORD)(
-         ba->GetBuffer( )[ 12 ] +
-         ( ( ba->GetBuffer( )[ 13 ] ) << 8 ) +
-         ( ( ba->GetBuffer( )[ 14 ] ) << 16 ) +
-         ( ( ba->GetBuffer( )[ 15 ] ) << 24 )
-         );
-      //Log::log( "Token::getCardMode - dwFlagsEx <%#08x>", dwFlagsEx );
-
-      WORD wActiveMode = (WORD)( ba->GetBuffer( )[ 12 ] + ( ( ba->GetBuffer( )[ 13 ] ) << 8 ) );
-      //Log::log( "Token::getCardMode - Active mode <%ld>", wActiveMode );
-
-      a_bMode = (BYTE)wActiveMode;
-
-      a_bTypePIN = (BYTE)ba->GetBuffer( )[ 0 ];
-   }
-   catch( ... )
-   {
-      Log::log( "Token::getCardMode - PIN_INFO_EX not supported - Default values used" );
-      a_bMode = UVM_PIN_ONLY;
-      a_bTypePIN = PIN_TYPE_REGULAR;
-   }
-
-   delete ba;
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,258 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_token_h
-#define _include_token_h
-
-#include <memory>
-#include <string>
-#include <list>
-#include <map>
-#include "cardmoduleservice.h"
-#include "rsapublickeyobject.h"
-#include "rsaprivatekeyobject.h"
-#include "x509pubkeycertobject.h"
-#include "cr_rsa.h"
-
-// This class represents the data in the card/token
-
-#define FILE_TYPE_RAW_CERT          0
-#define FILE_TYPE_DATA              1
-#define FILE_TYPE_CERT              2
-#define FILE_TYPE_SECRETKEY         3
-#define FILE_TYPE_PUBLICKEY         4
-#define FILE_TYPE_PRIVATEKEY        5
-
-#define CARD_ROLE_EVERYONE      0x00
-#define CARD_ROLE_USER          0x01
-#define CARD_ROLE_ADMIN         0x02
-
-#define CARD_PERMISSION_READ    0x04
-#define CARD_PERMISSION_WRITE   0x02
-#define CARD_PERMISSION_EXECUTE 0x01
-
-#define KEYSPEC_KEYEXCHANGE  0x01
-#define KEYSPEC_SIGNATURE    0x02
-
-#define KEY_TAG_UNKNOWN         0x00
-#define KEY_TAG_EXPONENT        0x01
-#define KEY_TAG_MODULUS         0x02
-#define KEY_TAG_KEYSPEC         0x03
-#define KEY_TAG_MINBITLEN       0x04
-#define KEY_TAG_MAXBITLEN       0x05
-#define KEY_TAG_DEFAULTBITLEN   0x06
-#define KEY_TAG_INCREMENTBITLEN 0x07
-
-#define MODE_CHANGE_PIN         0x00
-#define MODE_UNBLOCK_PIN        0x01
-
-#define MAX_USER_PIN_TRIES      0x05
-#define MAX_SO_PIN_TRIES        0x05
-
-#define MIN_PIN_LEN             4
-#define MAX_PIN_LEN             24
-
-#define RSA_KEY_MIN_LENGTH 512
-#define RSA_KEY_MAX_LENGTH 2048
-
-// Constants defining layout of the records in cmapfile
-#define SIZE_CONTAINERMAPRECORD 86
-#define IDX_GUID_INFO 0
-#define IDX_FLAGS 80
-#define IDX_SIG_KEY_SIZE 82
-#define IDX_EXC_KEY_SIZE 84
-
-// Helper structs used when sync'ing CAPI containers
-// against P11 data.
-
-struct KeyPair
-{
-    KeyPair() : _checkValue(0), _fP11PrivKeyExists(false), _fP11CertExists(false) {}
-
-    u1Array _publicExponent;
-    u1Array _modulus;
-    u8 _checkValue;
-    u1Array _cert;
-    string _certName;
-    bool _fP11PrivKeyExists;
-    bool _fP11CertExists;
-};
-
-struct ContainerInfo
-{
-    ContainerInfo() : _cmapEntry(false) {}
-
-    bool _cmapEntry;        // True if it represents a valid entry in cmapfile
-    KeyPair _signKP;
-    KeyPair _exchKP;
-};
-
-class CardCache;
-
-class Token {
-
-private:
-    CardModuleService*      _mscm;
-
-    bool                    _initialized;
-    bool                    _supportGarbageCollection;
-    vector<StorageObject*>  _objects;
-    vector<string>          _toDelete;          // List of files to be deleted at next login
-    CardCache *             _cardCache;
-    unsigned long           _cardCfTimer;       // Timer indicating when _cardCf was last known to be up-to-date
-    CK_ULONG                _cardCf;            // Current state from \cardcf
-    CK_ULONG                _publCardCf;        // Reflects state of public cached objects
-    CK_ULONG                _privCardCf;        // Reflects state of private cached objects
-    CK_ULONG                _cacheCardCf;       // Reflects state of card cache (_cardCache)
-
-    bool                    _fPinChanged;
-    bool                    _fContainerChanged;
-    bool                    _fFileChanged;
-   
-    BYTE m_bCardMode;
-    BYTE m_bTypePIN;
-    //u1Array* m_u1aSerialNumber;
-
-public:
-    CK_BBOOL                _version;
-    CK_TOKEN_INFO           _tokenInfo;
-    CK_ULONG                _roleLogged;
-    //bool m_isPinExternal;
-    bool m_bIsPinPadSupported;
-    bool m_bIsSSO;
-    bool m_bIsNoPinSupported;
-
-public:
-    Token(std::string* reader);
-    ~Token();
-
-    CardModuleService* /*const*/ GetMiniDriverService( void ) { return _mscm; };
-
-    void Clear();
-    void BeginTransaction();
-    void EndTransaction();
-    void CardBeginTransaction();
-    void CardEndTransaction();
-    void ManageGC( bool bForceGarbage = false );
-
-    CK_RV Login(CK_ULONG userType,u1Array* pin);
-    CK_RV Logout();
-    CK_RV GenerateRandom(CK_BYTE_PTR randomData,CK_ULONG len);
-    CK_RV AddObject(auto_ptr<StorageObject> & stobj, CK_OBJECT_HANDLE_PTR phObject);
-    CK_RV AddPrivateKeyObject(auto_ptr<StorageObject> & stobj,CK_OBJECT_HANDLE_PTR phObject);
-    CK_RV AddCertificateObject(auto_ptr<StorageObject> & stobj,CK_OBJECT_HANDLE_PTR phObject);
-    CK_RV DeleteObject(CK_OBJECT_HANDLE hObject);
-    CK_ULONG FindObjects(Session* session,CK_OBJECT_HANDLE_PTR phObject,
-                         CK_ULONG ulMaxObjectCount,CK_ULONG_PTR  pulObjectCount);
-
-    CK_RV GetAttributeValue(CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-    CK_RV SetAttributeValue(CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-
-    CK_RV GenerateKeyPair(auto_ptr<StorageObject> & stobjRsaPub, auto_ptr<StorageObject> & stobjRsaPriv,
-                          CK_OBJECT_HANDLE_PTR phPubKey,CK_OBJECT_HANDLE_PTR phPrivKey);
-
-    CK_RV GetObject(CK_OBJECT_HANDLE hObject,StorageObject** object);
-
-    CK_RV Sign(StorageObject* privObj,u1Array* dataToSign,CK_ULONG mechanism,CK_BYTE_PTR pSignature);
-    CK_RV Decrypt(StorageObject* privObj,u1Array* dataToDecrypt,CK_ULONG mechanism,CK_BYTE_PTR pData, CK_ULONG_PTR pulDataLen);
-    CK_RV Verify(StorageObject* pubObj,u1Array* dataToVerify,CK_ULONG mechanism,u1Array* signature);
-    CK_RV Encrypt(StorageObject* pubObj,u1Array* dataToEncrypt,CK_ULONG mechanism,CK_BYTE_PTR pEncryptedData);
-
-    CK_RV InitToken(u1Array* pin,u1Array* label);
-    CK_RV InitPIN(u1Array* soPIN,u1Array* userPIN);
-    CK_RV SetPIN(u1Array* oldPIN,u1Array* newPIN);
-
-    bool isAuthenticated( void );
-    bool isSSO( void );
-    bool isNoPinSupported( void );
-
-private:
-
-   void getCardConfiguration( BYTE& a_bMode, BYTE &a_bTypePIN );
-   BYTE howToAuthenticate( BYTE bPinLen );
-   bool isPinPadSupported( void );
-   //bool isPinExternalSupported( void );
-   CK_RV verifyPinWithPinPad( void );
-   CK_RV verifyPinWithBio( void /*Marshaller::u1Array *pin*/ );
-   DWORD m_dwIoctlVerifyPIN;
-
-   std::string m_sReaderName;
-    void Initialize();
-    void Resynchronize();
-    CK_RV AuthenticateUser(u1Array* pin);
-    CK_RV AuthenticateAdmin(u1Array* key);
-    void CreateDirIfNotPresent(std::string* parent,std::string* dir,u1Array* acls);
-    bool IsInitialized();
-    void PopulateDefaultTokenInfo();
-    void SerializeTokenInfo();
-    void DeserializeTokenInfo();
-    CK_BYTE GetAvailableContainerIndex(u1Array const & cmapContents);
-    CK_BYTE GetContainerForCert(u1Array const & cmapContents, u8 checkValue, u1 * keySpec);
-    CK_BYTE GetContainerForPrivateKey(u1Array const & cmapContents, u8 checkValue, u1 * keySpec);
-
-    auto_ptr<u1Array> UpdateCMap(CK_BYTE ctrIdx,u1Array const & contents,string const & contName);
-    auto_ptr<u1Array> UpdateCMap(CK_BYTE ctrIdx,u1Array const & contents,u4 keySize,u1 keySpec,
-                                 CK_BBOOL isDefault, string const & contName);
-
-    vector <PrivateKeyObject*> FindPrivateKeys(vector<StorageObject*> const & objects, u8 checkValue);
-    PrivateKeyObject* FindPrivateKey(vector<StorageObject*> const & objects, CK_BYTE ctrdIdx, u1 keySpec);
-    vector <CertificateObject*> FindCertificates(vector<StorageObject*> const & objects, u8 checkValue);
-    CertificateObject* FindCertificate(vector<StorageObject*> const & objects, CK_BYTE ctrdIdx, u1 keySpec);
-
-    u1Array* PadRSAPKCS1v15(u1Array* dataToSign,CK_ULONG modulusLen);
-    u1Array* PadRSAX509(u1Array* dataToSign,CK_ULONG modulusLen);
-    u1Array* EncodeHashForSigning(u1Array* hashedData,CK_ULONG modulusLen,CK_ULONG hashAlgo);
-
-    CK_BBOOL IsSynchronized();
-    void SynchronizeCertificates(vector<StorageObject*> & objects, map<int, ContainerInfo> & contMap);
-    void SynchronizePrivateKeys(vector<StorageObject*> & objects, map<int, ContainerInfo> & contMap);
-    void PrepareCertAttributesFromRawData(X509PubKeyCertObject* certObject);
-    bool PerformDeferredDelete();
-    string FindFreeFileName(StorageObject* object);
-    CK_RV WriteObject(StorageObject* object);
-
-    void ReadAndPopulateObjects(vector<StorageObject*> & objects, vector<string> & toDelete,
-                                std::string const & prefix, map<int, ContainerInfo> & contMap);
-    void SynchronizePublicObjects(vector<StorageObject*> & objects, vector<string> & toDelete, map<int, ContainerInfo> & contMap);
-    void SynchronizePrivateObjects(vector<StorageObject*> & objects, vector<string> & toDelete, map<int, ContainerInfo> & contMap);
-    void BuildContainerInfoMap(map<int, ContainerInfo> & contMap);
-    void DeleteCMapRecord(CK_BYTE ctrdIdx);
-    void RemoveKeyFromCMapRecord(CK_BYTE ctrIndex, u1 keySpec);
-    void SetDefaultContainer(u1Array & contents, CK_BYTE ctrIndex);
-    u1Array* ComputeCryptogram(u1Array* challenge,u1Array* pin);
-    CK_RV VerifyRSAPKCS1v15(u1Array* messageToVerify,u1Array* dataToVerify,u4 modulusLen);
-    CK_RV VerifyRSAX509(u1Array* messageToVerify,u1Array* dataToVerify,u4 modulusLen);
-    CK_RV VerifyHash(u1Array* messageToVerify,u1Array* dataToVerify,u4 modulusLen,CK_ULONG hashAlgo);
-
-    static CK_RV DoPINValidityChecks(u1Array* pin, bool fCheckCharaceters = true);
-    s4 RegisterStorageObject(StorageObject * object);
-    void UnregisterStorageObject(StorageObject * object);
-    auto_ptr<u1Array> ReadCertificateFile(string const & path);
-    void RegisterPinUpdate();
-    void RegisterContainerUpdate();
-    void RegisterFileUpdate();
-    //void CheckAvailableSpace();
-    StorageObject * GetObject(CK_OBJECT_HANDLE hObject);
-
-};
-
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,308 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "secretkeyobject.h"
-
-SecretKeyObject::SecretKeyObject() : KeyObject()
-{
-   this->_sensitive        = CK_FALSE;
-   this->_encrypt          = CK_FALSE;
-   this->_decrypt          = CK_FALSE;
-   this->_sign             = CK_FALSE;
-   this->_verify           = CK_FALSE;
-   this->_wrap             = CK_FALSE;
-   this->_unwrap           = CK_FALSE;
-   this->_extractable      = CK_FALSE;
-   this->_alwaysSensitive  = CK_FALSE;
-   this->_neverExtractable = CK_FALSE;
-   this->_checkSum         = NULL_PTR;
-   this->_wrapWithTrusted  = CK_FALSE;
-   this->_trusted          = CK_FALSE;
-
-   this->_value            = NULL_PTR;
-   this->_valueLength      = 0;
-
-   this->_class            = CKO_SECRET_KEY;
-}
-
-SecretKeyObject::~SecretKeyObject(){
-
-   if(this->_value != NULL_PTR){
-      delete this->_value;
-   }
-}
-
-CK_BBOOL SecretKeyObject::Compare(CK_ATTRIBUTE attribute)
-{
-   switch(attribute.type){
-
-        case CKA_SENSITIVE:
-           return (this->_sensitive == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_ENCRYPT:
-           return (this->_encrypt == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_DECRYPT:
-           return (this->_decrypt == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_SIGN:
-           return (this->_sign == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_VERIFY:
-           return (this->_verify == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_UNWRAP:
-           return (this->_unwrap == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_EXTRACTABLE:
-           return (this->_extractable == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_ALWAYS_SENSITIVE:
-           return (this->_alwaysSensitive == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_NEVER_EXTRACTABLE:
-           return (this->_neverExtractable == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_CHECK_VALUE:
-           return Util::CompareU1Arrays(this->_checkSum,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_WRAP_WITH_TRUSTED:
-           return (this->_wrapWithTrusted == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_TRUSTED:
-           return (this->_trusted == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_VALUE:
-           return Util::CompareU1Arrays(this->_value,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_VALUE_LEN:
-           return (this->_valueLength == *(CK_ULONG*)attribute.pValue);
-
-        default:
-           return KeyObject::Compare(attribute);
-   }
-}
-
-CK_RV SecretKeyObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-   switch(attribute->type)
-   {
-   case CKA_SENSITIVE:
-      return StorageObject::PutBBoolInAttribute(this->_sensitive,attribute);
-
-   case CKA_ENCRYPT:
-      return StorageObject::PutBBoolInAttribute(this->_encrypt,attribute);
-
-   case CKA_DECRYPT:
-      return StorageObject::PutBBoolInAttribute(this->_decrypt,attribute);
-
-   case CKA_SIGN:
-      return StorageObject::PutBBoolInAttribute(this->_sign,attribute);
-
-   case CKA_VERIFY:
-      return StorageObject::PutBBoolInAttribute(this->_verify,attribute);
-
-   case CKA_UNWRAP:
-      return StorageObject::PutBBoolInAttribute(this->_unwrap,attribute);
-
-   case CKA_EXTRACTABLE:
-      return StorageObject::PutBBoolInAttribute(this->_extractable,attribute);
-
-   case CKA_ALWAYS_SENSITIVE:
-      return StorageObject::PutBBoolInAttribute(this->_alwaysSensitive,attribute);
-
-   case CKA_NEVER_EXTRACTABLE:
-      return StorageObject::PutBBoolInAttribute(this->_neverExtractable,attribute);
-
-   case CKA_CHECK_VALUE:
-      return StorageObject::PutU1ArrayInAttribute(this->_checkSum,attribute);
-
-   case CKA_WRAP_WITH_TRUSTED:
-      return StorageObject::PutBBoolInAttribute(this->_wrapWithTrusted,attribute);
-
-   case CKA_TRUSTED:
-      return StorageObject::PutBBoolInAttribute(this->_trusted,attribute);
-
-   case CKA_VALUE:
-      if(this->_sensitive == CK_TRUE || this->_extractable == CK_FALSE){
-         attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-         return CKR_ATTRIBUTE_SENSITIVE;
-      }
-      return StorageObject::PutU1ArrayInAttribute(this->_value,attribute);
-
-   case CKA_VALUE_LEN:
-      return StorageObject::PutULongInAttribute(this->_valueLength,attribute);
-
-   default:
-      return KeyObject::GetAttribute(attribute);
-   }
-}
-
-CK_RV SecretKeyObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-   switch(attribute.type)
-   {
-   case CKA_SENSITIVE:
-      this->_sensitive = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_ENCRYPT:
-      this->_encrypt = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_DECRYPT:
-      this->_decrypt = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_SIGN:
-      this->_sign = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_VERIFY:
-      this->_verify = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_UNWRAP:
-      this->_unwrap = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_EXTRACTABLE:
-      this->_extractable = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_ALWAYS_SENSITIVE:
-      this->_alwaysSensitive = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_NEVER_EXTRACTABLE:
-      this->_neverExtractable = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_CHECK_VALUE:
-      if(this->_checkSum != NULL_PTR){
-         delete this->_checkSum;
-      }
-      this->_checkSum = new u1Array(attribute.ulValueLen);
-      memcpy((u1*)this->_checkSum->GetBuffer(),(CK_BYTE_PTR)attribute.pValue,attribute.ulValueLen);
-      break;
-
-   case CKA_WRAP_WITH_TRUSTED:
-      this->_wrapWithTrusted = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_TRUSTED:
-      this->_trusted = *(CK_BBOOL*)attribute.pValue;
-      break;
-
-   case CKA_VALUE:
-      if(this->_value != NULL_PTR){
-         delete this->_value;
-      }
-      this->_value = new u1Array(attribute.ulValueLen);
-      memcpy((u1*)this->_value->GetBuffer(),(CK_BYTE_PTR)attribute.pValue,attribute.ulValueLen);
-      break;
-
-   case CKA_VALUE_LEN:
-      this->_valueLength = *(CK_ULONG*)attribute.pValue;
-      break;
-
-   default:
-      return KeyObject::SetAttribute(attribute,objCreation);
-   }
-
-   return CKR_OK;
-}
-
-void SecretKeyObject::Serialize(std::vector<u1> *to)
-{
-   KeyObject::Serialize(to);
-
-   Util::PushBBoolInVector(to,this->_sensitive);
-
-   Util::PushBBoolInVector(to,this->_encrypt);
-
-   Util::PushBBoolInVector(to,this->_decrypt);
-
-   Util::PushBBoolInVector(to,this->_sign);
-
-   Util::PushBBoolInVector(to,this->_verify);
-
-   Util::PushBBoolInVector(to,this->_unwrap);
-
-   Util::PushBBoolInVector(to,this->_extractable);
-
-   Util::PushBBoolInVector(to,this->_alwaysSensitive);
-
-   Util::PushBBoolInVector(to,this->_neverExtractable);
-
-   Util::PushByteArrayInVector(to,this->_checkSum);
-
-   Util::PushBBoolInVector(to,this->_wrapWithTrusted);
-
-   Util::PushBBoolInVector(to,this->_trusted);
-
-   Util::PushByteArrayInVector(to,this->_value);
-
-   Util::PushULongInVector(to,this->_valueLength);
-}
-
-void SecretKeyObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-   KeyObject::Deserialize(from,idx);
-
-   this->_sensitive = Util::ReadBBoolFromVector(from,idx);
-
-   this->_encrypt = Util::ReadBBoolFromVector(from,idx);
-
-   this->_decrypt = Util::ReadBBoolFromVector(from,idx);
-
-   this->_sign = Util::ReadBBoolFromVector(from,idx);
-
-   this->_verify = Util::ReadBBoolFromVector(from,idx);
-
-   this->_unwrap = Util::ReadBBoolFromVector(from,idx);
-
-   this->_extractable = Util::ReadBBoolFromVector(from,idx);
-
-   this->_alwaysSensitive = Util::ReadBBoolFromVector(from,idx);
-
-   this->_neverExtractable = Util::ReadBBoolFromVector(from,idx);
-
-   this->_checkSum = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_wrapWithTrusted = Util::ReadBBoolFromVector(from,idx);
-
-   this->_trusted = Util::ReadBBoolFromVector(from,idx);
-
-   this->_value = Util::ReadByteArrayFromVector(from,idx);
-
-   this->_valueLength = Util::ReadULongFromVector(from,idx);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,61 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_secretkeyobject_h
-#define _include_secretkeyobject_h
-
-#include "keyobject.h"
-
-class SecretKeyObject : public KeyObject
-{
-
-public:
-    CK_BBOOL    _sensitive;
-    CK_BBOOL    _encrypt;
-    CK_BBOOL    _decrypt;
-    CK_BBOOL    _sign;
-    CK_BBOOL    _verify;
-    CK_BBOOL    _wrap;
-    CK_BBOOL    _unwrap;
-    CK_BBOOL    _extractable;
-    CK_BBOOL    _alwaysSensitive;
-    CK_BBOOL    _neverExtractable;
-    u1Array*    _checkSum;
-    CK_BBOOL    _wrapWithTrusted;
-    CK_BBOOL    _trusted;
-
-    u1Array*    _value;
-    CK_ULONG    _valueLength;
-
-public:
-    SecretKeyObject();
-    virtual ~SecretKeyObject();
-
-    CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    void Serialize(vector<u1>* to);
-    void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,604 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include "platconfig.h"
-#include "config.h"
-#include "thread.h"
-#include "event.h"
-#include "template.h"
-#include "session.h"
-#include "slot.h"
-
-Session::Session(CK_BBOOL isReadWrite){
-    this->_isReadWrite    = isReadWrite;
-    this->_searchTempl    = NULL_PTR;
-    this->_isSearchActive = CK_FALSE;
-
-    this->_digest         = NULL_PTR;
-    this->_digestRSA      = NULL_PTR;
-    this->_digestRSAVerification = NULL_PTR;
-
-    this->_isDigestActive = CK_FALSE;
-    this->_isDigestRSAActive = CK_FALSE;
-    this->_isDigestRSAVerificationActive = CK_FALSE;
-
-    this->_signature = NULL_PTR;
-    this->_decryption     = NULL_PTR;
-    this->_encryption     = NULL_PTR;
-    this->_verification   = NULL_PTR;
-
-    this->_soPIN     = NULL_PTR;
-
-    this->_accumulatedDataToSign = NULL_PTR;
-    this->_accumulatedDataToVerify = NULL_PTR;
-
-    _objects.clear();
-    _sessionObjectsReturnedInSearch.clear();
-    _tokenObjectsReturnedInSearch.clear();
-
-    if( TRUE == this->_isReadWrite )
-    {
-      this->_state = CKS_RW_PUBLIC_SESSION;
-    }
-    else
-    {
-      this->_state = CKS_RO_PUBLIC_SESSION;
-    }
-}
-
-Session::~Session(){
-
-   for(size_t i = 0; i < _objects.size(); i++)
-   {
-      if( NULL_PTR != _objects[i] )
-      {
-         delete _objects[i];
-      }
-      _objects[i] = NULL_PTR;
-   }
-
-    if(this->_digest != NULL_PTR){
-        delete this->_digest;
-    }
-
-    if(this->_digestRSA != NULL_PTR){
-        delete this->_digestRSA;
-    }
-
-    if(this->_digestRSAVerification != NULL_PTR){
-        delete this->_digestRSAVerification;
-    }
-
-    if(this->_signature != NULL_PTR){
-        delete this->_signature;
-    }
-
-    if(this->_decryption != NULL_PTR){
-        delete this->_decryption;
-    }
-
-    if(this->_encryption != NULL_PTR){
-        delete this->_encryption;
-    }
-
-    if(this->_verification != NULL_PTR){
-        delete this->_verification;
-    }
-
-    if(this->_soPIN != NULL_PTR){
-        delete this->_soPIN;
-    }
-
-    if(this->_accumulatedDataToSign != NULL_PTR){
-        delete this->_accumulatedDataToSign;
-    }
-
-    if(this->_accumulatedDataToVerify != NULL_PTR){
-        delete this->_accumulatedDataToVerify;
-    }
-}
-
-void Session::SetSearchTemplate(Template* templ)
-{
-    PKCS11_ASSERT(this->_isSearchActive == CK_FALSE);
-
-    this->_searchTempl = templ;
-    this->_isSearchActive = CK_TRUE;
-
-    _tokenObjectsReturnedInSearch.clear();
-    _sessionObjectsReturnedInSearch.clear();
-}
-
-void Session::RemoveSearchTemplate()
-{
-    if(this->_searchTempl != NULL_PTR){
-        delete this->_searchTempl;
-        this->_searchTempl = NULL_PTR;
-    }
-
-    this->_isSearchActive = CK_FALSE;
-}
-
-void Session::UpdateState(CK_ULONG roleLogged)
-{
-    if(this->_isReadWrite)
-    {
-        switch(roleLogged)
-        {
-            case CKU_NONE:
-                this->_state = CKS_RW_PUBLIC_SESSION;
-                break;
-
-            case CKU_SO:
-                this->_state = CKS_RW_SO_FUNCTIONS;
-                break;
-
-            case CKU_USER:
-                this->_state = CKS_RW_USER_FUNCTIONS;
-                break;
-        }
-    }
-    else
-    {
-        switch(roleLogged)
-        {
-            case CKU_NONE:
-                this->_state = CKS_RO_PUBLIC_SESSION;
-                break;
-
-            case CKU_USER:
-                this->_state = CKS_RO_USER_FUNCTIONS;
-                break;
-        }
-    }
-}
-
-CK_BBOOL Session::IsSearchActive()
-{
-    return this->_isSearchActive;
-}
-
-void Session::SetId(CK_ULONG id)
-{
-    this->_id = id;
-}
-
-void Session::SetSlot(Slot* slot)
-{
-    this->_slot = slot;
-}
-
-CK_ULONG Session::MakeObjectHandle(CK_ULONG idx)
-{
-     CK_ULONG objHandle = CO_SESSION_OBJECT | idx;
-     objHandle = (this->_id << 16) | objHandle;
-
-     return objHandle;
-}
-
-CK_ULONG Session::FindObjects(CK_ULONG idx,CK_OBJECT_HANDLE_PTR phObject,
-                              CK_ULONG ulMaxObjectCount,CK_ULONG_PTR  pulObjectCount)
-{
-
-    PKCS11_ASSERT(this->_isSearchActive);
-
-    for(CK_LONG i=0;i<static_cast<CK_LONG>(_objects.size()) && (idx < ulMaxObjectCount);i++){
-
-        if(this->_objects[i] == NULL_PTR){
-            continue;
-        }
-
-        if(this->_sessionObjectsReturnedInSearch[i] == CK_TRUE){
-            continue;
-        }
-
-         if( CK_TRUE == this->_objects[i]->_private )
-         {
-            if( false == _slot->_token->m_bIsNoPinSupported )
-            {
-               if(   ( CKU_USER != _slot->_token->_roleLogged )
-                  && ( ( true == _slot->_token->m_bIsSSO ) && ( false == _slot->_token->isAuthenticated( ) ) )
-                  )
-               {
-                  continue;
-               }
-            }
-         }
-        //if((this->_objects[i]->_private == CK_TRUE) &&
-        //    (this->_slot->_token->_roleLogged != CKU_USER))
-        //{
-        //    continue;
-        //}
-
-        if(this->_searchTempl == NULL_PTR){
-            phObject[idx++] = MakeObjectHandle(i+1);
-            *pulObjectCount = *pulObjectCount + 1;
-            this->_sessionObjectsReturnedInSearch[i] = CK_TRUE;
-        }
-        else{
-            CK_BBOOL match = CK_TRUE;
-
-            vector<CK_ATTRIBUTE> attributes = this->_searchTempl->_attributes;
-            for(CK_ULONG a=0;a<attributes.size();a++){
-                if(this->_objects[i]->Compare(attributes.at(a)) == CK_FALSE){
-                    match = CK_FALSE;
-                    break;
-                }
-            }
-
-            if(match == CK_TRUE){
-                phObject[idx++] = MakeObjectHandle(i+1);
-                *pulObjectCount = *pulObjectCount + 1;
-                this->_sessionObjectsReturnedInSearch[i] = CK_TRUE;
-            }
-
-        }
-    }
-
-    return idx;
-}
-
-CK_RV Session::AddObject(StorageObject* obj,CK_OBJECT_HANDLE_PTR phObject)
-{
-    for(CK_ULONG i = 0; i < static_cast<CK_ULONG>(_objects.size()); i++)
-    {
-        if(this->_objects[i] == NULL_PTR)
-        {
-            this->_objects[i] = obj;
-            *phObject = MakeObjectHandle(i+1);
-
-            return CKR_OK;
-        }
-    }
-
-    _objects.push_back(obj);
-
-    *phObject = MakeObjectHandle(static_cast<CK_ULONG>(_objects.size()));
-
-    return CKR_OK;
-}
-
-CK_RV Session::DeleteObject(CK_OBJECT_HANDLE hObject)
-{
-    // object handle also encodes the session to which it
-    // belongs, it is also possible to delete object of one
-    // session from other
-
-    CK_SESSION_HANDLE encodedSId = ((hObject >> 16) & 0x0000FFFF);
-
-    if ((encodedSId < 1) || (encodedSId >= _slot->_sessions.size())){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    if(this->_slot->_sessions[encodedSId] == NULL_PTR){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    // determine the index
-    CK_LONG idx = (CK_LONG)(hObject & CO_OBJECT_HANDLE_MASK);
-    if(idx < 1 || idx > static_cast<CK_LONG>(_slot->_sessions[encodedSId]->_objects.size()))
-        return CKR_OBJECT_HANDLE_INVALID;
-
-    StorageObject* obj = this->_slot->_sessions[encodedSId]->_objects[idx-1];
-
-    if(obj == NULL_PTR){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    // if this is a readonly session and
-    // user is not logged then only public session objects
-    // can be created
-    if(this->_isReadWrite == CK_FALSE)
-    {
-        if(obj->_tokenObject)
-            return CKR_SESSION_READ_ONLY;
-    }
-
-   if( CK_TRUE == obj->_private )
-   {
-      if( false == _slot->_token->m_bIsNoPinSupported )
-      {
-         if(   ( CKU_USER != _slot->_token->_roleLogged )
-            && ( ( true == _slot->_token->m_bIsSSO ) && ( false == _slot->_token->isAuthenticated( ) ) )
-            )
-         {
-            return CKR_USER_NOT_LOGGED_IN;
-         }
-      }
-   }
-    //if ((this->_slot->_token->_roleLogged != CKU_USER) && (obj->_private == CK_TRUE)){
-    //    return CKR_USER_NOT_LOGGED_IN;
-    //}
-
-    delete obj;
-
-    this->_slot->_sessions[encodedSId]->_objects[idx-1] = NULL_PTR;
-
-    return CKR_OK;
-}
-
-CK_RV Session::GetAttributeValue(CK_OBJECT_HANDLE hObject,
-                               CK_ATTRIBUTE_PTR pTemplate,
-                               CK_ULONG ulCount)
-{
-    CK_RV rv  = CKR_OK;
-    CK_RV arv = CKR_OK;
-
-    CK_LONG idx = (CK_LONG)(hObject & CO_OBJECT_HANDLE_MASK);
-
-    //  lets see if the object handle provided is a correct handle or not
-    if((idx < 1) || (idx > static_cast<CK_LONG>(_objects.size())) || (this->_objects[idx-1] == NULL_PTR)){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    StorageObject* obj = this->_objects[idx-1];
-
-   if( CK_TRUE == obj->_private )
-   {
-      if( false == _slot->_token->m_bIsNoPinSupported )
-      {
-         if(   ( CKU_USER != _slot->_token->_roleLogged )
-            && ( ( true == _slot->_token->m_bIsSSO ) && ( false == _slot->_token->isAuthenticated( ) ) )
-            )
-         {
-            for(u4 i=0;i<ulCount;i++)
-            {
-               pTemplate[i].ulValueLen = (CK_ULONG)-1;
-            }
-            return CKR_USER_NOT_LOGGED_IN;
-         }
-      }
-   }
-   //if((this->_slot->_token->_roleLogged != CKU_USER) && (obj->_private == CK_TRUE))
-   // {
-   //     for(u4 i=0;i<ulCount;i++){
-   //         pTemplate[i].ulValueLen = (CK_ULONG)-1;
-   //     }
-   //     return CKR_USER_NOT_LOGGED_IN;
-   // }
-
-    for(u4 i=0;i<ulCount;i++){
-        rv = obj->GetAttribute(&pTemplate[i]);
-        if(rv != CKR_OK){
-            arv = rv;
-        }
-    }
-
-    return arv;
-}
-
-CK_RV Session::SetAttributeValue(CK_OBJECT_HANDLE hObject,
-                               CK_ATTRIBUTE_PTR pTemplate,
-                               CK_ULONG ulCount)
-{
-    CK_RV rv  = CKR_OK;
-    CK_RV arv = CKR_OK;
-
-    CK_LONG idx = (CK_LONG)(hObject & CO_OBJECT_HANDLE_MASK);
-
-    //  lets see if the object handle provided is a correct handle or not
-    if((idx < 1) || (idx > static_cast<CK_LONG>(_objects.size())) || (this->_objects[idx-1] == NULL_PTR)){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    StorageObject* obj = this->_objects[idx-1];
-
-   if( CK_TRUE == obj->_private )
-   {
-      if( false == _slot->_token->m_bIsNoPinSupported )
-      {
-         if(   ( CKU_USER != _slot->_token->_roleLogged )
-            && ( ( true == _slot->_token->m_bIsSSO ) && ( false == _slot->_token->isAuthenticated( ) ) )
-            )
-         {
-            return CKR_USER_NOT_LOGGED_IN;
-         }
-      }
-   }
-    //if ((this->_slot->_token->_roleLogged != CKU_USER) && (obj->_private == CK_TRUE)){
-    //    return CKR_USER_NOT_LOGGED_IN;
-    //}
-
-    for(u4 i=0;i<ulCount;i++){
-        rv = obj->SetAttribute(pTemplate[i],CK_FALSE);
-        if(rv != CKR_OK){
-            arv = rv;
-        }
-    }
-
-    return arv;
-}
-
-void Session::SetDigest(CDigest *digest)
-{
-    this->_digest = digest;
-    this->_isDigestActive = CK_TRUE;
-}
-
-void Session::RemoveDigest()
-{
-    if(this->_digest != NULL_PTR){
-        delete this->_digest;
-        this->_digest = NULL_PTR;
-    }
-
-    this->_isDigestActive = CK_FALSE;
-}
-
-CK_BBOOL Session::IsDigestActive()
-{
-    return this->_isDigestActive;
-}
-
-void Session::SetDigestRSA(CDigest *digest)
-{
-    this->_digestRSA = digest;
-    this->_isDigestRSAActive = CK_TRUE;
-}
-
-void Session::RemoveDigestRSA()
-{
-    if(this->_digestRSA != NULL_PTR){
-        delete this->_digestRSA;
-        this->_digestRSA = NULL_PTR;
-    }
-
-    this->_isDigestRSAActive = CK_FALSE;
-}
-
-CK_BBOOL Session::IsDigestRSAActive()
-{
-    return this->_isDigestRSAActive;
-}
-
-void Session::SetDigestRSAVerification(CDigest *digest)
-{
-    this->_digestRSAVerification = digest;
-    this->_isDigestRSAVerificationActive = CK_TRUE;
-}
-
-void Session::RemoveDigestRSAVerification()
-{
-    if(this->_digestRSAVerification != NULL_PTR){
-        delete this->_digestRSAVerification;
-        this->_digestRSAVerification = NULL_PTR;
-    }
-
-    this->_isDigestRSAVerificationActive = CK_FALSE;
-}
-
-CK_BBOOL Session::IsDigestRSAVerificationActive()
-{
-    return this->_isDigestRSAVerificationActive;
-}
-
-CK_RV Session::GetObject(CK_OBJECT_HANDLE hObject,StorageObject** object)
-{
-    if(hObject == 0){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    CK_SESSION_HANDLE encodedSId = ((hObject >> 16) & 0x0000FFFF);
-
-    if ((encodedSId < 1) || (encodedSId >= _slot->_sessions.size())){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    if(this->_slot->_sessions[encodedSId] == NULL_PTR){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    // determine the index
-    CK_LONG idx = (CK_LONG)(hObject & CO_OBJECT_HANDLE_MASK);
-
-    StorageObject* obj = this->_slot->_sessions[encodedSId]->_objects[idx-1];
-
-    if(obj == NULL_PTR){
-        return CKR_OBJECT_HANDLE_INVALID;
-    }
-
-    *object = obj;
-
-    return CKR_OK;
-}
-
-void Session::SetEncryptionOperation(CryptoOperation *encryption)
-{
-    this->_encryption = encryption;
-}
-
-void Session::RemoveEncryptionOperation()
-{
-    if(this->_encryption != NULL_PTR){
-        delete this->_encryption;
-    }
-
-    this->_encryption = NULL_PTR;
-}
-
-CK_BBOOL Session::IsEncryptionActive(){
-
-   return (this->_encryption != NULL_PTR);
-}
-
-void Session::SetVerificationOperation(CryptoOperation *verification)
-{
-    this->_verification = verification;
-}
-
-void Session::RemoveVerificationOperation()
-{
-    if(this->_verification != NULL_PTR){
-        delete this->_verification;
-    }
-
-    this->_verification = NULL_PTR;
-}
-
-CK_BBOOL Session::IsVerificationActive(){
-
-   return (this->_verification != NULL_PTR);
-}
-
-void Session::SetDecryptionOperation(CryptoOperation *decryption)
-{
-    this->_decryption = decryption;
-}
-
-void Session::RemoveDecryptionOperation()
-{
-    if(this->_decryption != NULL_PTR){
-        delete this->_decryption;
-    }
-
-    this->_decryption = NULL_PTR;
-}
-
-CK_BBOOL Session::IsDecryptionActive(){
-
-   return (this->_decryption != NULL_PTR);
-}
-
-void Session::SetSignatureOperation(CryptoOperation* signature)
-{
-    this->_signature = signature;
-}
-
-void Session::RemoveSignatureOperation()
-{
-    if(this->_signature != NULL_PTR){
-        delete this->_signature;
-    }
-
-    this->_signature = NULL_PTR;
-}
-
-CK_BBOOL Session::IsSignatureActive(){
-
-    return (this->_signature != NULL_PTR);
-
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/session.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/session.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/session.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,144 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_session_h
-#define _include_session_h
-
-#include "template.h"
-#include "digest.h"
-#include "storageobject.h"
-#include <map>
-
-class Slot;
-
-class CryptoOperation{
-    CK_ULONG            _mechanism;
-    StorageObject*      _object;
-
-public:
-    CryptoOperation(CK_ULONG mechanism,StorageObject* obj){
-        this->_mechanism = mechanism;
-        this->_object = obj;
-    }
-
-    ~CryptoOperation(){}
-
-public:
-    CK_ULONG    GetMechanism() { return this->_mechanism;}
-    StorageObject* GetObject() { return this->_object;}
-};
-
-class Session{
-
-public:
-    CK_BBOOL                _isReadWrite;
-    CK_ULONG                _state;
-    vector<StorageObject*>  _objects;
-    Template*               _searchTempl;
-    CDigest*                _digest;
-    CDigest*                _digestRSA;
-    CDigest*                _digestRSAVerification;
-
-    map<CK_ULONG, bool>     _sessionObjectsReturnedInSearch;
-    map<CK_ULONG, bool>     _tokenObjectsReturnedInSearch;
-
-    CryptoOperation*         _signature;
-    CryptoOperation*         _decryption;
-    CryptoOperation*         _verification;
-    CryptoOperation*         _encryption;
-
-    CK_BBOOL                _isSearchActive;
-    CK_BBOOL                _isDigestActive;
-    CK_BBOOL                _isDigestRSAActive;
-    CK_BBOOL                _isDigestRSAVerificationActive;
-
-    CK_ULONG                _id;
-    Slot*                   _slot;
-
-    u1Array*                _accumulatedDataToSign;
-    u1Array*                _accumulatedDataToVerify;
-
-
-    // Looks scary huh, the problem is that CardModule interface require
-    // cryptogram as part of ChangeReferenceData method whereas
-    // PKCS#11 first log SO in and then call InitPIN. InitPIN does not have any
-    // information about SO PIN so what we do here is to cache it momentarily.
-    // Basically during Login (as SO) we cache it and destroy it during closing
-    // of session
-    u1Array*                _soPIN;
-
-public:
-    Session(CK_BBOOL isReadWrite);
-    ~Session();
-
-    void SetSearchTemplate(Template* templ);
-    void RemoveSearchTemplate();
-
-    void SetDigest(CDigest* digest);
-    void RemoveDigest();
-
-    void SetEncryptionOperation(CryptoOperation* encryption);
-    void RemoveEncryptionOperation();
-    CK_BBOOL IsEncryptionActive();
-
-    void SetVerificationOperation(CryptoOperation* verification);
-    void RemoveVerificationOperation();
-    CK_BBOOL IsVerificationActive();
-
-    void SetDecryptionOperation(CryptoOperation* decryption);
-    void RemoveDecryptionOperation();
-    CK_BBOOL IsDecryptionActive();
-
-    void SetSignatureOperation(CryptoOperation* signature);
-    void RemoveSignatureOperation();
-    CK_BBOOL IsSignatureActive();
-
-    void SetDigestRSA(CDigest* digest);
-    void RemoveDigestRSA();
-
-    void SetDigestRSAVerification(CDigest* digest);
-    void RemoveDigestRSAVerification();
-
-    void UpdateState(CK_ULONG roleLogged);
-    CK_BBOOL IsSearchActive();
-    CK_BBOOL IsDigestActive();
-    CK_BBOOL IsDigestRSAActive();
-    CK_BBOOL IsDigestRSAVerificationActive();
-
-    CK_RV AddObject(StorageObject* object,CK_OBJECT_HANDLE_PTR phObject);
-    CK_RV DeleteObject(CK_OBJECT_HANDLE hObject);
-
-    CK_ULONG FindObjects(CK_ULONG idx,CK_OBJECT_HANDLE_PTR phObject,
-                         CK_ULONG ulMaxObjectCount,CK_ULONG_PTR  pulObjectCount);
-
-	CK_RV GetAttributeValue(CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-    CK_RV SetAttributeValue(CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-
-    void SetId(CK_ULONG id);
-    void SetSlot(Slot* slot);
-
-    CK_RV GetObject(CK_OBJECT_HANDLE hObject,StorageObject** object);
-
-private:
-    CK_ULONG MakeObjectHandle(CK_ULONG idx);
-};
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,73 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "digest.h"
-#include "sha1.h"
-
-CSHA1::CSHA1(){
-    this->_hashValue     = (CK_BYTE_PTR)malloc(SHA1_HASH_LENGTH);
-    this->_workingBuffer = (CK_BYTE_PTR)malloc(SHA1_BLOCK_LENGTH);
-    this->_hashLength    = SHA1_HASH_LENGTH;
-    this->_blockLength   = SHA1_BLOCK_LENGTH;
-}
-
-CSHA1::~CSHA1(){
-}
-
-void CSHA1::TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result)
-{
-    algo_sha1_context ctx;
-
-    ctx.digest = (u4*)result;
-
-    if (counter == 0) {
-		algo_sha1_starts(&ctx);
-    } else {
-        ctx.total[0] = counter;
-        ctx.total[1] = 0;
-    }
-
-    algo_sha1_update(&ctx, data, SHA1_BLOCK_LENGTH);
-}
-
-void CSHA1::TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result)
-{
-    algo_sha1_context ctx;
-
-    ctx.digest = (u4*)result;
-
-    if (counter == 0) {
-		algo_sha1_starts(&ctx);
-    } else {
-        ctx.total[0] = counter;
-        ctx.total[1] = 0;
-    }
-
-    ctx.input = (u1*)malloc(SHA1_BLOCK_LENGTH);
-    memset(ctx.input,0,SHA1_BLOCK_LENGTH);
-
-    algo_sha1_update(&ctx, data, length);
-    algo_sha1_finish(&ctx);
-
-    free(ctx.input);
-}
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,22 +18,29 @@
  *
  */
 
-#ifndef _include_sha1_h
-#define _include_sha1_h
 
-#include "MarshallerCfg.h"
+#ifndef __GEMALTO_SHA1__
+#define __GEMALTO_SHA1__
+
+
+#include "digest.h"
 #include "algo_sha1.h"
 
-class CSHA1 : public CDigest
-{
+
+class CSHA1 : public CDigest {
+
 private:
-    void TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result);
-    void TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result);
+    
+    void TransformBlock( unsigned char* data, long counter, unsigned char* result );
+    
+    void TransformFinalBlock( unsigned char* data, long length, long counter, unsigned char* result );
 
 public:
-    CSHA1();
-    ~CSHA1();
+
+    CSHA1( );
+    
+    virtual ~CSHA1( );
+
 };
 
-#endif
-
+#endif // __GEMALTO_SHA1__

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,78 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "digest.h"
-#include "sha256.h"
-
-CSHA256::CSHA256(){
-    this->_hashValue     = (CK_BYTE_PTR)malloc(SHA256_HASH_LENGTH);
-    this->_workingBuffer = (CK_BYTE_PTR)malloc(SHA256_BLOCK_LENGTH);
-    this->_hashLength    = SHA256_HASH_LENGTH;
-    this->_blockLength   = SHA256_BLOCK_LENGTH;
-}
-
-CSHA256::~CSHA256(){
-}
-
-void CSHA256::TransformBlock(CK_BYTE_PTR data,CK_LONG counter,CK_BYTE_PTR result)
-{
-    algo_sha256_context* ctx = (algo_sha256_context*)malloc(sizeof(algo_sha256_context));
-
-    ctx->digest = (u4*)result;
-
-    if (counter == 0) {
-		algo_sha256_starts(ctx);
-    } else {
-        ctx->total[0] = counter;
-        ctx->total[1] = 0;
-    }
-
-    algo_sha256_update(ctx, data, SHA256_BLOCK_LENGTH);
-
-    free((u1*)ctx);
-}
-
-void CSHA256::TransformFinalBlock(CK_BYTE_PTR data,CK_LONG length,CK_LONG counter,CK_BYTE_PTR result)
-{
-    algo_sha256_context* ctx = (algo_sha256_context*)malloc(sizeof(algo_sha256_context));
-
-    ctx->digest = (u4*)result;
-
-    if (counter == 0) {
-		algo_sha256_starts(ctx);
-    } else {
-        ctx->total[0] = counter;
-        ctx->total[1] = 0;
-    }
-
-    // allocate tempory working buffer
-    ctx->input = (u1*)malloc(SHA256_BLOCK_LENGTH);
-    memset(ctx->input, 0,SHA256_BLOCK_LENGTH);
-
-    // warning: algo_sha1_update must not throw any exception.
-    algo_sha256_update(ctx, data, length);
-    algo_sha256_finish(ctx);
-
-    free(ctx->input);
-    free((u1*)ctx);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,2949 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifdef __APPLE__
-#include <PCSC/winscard.h>
-#else
-#include <winscard.h>
-#endif
-#include "cardmoduleservice.h"
-
-#include <assert.h>
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "thread.h"
-#include "event.h"
-#include "template.h"
-#include "digest.h"
-#include "sha1.h"
-#include "sha256.h"
-#include "md5.h"
-#include "session.h"
-#include "slot.h"
-#include "dataobject.h"
-#include "secretkeyobject.h"
-#include "rsaprivatekeyobject.h"
-#include "rsapublickeyobject.h"
-#include "x509pubkeycertobject.h"
-#include "application.h"
-#include "transaction.h"
-#include "log.h"
-#include "error.h"
-
-#ifdef _XCL_
-#include "xcl_utils.h"
-#endif // _XCL_
-
-CK_MECHANISM_TYPE MechanismList[] = {
-   CKM_RSA_PKCS_KEY_PAIR_GEN, // 0
-   CKM_RSA_PKCS,              // 1
-   CKM_RSA_X_509,             // 2
-   CKM_MD5_RSA_PKCS,          // 3
-   CKM_SHA1_RSA_PKCS,         // 4
-   CKM_SHA256_RSA_PKCS,       // 5
-#ifdef ENABLE_DIGEST
-   CKM_MD5,                   // 6
-   CKM_SHA_1,                 // 7
-   CKM_SHA256,                // 8
-#endif
-#ifdef ENABLE_SYMMETRIC
-   CKM_AES_KEY_GEN,           // 9
-   CKM_AES_ECB,               // 10
-   CKM_AES_CBC,               // 11
-   CKM_AES_CBC_PAD,           // 12
-   CKM_DES_KEY_GEN,           // 13
-   CKM_DES_ECB,               // 14
-   CKM_DES_CBC,               // 15
-   CKM_DES_CBC_PAD,           // 16
-   CKM_DES2_KEY_GEN,          // 17
-   CKM_DES3_KEY_GEN,          // 18
-   CKM_DES3_ECB,              // 19
-   CKM_DES3_CBC,              // 20
-   CKM_DES3_CBC_PAD           // 21
-#endif
-};
-
-CK_MECHANISM_INFO MechanismInfo[] = {
-   {/* 0 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_GENERATE_KEY_PAIR},
-#ifdef ENABLE_SYMMETRIC
-   {/* 1 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER | CKF_WRAP | CKF_UNWRAP},
-   {/* 2 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_SIGN | CKF_VERIFY | CKF_SIGN_RECOVER | CKF_VERIFY_RECOVER | CKF_WRAP | CKF_UNWRAP},
-#else
-   {/* 1 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_SIGN | /*CKF_SIGN_RECOVER |*/ CKF_VERIFY /*| CKF_VERIFY_RECOVER*/},
-   {/* 2 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_SIGN | /*CKF_SIGN_RECOVER |*/ CKF_VERIFY /*| CKF_VERIFY_RECOVER*/},
-#endif
-   {/* 3 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_SIGN | CKF_VERIFY},
-   {/* 4 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_SIGN | CKF_VERIFY},
-   {/* 5 */  RSA_KEY_MIN_LENGTH,RSA_KEY_MAX_LENGTH, CKF_HW | CKF_SIGN | CKF_VERIFY},
-#ifdef ENABLE_DIGEST
-   {/* 6 */  0,0, CKF_SW | CKF_DIGEST},
-   {/* 7 */  0,0, CKF_SW | CKF_DIGEST},
-   {/* 8 */  0,0, CKF_SW | CKF_DIGEST},
-#endif
-#ifdef ENABLE_SYMMETRIC
-   {/* 9 */  16,32, CKF_HW | CKF_GENERATE},
-   {/* 10 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 11 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 12 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 13 */  0,0, CKF_HW | CKF_GENERATE},
-   {/* 14 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 15 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 16 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 17 */  0,0, CKF_HW | CKF_GENERATE},
-   {/* 18 */  0,0, CKF_HW | CKF_GENERATE},
-   {/* 19 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 20 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP},
-   {/* 21 */  0,0, CKF_HW | CKF_ENCRYPT  | CKF_DECRYPT | CKF_WRAP | CKF_UNWRAP}
-#endif
-};
-
-#define MAKE_SESSIONHANDLE(H,S)         (H | (S << 24))
-#define GET_SESSIONID(H)                (H & 0x00FFFFFF)
-#define GET_SLOTID(H)                   ((H & 0xFF000000) >> 24)
-
-//#define CHECK_IF_NULL_SESSION(A,S)      if(A->_sessions[S] == NULL_PTR){return CKR_SESSION_HANDLE_INVALID;}
-#define CHECK_IF_NULL_SESSION(A,S) try \
-   { \
-      if( A->_sessions.at( S ) == NULL_PTR ) \
-      { \
-         return CKR_SESSION_HANDLE_INVALID; \
-      } \
-   } \
-   catch( ... ) \
-   { \
-      return CKR_SESSION_HANDLE_INVALID; \
-   } \
-
-#define CHECK_IF_TOKEN_IS_PRESENT(S)    if(S->_token == NULL_PTR){return CKR_TOKEN_NOT_PRESENT;}
-
-Slot::Slot()
-{
-   // initialize the fields
-
-   CK_ULONG idx;
-
-   this->_token = NULL_PTR;
-   this->_readerName = NULL_PTR;
-
-   _sessions.resize(1,NULL_PTR);   // First element is dummy
-
-   // initialize this slot
-   this->_slotId = 0;
-   this->_slotInfo.firmwareVersion.major = 0;
-   this->_slotInfo.firmwareVersion.minor = 0;
-   this->_slotInfo.flags                 = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
-   this->_slotInfo.hardwareVersion.major = 0;
-   this->_slotInfo.hardwareVersion.minor = 0;
-
-   for(idx=0;idx<64;idx++)
-      this->_slotInfo.slotDescription[idx] = ' ';
-
-   this->_slotInfo.manufacturerID[0] = 'U';
-   this->_slotInfo.manufacturerID[1] = 'n';
-   this->_slotInfo.manufacturerID[2] = 'k';
-   this->_slotInfo.manufacturerID[3] = 'n';
-   this->_slotInfo.manufacturerID[4] = 'o';
-   this->_slotInfo.manufacturerID[5] = 'w';
-   this->_slotInfo.manufacturerID[6] = 'n';
-
-   for(idx=7;idx<32;idx++){
-      this->_slotInfo.manufacturerID[idx] = ' ';
-   }
-
-#ifdef INCLUDE_EVENTING
-   this->_tracker = NULL_PTR;
-   this->_event   = CK_FALSE;
-#endif
-
-}
-
-Slot::~Slot( )
-{
-   Log::begin( "Slot::~Slot" );
-
-   if(this->_token != NULL_PTR)
-   {
-      delete this->_token;
-      this->_token = NULL_PTR;
-   }
-
-#ifdef INCLUDE_EVENTING
-   if(this->_tracker != NULL_PTR)
-   {
-      delete this->_tracker;
-      this->_tracker = NULL_PTR;
-   }
-#endif
-
-   if(this->_readerName != NULL_PTR)
-   {
-      delete this->_readerName;
-      this->_readerName = NULL_PTR;
-   }
-
-   // destroy all opened sessions
-   for(size_t i=1;i<_sessions.size();i++)
-   {
-      if( this->_sessions[i] != NULL_PTR)
-      {
-         delete this->_sessions[i];
-         this->_sessions[i] = NULL_PTR;
-      }
-   }
-
-   Log::end( "Slot::~Slot" );
-}
-
-
-#ifdef INCLUDE_EVENTING
-
-void Slot::SetEvent(CK_BBOOL event)
-{
-   this->_event = event;
-}
-
-CK_BBOOL Slot::GetEvent()
-{
-   return this->_event;
-}
-
-void Slot::Clear()
-{
-   // close all the sessions when card is removed
-   this->CloseAllSessions();
-
-   if(this->_token != NULL_PTR)
-   {
-      delete this->_token;
-      this->_token = NULL_PTR;
-   }
-}
-
-#endif
-
-CK_RV Slot::GetInfo(CK_SLOT_INFO_PTR pInfo)
-{
-   CK_BYTE idx;
-
-   // Check Parameters
-   if(pInfo == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   for(idx=0;idx<64;idx++)
-   {
-      pInfo->slotDescription[idx] = this->_slotInfo.slotDescription[idx];
-   }
-
-   for(idx=0;idx<32;idx++)
-   {
-      pInfo->manufacturerID[idx]  = this->_slotInfo.manufacturerID[idx];
-   }
-
-   pInfo->hardwareVersion.major = this->_slotInfo.hardwareVersion.major;
-   pInfo->hardwareVersion.minor = this->_slotInfo.hardwareVersion.minor;
-   pInfo->firmwareVersion.major = this->_slotInfo.firmwareVersion.major;
-   pInfo->firmwareVersion.minor = this->_slotInfo.firmwareVersion.minor;
-
-   // it turns out that we need to dynamically poll if
-   // token is present or not. rest of the information should not
-   // change since we enumerated
-   SCARD_READERSTATE readerStates;
-
-   readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-   readerStates.szReader = this->_readerName->c_str();
-
-   // lets check if token is present
-#ifndef _XCL_
-
-   if (SCardGetStatusChange(Application::_hContext, 0, &readerStates, 1) == SCARD_S_SUCCESS)
-   {
-      if ((readerStates.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT)
-      {
-         // we found a card in this reader
-         this->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-      }
-      else
-      {
-         // No card in reader
-         this->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-         CloseAllSessions();
-      }
-   }
-
-#else // _XCL_
-
-    PRINT_MSG("IN Slot::GetInfo");
-    if (xCL_IsTokenPresent())
-    {
-        // we found a card in this reader
-        this->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-    }
-    else
-    {
-        // No card in reader
-        this->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-    }
-
-#endif // _XCL_
-
-   pInfo->flags = this->_slotInfo.flags;
-
-   return CKR_OK;
-}
-
-
-CK_RV Slot::GetTokenInfo( CK_TOKEN_INFO_PTR pInfo )
-{
-   Log::begin( "Slot::GetTokenInfo" );
-
-   checkConnection( this );
-
-   // Check Parameters
-   if( NULL_PTR == pInfo )
-   {
-      Log::error( "Slot::GetTokenInfo", "CKR_ARGUMENTS_BAD" );
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   //Log::log( "Slot::GetTokenInfo - BuildToken..." );
-   //printf( "\n Slot::GetTokenInfo - BuildToken \n" );
-   CK_RV rv = this->BuildToken( );
-   //Log::log( "Slot::GetTokenInfo - BuildToken <%#02x>", rv );
-   if( CKR_OK == rv )
-   {
-      //Transaction trans( this );
-
-      Log::log( "Slot::GetTokenInfo - 1" );
-
-      CK_BYTE idx;
-
-      pInfo->firmwareVersion.major = this->_token->_tokenInfo.firmwareVersion.major;
-      pInfo->firmwareVersion.minor = this->_token->_tokenInfo.firmwareVersion.minor;
-      pInfo->hardwareVersion.major = this->_token->_tokenInfo.hardwareVersion.major;
-      pInfo->hardwareVersion.minor = this->_token->_tokenInfo.hardwareVersion.minor;
-
-      Log::log( "Slot::GetTokenInfo - 2" );
-
-      // label
-      for(idx=0;idx<32;idx++)
-      {
-         pInfo->label[idx] = this->_token->_tokenInfo.label[idx];
-      }
-      Log::log( "Slot::GetTokenInfo - 3" );
-
-      // manufacturerID
-      for(idx=0;idx<32;idx++)
-      {
-         pInfo->manufacturerID[idx]  = this->_token->_tokenInfo.manufacturerID[idx];
-      }
-      Log::log( "Slot::GetTokenInfo - 4" );
-
-      // model
-      for(idx=0;idx<16;idx++)
-      {
-         pInfo->model[idx]  = this->_token->_tokenInfo.model[idx];
-      }
-      Log::log( "Slot::GetTokenInfo - 5" );
-
-      // serial number
-      for(idx=0;idx<16;idx++)
-      {
-         pInfo->serialNumber[idx]  = this->_token->_tokenInfo.serialNumber[idx];
-      }
-      Log::log( "Slot::GetTokenInfo - 6" );
-
-      pInfo->ulFreePrivateMemory  = this->_token->_tokenInfo.ulFreePrivateMemory;
-      pInfo->ulFreePublicMemory   = this->_token->_tokenInfo.ulFreePublicMemory;
-      pInfo->ulMaxPinLen          = this->_token->_tokenInfo.ulMaxPinLen;
-      pInfo->ulMinPinLen          = this->_token->_tokenInfo.ulMinPinLen;
-      pInfo->ulMaxRwSessionCount  = CK_EFFECTIVELY_INFINITE;
-      pInfo->ulSessionCount       = 0;
-      pInfo->ulMaxSessionCount    = CK_EFFECTIVELY_INFINITE;
-      pInfo->ulRwSessionCount     = 0;
-      pInfo->ulTotalPrivateMemory = this->_token->_tokenInfo.ulTotalPrivateMemory;
-      pInfo->ulTotalPublicMemory  = this->_token->_tokenInfo.ulTotalPublicMemory;
-
-      Log::log( "Slot::GetTokenInfo - 7" );
-
-      for(size_t i=1;i<_sessions.size();i++)
-      {
-         if( NULL_PTR != _sessions[ i ] )
-         {
-            ++pInfo->ulSessionCount;
-            if(_sessions[i]->_isReadWrite)
-               ++pInfo->ulRwSessionCount;
-         }
-      }
-      Log::log( "Slot::GetTokenInfo - 8" );
-
-      // utcTime
-      for(idx=0;idx<16;idx++)
-      {
-         pInfo->utcTime[idx]  = this->_token->_tokenInfo.utcTime[idx];
-      }
-      Log::log( "Slot::GetTokenInfo - 9" );
-
-      bool bIsAuthenticated = this->_token->isAuthenticated( );
-      Log::log( "Slot::GetTokenInfo - IsNoPinSupported <%d>", this->_token->m_bIsNoPinSupported );
-      Log::log( "Slot::GetTokenInfo - IsSSO <%d>", this->_token->m_bIsSSO );
-      Log::log( "Slot::GetTokenInfo - IsAuthenticated <%d>", bIsAuthenticated );
-
-      // Check if the smart card is in SSO mode
-      if(   ( true == this->_token->m_bIsNoPinSupported ) 
-         || ( ( true == this->_token->m_bIsSSO ) && ( true == bIsAuthenticated ) )
-         )
-      {
-         this->_token->_tokenInfo.flags &= ~CKF_LOGIN_REQUIRED;
-         Log::log( "Slot::GetTokenInfo - No login required" );
-      }
-      else
-      {
-         this->_token->_tokenInfo.flags |= CKF_LOGIN_REQUIRED;
-         Log::log( "Slot::GetTokenInfo - Login required" );
-      }
-      pInfo->flags = this->_token->_tokenInfo.flags;
-      //Log::log( "Slot::GetTokenInfo - tokenInfo formated ok" );
-   }
-
-   //Log::logCK_RV( "Slot::GetTokenInfo", rv );
-   Log::end( "Slot::GetTokenInfo" );
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::GetMechanismList(CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount)
-{
-   if(pulCount == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   if(pMechanismList == NULL_PTR)
-   {
-      *pulCount = (sizeof(MechanismList)/sizeof(CK_ULONG));
-   }
-   else
-   {
-      if(*pulCount < (sizeof(MechanismList)/sizeof(CK_ULONG)))
-      {
-         *pulCount = (sizeof(MechanismList)/sizeof(CK_ULONG));
-         return CKR_BUFFER_TOO_SMALL;
-      }
-
-      for(size_t i=0;i<(sizeof(MechanismList)/sizeof(CK_ULONG));i++)
-      {
-         pMechanismList[i] = MechanismList[i];
-      }
-      *pulCount = (sizeof(MechanismList)/sizeof(CK_ULONG));
-   }
-
-   return CKR_OK;
-}
-
-
-/*
-*/
-CK_RV Slot::GetMechanismInfo(CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo)
-{
-   if(pInfo == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   size_t i = 0;
-   CK_BBOOL found = CK_FALSE;
-   for( ;i<(sizeof(MechanismList)/sizeof(CK_ULONG));i++)
-   {
-      if(MechanismList[i] == type)
-      {
-         found = CK_TRUE;
-         break;
-      }
-   }
-
-   if(found == CK_FALSE)
-   {
-      return CKR_MECHANISM_INVALID;
-   }
-
-   pInfo->ulMinKeySize = MechanismInfo[i].ulMinKeySize;
-   pInfo->ulMaxKeySize = MechanismInfo[i].ulMaxKeySize;
-   pInfo->flags  = MechanismInfo[i].flags;
-
-   return CKR_OK;
-}
-
-
-CK_RV Slot::InitToken(CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel)
-{
-   CK_RV rv = CKR_OK;
-
-   checkConnection( this );
-
-   if(pPin == NULL_PTR || ulPinLen == 0 || pLabel == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   // check if we have an open session
-   for(size_t i=1;i<_sessions.size();i++){
-      if(this->_sessions[i] != NULL_PTR){
-         return CKR_SESSION_EXISTS;
-      }
-   }
-
-   //printf( "\n Slot::InitToken - BuildToken \n" );
-   rv = this->BuildToken();
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   u1Array* pin = new u1Array(ulPinLen);
-   pin->SetBuffer(pPin);
-
-   u1Array* label = new u1Array(32);
-   label->SetBuffer(pLabel);
-
-   // Don't do the Transaction here.
-
-   rv = this->_token->InitToken(pin,label);
-
-   delete pin;
-   delete label;
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::OpenSession( CK_FLAGS flags, CK_VOID_PTR, CK_NOTIFY, CK_SESSION_HANDLE_PTR phSession )
-{
-   checkConnection( this );
-
-   if(phSession == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   if( ( flags & CKF_SERIAL_SESSION ) != CKF_SERIAL_SESSION )
-   {
-      return CKR_SESSION_PARALLEL_NOT_SUPPORTED;
-   }
-
-   //printf( "\n Slot::OpenSession - BuildToken \n" );
-   CK_RV rv = this->BuildToken( );
-   if( rv != CKR_OK )
-   {
-      return rv;
-   }
-
-   Transaction trans( this );
-
-   // if admin is logged we can not open RO session
-   CK_BBOOL rwSession = ((flags & CKF_RW_SESSION) == CKF_RW_SESSION);
-
-   if( ( this->_token->_roleLogged == CKU_SO ) && ( !rwSession ) )
-   {
-      return CKR_SESSION_READ_WRITE_SO_EXISTS;
-   }
-
-   // Create the session instance
-   Session* session = new Session( rwSession );
-
-   // lets create a session
-   s4 sessionId = this->AddSession( session );
-   if( 0 == sessionId )
-   {
-      return CKR_SESSION_COUNT;
-   }
-
-   session->SetId(sessionId);
-   session->SetSlot(this);
-
-    // prepare a unique session id
-   *phSession = MAKE_SESSIONHANDLE(sessionId,this->_slotId);
-
-   // Refresh the state of the session if the SSO mode is enabled or No pin is required
-   //UpdateAuthenticationState( );
-   if(   ( CKU_USER == this->_token->_roleLogged )
-      || ( true == this->_token->m_bIsNoPinSupported ) 
-      || ( ( true == this->_token->m_bIsSSO ) && ( true == this->_token->isAuthenticated( ) ) )
-      )
-   {
-      UpdateSessionState( CKU_USER );
-   }
-   else if( CKU_SO == this->_token->_roleLogged )
-   {
-      UpdateSessionState( CKU_SO );
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::CloseSession( CK_SESSION_HANDLE hSession )
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-
-   if( CKR_OK == rv )
-   {
-      CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-      CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-
-      pSlot->RemoveSession( hSessionId );
-
-      // Refresh the state of the session if the SSO mode is enabled
-      //pSlot->UpdateAuthenticationState( );
-   }
-
-   return rv;
-}
-
-
-///*
-//Check first if the card is in SSO mode then update the state of all sessions
-//*/
-//void Slot::UpdateAuthenticationState( void )
-//{
-//   if(   ( true == this->_token->_roleLogged )
-//      || ( true == this->_token->m_bIsNoPinSupported ) 
-//      || ( ( true == this->_token->m_bIsSSO ) && ( true == this->_token->isAuthenticated( ) ) )
-//      )
-//   {
-//      UpdateSessionState( CKU_USER );
-//   }
-//}
-
-
-/*
-*/
-CK_RV Slot::CloseAllSessions(void)
-{
-   //if( NULL != this->_token )
-   //{
-   //   this->_token->ManageGC( true );
-   //}
-
-   // remove all sessions
-   for( size_t i = 1 ; i < _sessions.size( ) ; i++ )
-   {
-      if( NULL_PTR != this->_sessions[ i ] )
-      {
-         delete this->_sessions[ i ];
-         this->_sessions[ i ] = NULL_PTR;
-      }
-      //this->_sessions[ i ] = NULL_PTR;
-   }
-
-   _sessions.resize( 1 );
-
-   CHECK_IF_TOKEN_IS_PRESENT( this );
-
-   this->_token->_roleLogged = CKU_NONE;
-
-   //// Refresh the state of the session if the SSO mode is enabled
-   //UpdateAuthenticationState( );
-   //// Update the state of all sessions
-   //UpdateSessionState( );
-
-   return CKR_OK;
-}
-
-
-/*
-*/
-CK_RV Slot::GetSessionInfo( CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo )
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-
-   if( CKR_OK != rv )
-   {
-      return rv;
-   }
-
-   if(pInfo == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId);
-
-   // JCD
-   //Transaction trans( pSlot );
-
-   pInfo->slotID = pSlot->_slotId;
-   pInfo->ulDeviceError = CKR_OK;
-
-   // JCD
-   // Check if the smart card is in SSO mode
-   //pSlot->UpdateAuthenticationState( );
-
-   pInfo->flags = ( ( pSlot->_sessions[ hSessionId ]->_isReadWrite ) ? CKF_RW_SESSION : 0 ) | (CKF_SERIAL_SESSION);
-   pInfo->state = pSlot->_sessions[ hSessionId ]->_state;
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::Login( CK_SESSION_HANDLE hSession,
-                   CK_USER_TYPE userType,
-                   CK_UTF8CHAR_PTR pPin,
-                   CK_ULONG ulPinLen )
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-
-   if( true == pSlot->_token->m_bIsNoPinSupported )
-   {
-      return CKR_OK; //CKR_USER_ALREADY_LOGGED_IN;
-   }
-   if( ( true == pSlot->_token->m_bIsSSO ) && ( true == pSlot->_token->isAuthenticated( ) ) )
-   {
-      return CKR_USER_ALREADY_LOGGED_IN;
-   }
-
-   Transaction trans( pSlot );
-
-   if(userType == CKU_SO)
-   {
-      if(pSlot->HasReadOnlySession())
-      {
-         return CKR_SESSION_READ_ONLY_EXISTS;
-      }
-   }
-
-   if( NULL_PTR == pPin )
-   {
-      ulPinLen = 0;
-   }
-
-   u1Array* pinValue = new u1Array(ulPinLen);
-   u1* pinValueBuffer = pinValue->GetBuffer();
-   CK_BYTE idx = 0;
-   for(idx=0;idx<ulPinLen;idx++)
-   {
-      pinValueBuffer[idx] = pPin[idx];
-   }
-   rv = pSlot->_token->Login(userType,pinValue);
-
-   if(rv == CKR_OK || rv == CKR_USER_ALREADY_LOGGED_IN)
-   {
-      if(userType == CKU_SO)
-      {
-         // cache SO PIN for the duration of this session
-         pSlot->_sessions[ hSessionId ]->_soPIN = new u1Array(pinValue->GetLength());
-         pSlot->_sessions[ hSessionId ]->_soPIN->SetBuffer(pinValue->GetBuffer());
-      }
-   }
-
-   if(rv == CKR_OK)
-   {
-      pSlot->UpdateSessionState();
-   }
-
-   delete pinValue;
-
-   return rv;
-}
-
-
-
-CK_RV Slot::Logout( CK_SESSION_HANDLE hSession )
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   rv = pSlot->_token->Logout( );
-
-   pSlot->UpdateSessionState( );
-
-   return rv;
-}
-
-
-CK_RV Slot::InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   if(pPin == NULL_PTR || ulPinLen == 0){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   if(session->_state != CKS_RW_SO_FUNCTIONS)
-   {
-      return CKR_USER_NOT_LOGGED_IN;
-   }
-
-   PKCS11_ASSERT(session->_soPIN != NULL_PTR);
-
-   u1Array* pin = new u1Array(ulPinLen);
-   pin->SetBuffer(pPin);
-
-   rv = pSlot->_token->InitPIN(session->_soPIN,pin);
-
-   delete pin;
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::SetPIN( CK_SESSION_HANDLE hSession,
-                    CK_UTF8CHAR_PTR pOldPin,
-                    CK_ULONG ulOldLen,
-                    CK_UTF8CHAR_PTR pNewPin,
-                    CK_ULONG ulNewLen )
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   if(pOldPin == NULL_PTR || ulOldLen == 0 || pNewPin == NULL_PTR || ulNewLen == 0)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   CK_ULONG state = pSlot->_sessions[ hSessionId ]->_state;
-
-   if((state != CKS_RW_PUBLIC_SESSION) &&
-      (state != CKS_RW_SO_FUNCTIONS)&&
-      (state != CKS_RW_USER_FUNCTIONS))
-   {
-      return CKR_SESSION_READ_ONLY;
-   }
-
-   u1Array* oldPin = new u1Array(ulOldLen);
-   oldPin->SetBuffer(pOldPin);
-
-   u1Array* newPin = new u1Array(ulNewLen);
-   newPin->SetBuffer(pNewPin);
-
-   rv = pSlot->_token->SetPIN(oldPin,newPin);
-
-   delete oldPin;
-   delete newPin;
-
-   return rv;
-}
-
-
-CK_RV  Slot::FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   
-   Transaction trans( pSlot );
-
-   if((pTemplate == NULL_PTR) && (ulCount != 0))
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   // check if search is active for this session or not
-   if(session->IsSearchActive() == CK_TRUE)
-   {
-      return CKR_OPERATION_ACTIVE;
-   }
-
-   Template* searchTmpl = NULL_PTR;
-   if(ulCount != 0)
-   {
-      searchTmpl = new Template(pTemplate,ulCount);
-   }
-
-   session->SetSearchTemplate(searchTmpl);
-
-   return rv;
-}
-
-
-
-CK_RV  Slot::FindObjects(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject,
-                         CK_ULONG ulMaxObjectCount,CK_ULONG_PTR  pulObjectCount)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   if((phObject == NULL_PTR) || (pulObjectCount == NULL_PTR))
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-
-   // Not needed here...
-   // JCD 1
-   //Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   // check if search is active for this session or not
-   if(session->IsSearchActive() == CK_FALSE)
-   {
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   *pulObjectCount = 0;
-
-   // find the token objects matching the template
-   // count will tell how much of the phObject buffer was written
-   CK_ULONG count = pSlot->_token->FindObjects( session, phObject, ulMaxObjectCount, pulObjectCount );
-
-   if(count < ulMaxObjectCount)
-   {
-      // find the session objects matching the template
-      count = session->FindObjects(count,phObject,ulMaxObjectCount,pulObjectCount);
-   }
-
-   return rv;
-}
-
-
-
-CK_RV  Slot::FindObjectsFinal(CK_SESSION_HANDLE hSession)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-
-   // Not needed here
-   // Transaction trans(slot);
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   // check if search is active for this session or not
-   if(session->IsSearchActive() == CK_FALSE)
-   {
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   session->RemoveSearchTemplate();
-
-   return rv;
-}
-
-CK_RV Slot::GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR randomData,CK_ULONG ulRandomLen)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   if((randomData == NULL_PTR) || (ulRandomLen == 0))
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   return pSlot->_token->GenerateRandom(randomData,ulRandomLen);
-}
-
-
-
-CK_RV Slot::CreateObject( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject )
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   checkConnection( pSlot );
-
-  if(rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   // check the pointer arguments
-   if((pTemplate == NULL_PTR) || (ulCount == 0) || (phObject == NULL_PTR))
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   // Check Template Consitency
-   rv = Template::CheckTemplate(pTemplate, ulCount, MODE_CREATE);
-   if (rv != CKR_OK)
-   {
-      return rv;
-   }
-
-   CK_ULONG classVal = Template::FindClassFromTemplate(pTemplate,ulCount);
-   PKCS11_ASSERT(classVal != -1);
-
-   auto_ptr<StorageObject> object;
-
-   switch(classVal){
-
-        case CKO_DATA:
-           object = auto_ptr<StorageObject>(new DataObject());
-           break;
-
-        case CKO_SECRET_KEY:
-           object = auto_ptr<StorageObject>(new SecretKeyObject());
-           break;
-
-        case CKO_PUBLIC_KEY:
-           object = auto_ptr<StorageObject>(new RSAPublicKeyObject());
-           break;
-
-        case CKO_PRIVATE_KEY:
-           object = auto_ptr<StorageObject>(new RSAPrivateKeyObject());
-           break;
-
-        case CKO_CERTIFICATE:
-           object = auto_ptr<StorageObject>(new X509PubKeyCertObject());
-           break;
-
-        default:
-           PKCS11_ASSERT(CK_FALSE);
-           break;
-   }
-
-   CK_BBOOL objCreationFailed = CK_FALSE;
-   CK_BYTE idx;
-   for(idx = 0; idx < ulCount; idx++)
-   {
-      if((rv = object->SetAttribute(pTemplate[idx],CK_TRUE)) != CKR_OK){
-         objCreationFailed = CK_TRUE;
-         break;
-      }
-   }
-
-   if(objCreationFailed)
-   {
-      return rv;
-   }
-
-   switch(object->_class)
-   {
-        case CKO_PUBLIC_KEY:
-           if(((RSAPublicKeyObject*)object.get())->_keyType != CKK_RSA)
-           {
-              return CKR_KEY_TYPE_INCONSISTENT;
-           }
-           break;
-
-        case CKO_PRIVATE_KEY:
-           if(((RSAPrivateKeyObject*)object.get())->_keyType != CKK_RSA)
-           {
-              return CKR_KEY_TYPE_INCONSISTENT;
-           }
-           break;
-   }
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   // if this is a readonly session and
-   // user is not logged then only public session objects
-   // can be created
-   if(session->_isReadWrite == CK_FALSE)
-   {
-      if(object->_tokenObject)
-      {
-         return CKR_SESSION_READ_ONLY;
-      }
-   }
-
-   if( CK_TRUE == object->_private )
-   {
-      if( false == pSlot->_token->m_bIsNoPinSupported )
-      {
-         if(   ( CKU_USER != pSlot->_token->_roleLogged )
-            && ( ( true == pSlot->_token->m_bIsSSO ) && ( false == pSlot->_token->isAuthenticated( ) ) )
-            )
-         {
-            return CKR_USER_NOT_LOGGED_IN;
-         }
-      }
-   }
-   /*if ((pSlot->_token->_roleLogged != CKU_USER) && (object->_private == CK_TRUE))
-   {
-      return CKR_USER_NOT_LOGGED_IN;
-   }
-   */
-
-   if(object->_tokenObject)
-   {
-
-      // any type of token object cannot be created
-      // unless user is logged in
-
-      // NOTE : Not PKCS#11 compilance
-      // CardModule service does not allow 'deletion' of any file unless user is logged in. We can create a file
-      // when nobody is logged in but we can not delete. In order to be symmetrical we do not also allow
-      // the creation.
-      if( false == pSlot->_token->m_bIsNoPinSupported )
-      {
-         if(   ( CKU_USER != pSlot->_token->_roleLogged )
-            && ( ( true == pSlot->_token->m_bIsSSO ) && ( false == pSlot->_token->isAuthenticated( ) ) )
-            )
-         {
-            return CKR_USER_NOT_LOGGED_IN;
-         }
-      }
-
-      // some sanity checks
-      if(object->_class == CKO_PRIVATE_KEY)
-      {
-         rv = pSlot->_token->AddPrivateKeyObject(object, phObject);
-      }
-      else if(object->_class == CKO_CERTIFICATE)
-      {
-         rv = pSlot->_token->AddCertificateObject(object, phObject);
-      }
-      else
-      {
-         rv = pSlot->_token->AddObject(object, phObject);
-      }
-   }
-   else
-   {
-      rv = session->AddObject(object.get(),phObject);
-      if(rv == CKR_OK)
-         object.release();
-   }
-
-   //printf( "\nSlot::CreateObject - ManageGC( true )\n" );
-    pSlot->_token->ManageGC( true );
-
-   return rv;
-}
-
-
-
-CK_RV Slot::DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   // from object handle we can determine
-   // if it is a token object or session object
-   CK_BBOOL istoken = ((hObject & CO_TOKEN_OBJECT) == CO_TOKEN_OBJECT);
-
-   // if this is a readonly session and
-   // user is not logged then only public session objects
-   // can be created
-   if(session->_isReadWrite == CK_FALSE)
-   {
-      if(istoken)
-      {
-         return CKR_SESSION_READ_ONLY;
-      }
-   }
-
-   if(istoken)
-   {
-      rv = pSlot->_token->DeleteObject(hObject);
-   }
-   else
-   {
-      rv = session->DeleteObject(hObject);
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::GetAttributeValue( CK_SESSION_HANDLE hSession,
-                               CK_OBJECT_HANDLE hObject,
-                               CK_ATTRIBUTE_PTR pTemplate,
-                               CK_ULONG ulCount )
-{
-   if(pTemplate == NULL_PTR || ulCount == 0)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   // from object handle we can determine
-   // if it is a token object or session object
-   CK_BBOOL istoken = ((hObject & CO_TOKEN_OBJECT) == CO_TOKEN_OBJECT);
-
-   // TBD : Attributes of types such as Array which have not be initialized ?
-   // for eg label
-
-   if(istoken)
-   {
-      rv = pSlot->_token->GetAttributeValue(hObject,pTemplate,ulCount);
-   }
-   else
-   {
-      rv = session->GetAttributeValue(hObject,pTemplate,ulCount);
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::SetAttributeValue( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount )
-{
-   if(pTemplate == NULL_PTR || ulCount == 0)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-  if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* pSession = pSlot->_sessions[ hSessionId ];
-
-   // From object handle we can determine if it is a token object or session object
-   CK_BBOOL istoken = ( ( hObject & CO_TOKEN_OBJECT ) == CO_TOKEN_OBJECT );
-   if( TRUE == istoken )
-   {
-      if( CK_FALSE == pSession->_isReadWrite )
-      {
-         return CKR_SESSION_READ_ONLY;
-      }
-
-      rv = pSlot->_token->SetAttributeValue( hObject, pTemplate, ulCount );
-   }
-   else
-   {
-      rv = pSession->SetAttributeValue( hObject, pTemplate, ulCount );
-   }
-
-   return rv;
-}
-
-
-CK_RV Slot::GenerateKeyPair(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pPublicKeyTemplate,
-                            CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,
-                            CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey)
-{
-   // Since MODULUS_BITS is an essential attribute pPublicKeyTemplate should never be NULL or ulPublicKeyAttributeCount
-   // should not be zero. For private key template there is not compuslary attributes to be specified so it can be
-   // NULL_PTR
-
-   if((pMechanism == NULL_PTR) || (pPublicKeyTemplate == NULL_PTR) ||
-      (ulPublicKeyAttributeCount == 0) || (phPublicKey == NULL_PTR) ||
-      (phPrivateKey == NULL_PTR))
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   if(pMechanism->mechanism != CKM_RSA_PKCS_KEY_PAIR_GEN)
-      return CKR_MECHANISM_INVALID;
-
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   //Session* session = pSlot->_sessions[ hSessionId ];
-
-   // Check Public Template Consitency
-   rv = Template::CheckTemplate(pPublicKeyTemplate, ulPublicKeyAttributeCount, MODE_GENERATE_PUB);
-   if (rv != CKR_OK)
-      return rv;
-
-   // Check Private Template Consitency
-   rv = Template::CheckTemplate(pPrivateKeyTemplate, ulPrivateKeyAttributeCount, MODE_GENERATE_PRIV);
-   if (rv != CKR_OK)
-      return rv;
-
-   auto_ptr<StorageObject> rsaPubKey(new RSAPublicKeyObject());
-   for(u4 i=0;i<ulPublicKeyAttributeCount;i++){
-      rv = rsaPubKey->SetAttribute(pPublicKeyTemplate[i],CK_TRUE);
-      if(rv != CKR_OK){
-         return rv;
-      }
-   }
-
-   auto_ptr<StorageObject> rsaPrivKey(new RSAPrivateKeyObject());
-   for(u4 i=0;i<ulPrivateKeyAttributeCount;i++){
-      rv = rsaPrivKey->SetAttribute(pPrivateKeyTemplate[i],CK_TRUE);
-      if(rv != CKR_OK){
-         return rv;
-      }
-   }
-
-   if(rsaPrivKey->_tokenObject){
-      rv = pSlot->_token->GenerateKeyPair(rsaPubKey,rsaPrivKey,phPublicKey,phPrivateKey);
-   }else{
-
-      // We do not support generation of key pair in the software
-      // TBD: Should we ?. I have noticed that during the import of
-      // p12 file using firefox it asks you to generate it in session
-
-      return CKR_ATTRIBUTE_VALUE_INVALID;
-   }
-
-   if(rv == CKR_OK)
-   {
-      if(rsaPubKey.get() && !rsaPubKey->_tokenObject)
-      {
-         pSlot->_sessions[ hSessionId ]->AddObject(rsaPubKey.get(),phPublicKey);
-         rsaPubKey.release();
-      }
-   }
-   return rv;
-}
-
-// ------------------------------------------------------------------------------------------------
-//                                  DIGEST RELATED FUNCTIONS
-// ------------------------------------------------------------------------------------------------
-CK_RV Slot::DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism)
-{
-   if(pMechanism == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   // Not needed
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   if(session->IsDigestActive()){
-      return CKR_OPERATION_ACTIVE;
-   }
-
-   switch(pMechanism->mechanism){
-
-        case CKM_SHA_1:
-           session->SetDigest(new CSHA1());
-           break;
-
-        case CKM_SHA256:
-           session->SetDigest(new CSHA256());
-           break;
-
-        case CKM_MD5:
-           session->SetDigest(new CMD5());
-           break;
-
-        default:
-           return CKR_MECHANISM_INVALID;
-
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::Digest(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,
-                   CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)
-{
-   if((pData == NULL_PTR) || (ulDataLen == 0) || (pulDigestLen == NULL_PTR)){
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsDigestActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   CDigest* digest = session->_digest;
-
-   if((*pulDigestLen < (CK_ULONG)digest->HashLength()) && (pDigest != NULL_PTR)){
-      *pulDigestLen = (CK_ULONG)digest->HashLength();
-      return CKR_BUFFER_TOO_SMALL;
-   }
-   else if(!pDigest){
-      *pulDigestLen = digest->HashLength();
-      return CKR_OK;
-   }
-
-   digest->HashCore(pData, 0, ulDataLen);
-
-   *pulDigestLen = (CK_ULONG)digest->HashLength();
-
-   if (pDigest != NULL_PTR)
-   {
-      digest->HashFinal(pDigest);
-      session->RemoveDigest();
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)
-{
-   if(pPart == NULL_PTR || ulPartLen == 0)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsDigestActive() == CK_FALSE)
-   {
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   session->_digest->HashCore(pPart,0,ulPartLen);
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen)
-{
-   if(pulDigestLen == NULL_PTR)
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   if(session->IsDigestActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   CDigest*    digest   = session->_digest;
-
-   if((*pulDigestLen < (CK_ULONG)digest->HashLength()) && (pDigest != NULL_PTR)){
-      *pulDigestLen = (CK_ULONG)digest->HashLength();
-      return CKR_BUFFER_TOO_SMALL;
-   }
-   else if(!pDigest){
-      *pulDigestLen = digest->HashLength();
-      return CKR_OK;
-   }
-
-   *pulDigestLen = (CK_ULONG)digest->HashLength();
-
-   if (pDigest != NULL_PTR){
-      digest->HashFinal(pDigest);
-      session->RemoveDigest();
-   }
-
-   return rv;
-}
-
-// ------------------------------------------------------------------------------------------------
-//                                  SIGNATURE RELATED FUNCTIONS
-// ------------------------------------------------------------------------------------------------
-CK_RV Slot::SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
-   if(pMechanism == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-   if(session->IsSignatureActive() == CK_TRUE){
-      return CKR_OPERATION_ACTIVE;
-   }
-
-   rv = Slot::IsValidMechanism(pMechanism->mechanism,CKF_SIGN);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   if( false == pSlot->_token->m_bIsNoPinSupported )
-   {
-      if(   ( CKU_USER != pSlot->_token->_roleLogged )
-         && ( ( true == pSlot->_token->m_bIsSSO ) && ( false == pSlot->_token->isAuthenticated( ) ) )
-         )
-      {
-         return CKR_USER_NOT_LOGGED_IN;
-      }
-   }
-   //if(pSlot->_token->_roleLogged != CKU_USER)
-   //{
-   //   return CKR_USER_NOT_LOGGED_IN;
-   //}
-
-   // get the corresponding object
-   StorageObject* object = NULL_PTR;
-
-   // from object handle we can determine
-   // if it is a token object or session object
-   CK_BBOOL istoken = ((hKey & CO_TOKEN_OBJECT) == CO_TOKEN_OBJECT);
-
-   if(istoken){
-      rv = pSlot->_token->GetObject(hKey,&object);
-   }else{
-      rv = session->GetObject(hKey,&object);
-   }
-
-   if(rv != CKR_OK){
-
-      if(rv == CKR_OBJECT_HANDLE_INVALID){
-         return CKR_KEY_HANDLE_INVALID;
-      }
-
-      return rv;
-   }
-
-   rv = Slot::IsValidCryptoOperation(object,CKF_SIGN);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   // let's initialize this crypto operation
-   session->SetSignatureOperation(new CryptoOperation(pMechanism->mechanism,object));
-
-   if(pMechanism->mechanism == CKM_SHA1_RSA_PKCS){
-      session->SetDigestRSA(new CSHA1());
-   }else if(pMechanism->mechanism == CKM_SHA256_RSA_PKCS){
-      session->SetDigestRSA(new CSHA256());
-   }else if(pMechanism->mechanism == CKM_MD5_RSA_PKCS){
-      session->SetDigestRSA(new CMD5());
-   }
-
-   return rv;
-}
-
-
-
-CK_RV Slot::Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,
-                 CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsSignatureActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   if(pData == NULL_PTR || ulDataLen == 0 || pulSignatureLen == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   StorageObject* object = session->_signature->GetObject();
-
-   PKCS11_ASSERT(object->_class == CKO_PRIVATE_KEY);
-
-   CK_ULONG mechanism = session->_signature->GetMechanism();
-
-   // TBD : Private key may not necessarily have the modulus or modulus bits
-   // if that is the case then we need to locate the corresponding public key
-   // or may be I should always put the modulus bits in private key attributes
-
-   u1Array* modulus = ((RSAPrivateKeyObject*)object)->_modulus;
-
-   PKCS11_ASSERT(modulus != NULL_PTR);
-
-   if(((mechanism == CKM_RSA_PKCS) && (ulDataLen > modulus->GetLength() - 11)) ||
-      ((mechanism == CKM_RSA_X_509) && (ulDataLen > modulus->GetLength())))
-   {
-      return CKR_DATA_LEN_RANGE;
-   }
-
-   if(pSignature == NULL_PTR){
-      *pulSignatureLen = modulus->GetLength();
-      return CKR_OK;
-   }else{
-      if(*pulSignatureLen < modulus->GetLength()){
-         *pulSignatureLen = modulus->GetLength();
-         return CKR_BUFFER_TOO_SMALL;
-      }
-   }
-
-   u1Array* dataToSign = NULL_PTR;
-
-   if(session->IsDigestRSAActive() == CK_TRUE){
-      // require hashing also
-      CK_BYTE_PTR hash   = NULL_PTR;
-      CDigest* digest = session->_digestRSA;
-
-      hash = (CK_BYTE_PTR)malloc(digest->HashLength());
-
-      digest->HashCore(pData,0,ulDataLen);
-      digest->HashFinal(hash);
-
-      dataToSign  = new u1Array(digest->HashLength());
-      dataToSign->SetBuffer(hash);
-
-      free(hash);
-   }
-   // Sign Only
-   else {
-      dataToSign = new u1Array(ulDataLen);
-      dataToSign->SetBuffer(pData);
-   }
-
-   rv = pSlot->_token->Sign(session->_signature->GetObject(),dataToSign,session->_signature->GetMechanism(),pSignature);
-
-   if(rv == CKR_OK){
-      *pulSignatureLen = modulus->GetLength();
-   }
-
-   session->RemoveDigestRSA();
-   session->RemoveSignatureOperation();
-
-   delete dataToSign;
-
-   return rv;
-}
-
-
-
-CK_RV Slot::SignUpdate(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULONG ulPartLen)
-{
-   // what we do here is to update the hash or
-   // if hashing is not getting used we just accumulate it
-
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsSignatureActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   if(pPart == NULL_PTR || ulPartLen == 0){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   if(session->IsDigestRSAActive() == CK_TRUE){
-      CDigest* digest = session->_digestRSA;
-      digest->HashCore(pPart,0,ulPartLen);
-   }
-   // Sign Only
-   else {
-
-      if(session->_accumulatedDataToSign != NULL_PTR){
-         // just accumulate the data
-         u1Array* updatedData = new u1Array(session->_accumulatedDataToSign->GetLength() + ulPartLen);
-         memcpy(updatedData->GetBuffer(),session->_accumulatedDataToSign->GetBuffer(),session->_accumulatedDataToSign->GetLength());
-
-         memcpy((u1*)&updatedData->GetBuffer()[session->_accumulatedDataToSign->GetLength()],pPart,ulPartLen);
-
-         delete session->_accumulatedDataToSign;
-
-         session->_accumulatedDataToSign = updatedData;
-      }else{
-
-         session->_accumulatedDataToSign = new u1Array(ulPartLen);
-         session->_accumulatedDataToSign->SetBuffer(pPart);
-      }
-
-      CK_ULONG mech = session->_signature->GetMechanism();
-      u1Array* modulus = ((RSAPrivateKeyObject*)session->_signature->GetObject())->_modulus;
-
-      if(((mech == CKM_RSA_PKCS) && (session->_accumulatedDataToSign->GetLength() > modulus->GetLength() - 11)) ||
-         ((mech == CKM_RSA_X_509) && (session->_accumulatedDataToSign->GetLength() > modulus->GetLength())))
-      {
-         return CKR_DATA_LEN_RANGE;
-      }
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsSignatureActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   if(pulSignatureLen == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   StorageObject* object = session->_signature->GetObject();
-
-   PKCS11_ASSERT(object->_class == CKO_PRIVATE_KEY);
-
-
-   // TBD : Private key may not necessarily have the modulus or modulus bits
-   // if that is the case then we need to locate the corresponding public key
-   // or may be I should always put the modulus bits in private key attributes
-
-   u1Array* modulus = ((RSAPrivateKeyObject*)object)->_modulus;
-
-   PKCS11_ASSERT(modulus != NULL_PTR);
-
-   if(pSignature == NULL_PTR){
-      *pulSignatureLen = modulus->GetLength();
-      return CKR_OK;
-   }else{
-      if(*pulSignatureLen < modulus->GetLength()){
-         *pulSignatureLen = modulus->GetLength();
-         return CKR_BUFFER_TOO_SMALL;
-      }
-   }
-
-   u1Array* dataToSign = NULL_PTR;
-
-   if(session->IsDigestRSAActive() == CK_TRUE){
-      // require hashing also
-      CK_BYTE_PTR hash   = NULL_PTR;
-      CDigest* digest = session->_digestRSA;
-
-      hash = (CK_BYTE_PTR)malloc(digest->HashLength());
-
-      digest->HashFinal(hash);
-
-      dataToSign  = new u1Array(digest->HashLength());
-      dataToSign->SetBuffer(hash);
-
-      free(hash);
-   }
-   // Sign Only
-   else {
-      dataToSign = session->_accumulatedDataToSign;
-   }
-
-   rv = pSlot->_token->Sign(session->_signature->GetObject(),dataToSign,session->_signature->GetMechanism(),pSignature);
-
-   if(rv == CKR_OK){
-      *pulSignatureLen = modulus->GetLength();
-   }
-
-   session->RemoveDigestRSA();
-   session->RemoveSignatureOperation();
-
-   delete dataToSign;
-   session->_accumulatedDataToSign = NULL_PTR;
-
-   return rv;
-}
-
-
-
-CK_RV Slot::EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
-   if(pMechanism == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsEncryptionActive() == CK_TRUE){
-      return CKR_OPERATION_ACTIVE;
-   }
-
-   rv = Slot::IsValidMechanism(pMechanism->mechanism,CKF_ENCRYPT);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   if( false == pSlot->_token->m_bIsNoPinSupported )
-   {
-      if(   ( CKU_USER != pSlot->_token->_roleLogged )
-         && ( ( true == pSlot->_token->m_bIsSSO ) && ( false == pSlot->_token->isAuthenticated( ) ) )
-         )
-      {
-         return CKR_USER_NOT_LOGGED_IN;
-      }
-   }
-   //if(pSlot->_token->_roleLogged != CKU_USER)
-   //{
-   //   return CKR_USER_NOT_LOGGED_IN;
-   //}
-
-   // get the corresponding object
-   StorageObject* object = NULL_PTR;
-
-   // from object handle we can determine
-   // if it is a token object or session object
-   CK_BBOOL istoken = ((hKey & CO_TOKEN_OBJECT) == CO_TOKEN_OBJECT);
-
-   if(istoken){
-      rv = pSlot->_token->GetObject(hKey,&object);
-   }else{
-      rv = session->GetObject(hKey,&object);
-   }
-
-   if(rv != CKR_OK){
-      if(rv == CKR_OBJECT_HANDLE_INVALID){
-         return CKR_KEY_HANDLE_INVALID;
-      }
-
-      return rv;
-   }
-
-   rv = Slot::IsValidCryptoOperation(object,CKF_ENCRYPT);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   // let's initialize this crypto operation
-   session->SetEncryptionOperation(new CryptoOperation(pMechanism->mechanism,object));
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,
-                    CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen)
-{
-   if(pData == NULL_PTR || ulDataLen == 0 || pulEncryptedDataLen == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-    if(rv != CKR_OK)
-   {
-      return rv;
-   }
-  checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsEncryptionActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   StorageObject* object = session->_encryption->GetObject();
-
-   PKCS11_ASSERT(object->_class == CKO_PUBLIC_KEY);
-
-   //CK_ULONG mechanism = session->_encryption->GetMechanism();
-
-   u1Array* modulus = ((RSAPublicKeyObject*)object)->_modulus;
-
-   PKCS11_ASSERT(modulus != NULL_PTR);
-
-   if(pEncryptedData == NULL_PTR){
-      *pulEncryptedDataLen = modulus->GetLength();
-      return CKR_OK;
-   }else{
-      if(*pulEncryptedDataLen < modulus->GetLength()){
-         *pulEncryptedDataLen = modulus->GetLength();
-         return CKR_BUFFER_TOO_SMALL;
-      }
-   }
-
-   u1Array* dataToEncrypt = new u1Array(ulDataLen);
-   dataToEncrypt->SetBuffer(pData);
-
-   rv = pSlot->_token->Encrypt(session->_encryption->GetObject(),dataToEncrypt,session->_encryption->GetMechanism(),pEncryptedData);
-
-   if(rv == CKR_OK){
-      *pulEncryptedDataLen = modulus->GetLength();
-   }
-
-   session->RemoveEncryptionOperation();
-
-   delete dataToEncrypt;
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
-   if(pMechanism == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsDecryptionActive() == CK_TRUE){
-      return CKR_OPERATION_ACTIVE;
-   }
-
-   rv = Slot::IsValidMechanism(pMechanism->mechanism,CKF_DECRYPT);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   if( false == pSlot->_token->m_bIsNoPinSupported )
-   {
-      if(   ( CKU_USER != pSlot->_token->_roleLogged )
-         && ( ( true == pSlot->_token->m_bIsSSO ) && ( false == pSlot->_token->isAuthenticated( ) ) )
-         )
-      {
-         return CKR_USER_NOT_LOGGED_IN;
-      }
-   }
-   //if(pSlot->_token->_roleLogged != CKU_USER)
-   //{
-   //   return CKR_USER_NOT_LOGGED_IN;
-   //}
-
-   // get the corresponding object
-   StorageObject* object = NULL_PTR;
-
-   // from object handle we can determine
-   // if it is a token object or session object
-   CK_BBOOL istoken = ((hKey & CO_TOKEN_OBJECT) == CO_TOKEN_OBJECT);
-
-   if(istoken){
-      rv = pSlot->_token->GetObject(hKey,&object);
-   }else{
-      rv = session->GetObject(hKey,&object);
-   }
-
-   if(rv != CKR_OK){
-      if(rv == CKR_OBJECT_HANDLE_INVALID){
-         return CKR_KEY_HANDLE_INVALID;
-      }
-
-      return rv;
-   }
-
-   rv = Slot::IsValidCryptoOperation(object,CKF_DECRYPT);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   // let's initialize this crypto operation
-   session->SetDecryptionOperation(new CryptoOperation(pMechanism->mechanism,object));
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,
-                    CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen)
-{
-   if(pEncryptedData == NULL_PTR || ulEncryptedDataLen == 0 ||pulDataLen == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsDecryptionActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   StorageObject* object = session->_decryption->GetObject();
-
-   PKCS11_ASSERT(object->_class == CKO_PRIVATE_KEY);
-
-   CK_ULONG mechanism = session->_decryption->GetMechanism();
-
-   // TBD : Private key may not necessarily have the modulus or modulus bits
-   // if that is the case then we need to locate the corresponding public key
-   // or may be I should always put the modulus bits in private key attributes
-
-   u1Array* modulus = ((RSAPrivateKeyObject*)object)->_modulus;
-
-   PKCS11_ASSERT(modulus != NULL_PTR);
-
-   // [HB]: Fix length of return value
-   if(mechanism == CKM_RSA_PKCS){
-      // Can't know exact size of returned value before decryption has been done
-      if(pData == NULL_PTR){
-         *pulDataLen = modulus->GetLength() - 11;
-         return CKR_OK;
-      }
-   }
-   else if(mechanism == CKM_RSA_X_509){
-      if(pData == NULL_PTR){
-         *pulDataLen = modulus->GetLength();
-         return CKR_OK;
-      }else{
-         if(*pulDataLen < modulus->GetLength()){
-            *pulDataLen = modulus->GetLength();
-            return CKR_BUFFER_TOO_SMALL;
-         }
-      }
-   }
-   else
-      return CKR_MECHANISM_INVALID;
-
-   if(ulEncryptedDataLen != modulus->GetLength()){
-      return CKR_ENCRYPTED_DATA_LEN_RANGE;
-   }
-
-   u1Array* dataToDecrypt = new u1Array(ulEncryptedDataLen);
-   dataToDecrypt->SetBuffer(pEncryptedData);
-
-   rv = pSlot->_token->Decrypt(session->_decryption->GetObject(),dataToDecrypt,session->_decryption->GetMechanism(),pData, pulDataLen);
-
-   session->RemoveDecryptionOperation();
-
-   delete dataToDecrypt;
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV  Slot::VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey)
-{
-   if(pMechanism == NULL_PTR){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-    if(rv != CKR_OK)
-   {
-      return rv;
-   }
-  checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsVerificationActive() == CK_TRUE){
-      return CKR_OPERATION_ACTIVE;
-   }
-
-   rv = Slot::IsValidMechanism(pMechanism->mechanism,CKF_VERIFY);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   if( false == pSlot->_token->m_bIsNoPinSupported )
-   {
-      if(   ( CKU_USER != pSlot->_token->_roleLogged )
-         && ( ( true == pSlot->_token->m_bIsSSO ) && ( false == pSlot->_token->isAuthenticated( ) ) )
-         )
-      {
-         return CKR_USER_NOT_LOGGED_IN;
-      }
-   }
-   //if(pSlot->_token->_roleLogged != CKU_USER)
-   //{
-   //   return CKR_USER_NOT_LOGGED_IN;
-   //}
-
-   // get the corresponding object
-   StorageObject* object = NULL_PTR;
-
-   // from object handle we can determine
-   // if it is a token object or session object
-   CK_BBOOL istoken = ((hKey & CO_TOKEN_OBJECT) == CO_TOKEN_OBJECT);
-
-   if(istoken){
-      rv = pSlot->_token->GetObject(hKey,&object);
-   }else{
-      rv = session->GetObject(hKey,&object);
-   }
-
-   if(rv != CKR_OK){
-
-      if(rv == CKR_OBJECT_HANDLE_INVALID){
-         return CKR_KEY_HANDLE_INVALID;
-      }
-
-      return rv;
-   }
-
-   rv = Slot::IsValidCryptoOperation(object,CKF_VERIFY);
-
-   if(rv != CKR_OK){
-      return rv;
-   }
-
-   // let's initialize this crypto operation
-   session->SetVerificationOperation(new CryptoOperation(pMechanism->mechanism,object));
-
-   if(pMechanism->mechanism == CKM_SHA1_RSA_PKCS){
-      session->SetDigestRSAVerification(new CSHA1());
-   }else if(pMechanism->mechanism == CKM_SHA256_RSA_PKCS){
-      session->SetDigestRSAVerification(new CSHA256());
-   }else if(pMechanism->mechanism == CKM_MD5_RSA_PKCS){
-      session->SetDigestRSAVerification(new CMD5());
-   }
-
-   return CKR_OK;
-
-}
-
-
-/*
-*/
-CK_RV  Slot::Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,
-                    CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsVerificationActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   if((pData == NULL_PTR) || (ulDataLen == 0) ||
-      (pSignature == NULL_PTR) || (ulSignatureLen == 0))
-   {
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   CK_ULONG mechanism = session->_verification->GetMechanism();
-
-
-   // I am doubtful regarding these 3 lines as
-   // the object could be privatekey which contains
-   // the public components
-   StorageObject* object = session->_verification->GetObject();
-   PKCS11_ASSERT(object->_class == CKO_PUBLIC_KEY);
-   u1Array* modulus = ((RSAPublicKeyObject*)object)->_modulus;
-
-   PKCS11_ASSERT(modulus != NULL_PTR);
-
-   if(((mechanism == CKM_RSA_PKCS) && (ulDataLen > modulus->GetLength() - 11)) ||
-      ((mechanism == CKM_RSA_X_509) && (ulDataLen > modulus->GetLength())))
-   {
-      return CKR_DATA_LEN_RANGE;
-   }
-
-   u1Array* dataToVerify = NULL_PTR;
-
-   if(session->IsDigestRSAVerificationActive() == CK_TRUE){
-      // require hashing also
-      CK_BYTE_PTR hash   = NULL_PTR;
-      CDigest* digest = session->_digestRSAVerification;
-
-      hash = (CK_BYTE_PTR)malloc(digest->HashLength());
-
-      digest->HashCore(pData,0,ulDataLen);
-      digest->HashFinal(hash);
-
-      dataToVerify  = new u1Array(digest->HashLength());
-      dataToVerify->SetBuffer(hash);
-
-      free(hash);
-   }
-   // Sign Only
-   else {
-      dataToVerify = new u1Array(ulDataLen);
-      dataToVerify->SetBuffer(pData);
-   }
-
-   u1Array* signature = new u1Array(ulSignatureLen);
-   signature->SetBuffer(pSignature);
-
-   rv = pSlot->_token->Verify(session->_verification->GetObject(),dataToVerify,session->_verification->GetMechanism(),signature);
-
-   delete signature;
-
-   session->RemoveDigestRSAVerification();
-   session->RemoveVerificationOperation();
-
-   delete dataToVerify;
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen)
-{
-
-   // what we do here is to update the hash or
-   // if hashing is not getting used we just accumulate it
-
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsVerificationActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   if(pPart == NULL_PTR || ulPartLen == 0){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   if(session->IsDigestRSAVerificationActive() == CK_TRUE){
-      CDigest* digest = session->_digestRSAVerification;
-      digest->HashCore(pPart,0,ulPartLen);
-   }
-   // Sign Only
-   else {
-
-      if(session->_accumulatedDataToVerify != NULL_PTR){
-         // just accumulate the data
-         u1Array* updatedData = new u1Array(session->_accumulatedDataToVerify->GetLength() + ulPartLen);
-         memcpy(updatedData->GetBuffer(),session->_accumulatedDataToVerify->GetBuffer(),session->_accumulatedDataToVerify->GetLength());
-
-         memcpy((u1*)&updatedData->GetBuffer()[session->_accumulatedDataToVerify->GetLength()],pPart,ulPartLen);
-
-         delete session->_accumulatedDataToVerify;
-
-         session->_accumulatedDataToVerify = updatedData;
-      }else{
-
-         session->_accumulatedDataToVerify = new u1Array(ulPartLen);
-         session->_accumulatedDataToVerify->SetBuffer(pPart);
-      }
-
-      CK_ULONG mech = session->_verification->GetMechanism();
-      u1Array* modulus = ((RSAPublicKeyObject*)session->_verification->GetObject())->_modulus;
-
-      if(((mech == CKM_RSA_PKCS) && (session->_accumulatedDataToVerify->GetLength() > modulus->GetLength() - 11)) ||
-         ((mech == CKM_RSA_X_509) && (session->_accumulatedDataToVerify->GetLength() > modulus->GetLength())))
-      {
-         return CKR_DATA_LEN_RANGE;
-      }
-   }
-
-   return rv;
-}
-
-
-/*
-*/
-CK_RV Slot::VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen)
-{
-   CK_SESSION_HANDLE hSessionId = CK_INVALID_HANDLE;
-   Slot* pSlot = NULL_PTR;
-   CK_RV rv = GetSlotAndSessionIdFromSessionHandle( hSession, &pSlot, &hSessionId );
-   if(rv != CKR_OK)
-   {
-      return rv;
-   }
-   checkConnection( pSlot );
-
-   CHECK_IF_TOKEN_IS_PRESENT( pSlot );
-   CHECK_IF_NULL_SESSION( pSlot, hSessionId );
-   Transaction trans( pSlot );
-
-   Session* session = pSlot->_sessions[ hSessionId ];
-
-
-   if(session->IsVerificationActive() == CK_FALSE){
-      return CKR_OPERATION_NOT_INITIALIZED;
-   }
-
-   if((pSignature == NULL_PTR) || (ulSignatureLen == 0)){
-      return CKR_ARGUMENTS_BAD;
-   }
-
-   //StorageObject* object = session->_verification->GetObject();
-   //PKCS11_ASSERT(object->_class == CKO_PUBLIC_KEY);
-
-   u1Array* dataToVerify = NULL_PTR;
-
-   if(session->IsDigestRSAVerificationActive() == CK_TRUE){
-      // require hashing also
-      CK_BYTE_PTR hash   = NULL_PTR;
-      CDigest* digest = session->_digestRSAVerification;
-
-      hash = (CK_BYTE_PTR)malloc(digest->HashLength());
-
-      digest->HashFinal(hash);
-
-      dataToVerify  = new u1Array(digest->HashLength());
-      dataToVerify->SetBuffer(hash);
-
-      free(hash);
-   }
-   // Sign Only
-   else {
-      dataToVerify = session->_accumulatedDataToVerify;
-   }
-
-   u1Array* signature = new u1Array(ulSignatureLen);
-   signature->SetBuffer(pSignature);
-
-   rv = pSlot->_token->Verify(session->_verification->GetObject(),dataToVerify,session->_verification->GetMechanism(),signature);
-
-   session->RemoveDigestRSAVerification();
-   session->RemoveVerificationOperation();
-
-   delete dataToVerify;
-   delete signature;
-   session->_accumulatedDataToVerify = NULL_PTR;
-
-   return rv;
-}
-
-
-
-// --------------
-
-
-
-/* Return true if the connection is aware
-*/
-/*bool*/ void Slot::checkConnection( Slot* a_pSlot )
-{
-   //Log::begin( "Slot::checkConnection" );
-
-   //bool bRet = false;
-
-   if( NULL_PTR != a_pSlot )
-   {
-      char readers[ 1024 ];
-      memset( readers, 0, sizeof( readers ) );
-      memcpy( readers, a_pSlot->_readerName->c_str( ), a_pSlot->_readerName->length( ) );
-      DWORD dwLen = sizeof( readers );
-      DWORD dwState = 0;
-      DWORD dwProtocol = 0;
-      BYTE Atr[32];
-      memset( Atr, 0, sizeof( Atr ) );
-      DWORD dwLenAtr = sizeof( Atr );
-      if( NULL != a_pSlot->_token )
-      {
-         CardModuleService* pMSCM = a_pSlot->_token->GetMiniDriverService( );
-         if( NULL != pMSCM )
-         {
-            SCARDHANDLE hCard = pMSCM->GetPcscCardHandle( );
-            DWORD hResult = SCardStatus( hCard, readers, &dwLen, &dwState, &dwProtocol, &Atr[0], &dwLenAtr );
-            //Log::log( "Slot::checkConnection - SCardStatus <%#02x>", hResult );
-            //printf( "\n Slot::checkConnection - SCardStatus <%#02x> \n", hResult );
-            if( ( SCARD_W_RESET_CARD == hResult ) || ( SCARD_W_REMOVED_CARD == hResult ) )
-            {
-               Log::error( "Slot::checkConnection", "Connection is broken" );
-               //printf( "\n Slot::checkConnection - Connection is broken \n" );
-
-               // Close all session
-               a_pSlot->CloseAllSessions( );
-
-               // Rebuild the token to restablish the CardModule communication
-               delete a_pSlot->_token;
-               a_pSlot->_token = NULL_PTR;
-
-               //printf( "\n Slot::checkConnection - BuildToken \n" );
-               a_pSlot->BuildToken( );
-
-              // bRet = false;
-            }
-         }
-      }
-   }
-
-   //Log::end( "Slot::checkConnection" );
-
-   //return bRet;
-}
-
-
-CK_LONG Slot::AddSession(Session* session)
-{
-   // 0 is an invalid session handle
-   for(size_t i=1;i<_sessions.size();i++){
-      if(this->_sessions[i] == NULL_PTR){
-         this->_sessions[i] = session;
-         session->UpdateState(this->_token->_roleLogged);
-         return (CK_LONG)i;
-      }
-   }
-
-   // No free elements, add a new
-   _sessions.push_back(session);
-   return (CK_LONG)(_sessions.size()-1);
-}
-
-
-/*
-*/
-void Slot::RemoveSession( CK_LONG sessionId )
-{
-   //this->_token->ManageGC( true );
-
-   delete this->_sessions[ sessionId ];
-   this->_sessions[sessionId] = NULL_PTR;
-
-   // If this was the upper element in the vector, reduce size
-   size_t maxId = 0;
-   for( size_t i = 1 ; i < _sessions.size( ) ; i++ )
-   {
-      if( _sessions[ i ] )
-      {
-         maxId = i;
-      }
-   }
-   if( maxId < _sessions.size( ) - 1 )
-   {
-      _sessions.resize( maxId + 1 );
-   }
-
-   // if this was the last session to be removed
-   // then the login state of token for application
-   // returns to public sessions
-   if( 0 == maxId )
-   {
-      // TBD : Should I call logout here or merely set the flag ?
-      // if I logged the user out from this application
-      // what happens to another application
-      // This is where on-card implementation helps
-
-      PKCS11_ASSERT(this->_token != NULL_PTR);
-
-      this->_token->_roleLogged = CKU_NONE;
-   }
-}
-
-
-/*
-*/
-void Slot::UpdateSessionState( CK_ULONG ulRole )
-{
-   // update the state of all sessions
-   for(size_t i=1;i<_sessions.size();i++){
-      if(this->_sessions[i] != NULL_PTR){
-         this->_sessions[i]->UpdateState( ulRole );
-      }
-   }
-}
-
-
-/*
-*/
-void Slot::UpdateSessionState( )
-{
-   // update the state of all sessions
-   for(size_t i=1;i<_sessions.size();i++){
-      if(this->_sessions[i] != NULL_PTR){
-         this->_sessions[i]->UpdateState(this->_token->_roleLogged);
-      }
-   }
-}
-
-
-CK_BBOOL Slot::HasReadOnlySession()
-{
-   for(size_t i=1;i<_sessions.size();i++){
-      if(this->_sessions[i] != NULL_PTR){
-         if(this->_sessions[i]->_isReadWrite == CK_FALSE){
-            return CK_TRUE;
-         }
-      }
-   }
-
-   return CK_FALSE;
-}
-
-CK_RV Slot::GetSlotAndSessionIdFromSessionHandle(CK_SESSION_HANDLE hSession,
-                                                 Slot** slot,
-                                                 CK_ULONG_PTR sessionId)
-{
-   CK_SLOT_ID slotId  = GET_SLOTID(hSession);
-   *sessionId         = GET_SESSIONID(hSession);
-
-   if(((int)slotId < 0) || (slotId >= CONFIG_MAX_SLOT)){
-      // we return here invalid session handle as
-      // app does not have a notion of slot at this time
-      return CKR_SESSION_HANDLE_INVALID;
-   }
-
-   if (Application::_slotCache[slotId] != NULL_PTR){
-      *slot = Application::_slotCache[slotId];
-
-      if((*sessionId < 1) || (*sessionId >= ((*slot)->_sessions.size()))){
-         return CKR_SESSION_HANDLE_INVALID;
-      }
-      if((*slot)->_sessions[*sessionId]) {
-         return CKR_OK;
-      }
-   }
-
-   return CKR_SESSION_HANDLE_INVALID;
-}
-
-CK_RV Slot::BuildToken(void)
-{
-   Log::begin( "Slot::BuildToken" );
-
-   if(this->_token == NULL_PTR)
-   {
-      SCARD_READERSTATE readerStates;
-      memset( &readerStates, 0, sizeof( SCARD_READERSTATE ) );
-      readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-      readerStates.szReader = this->_readerName->c_str( );
-
-#ifndef _XCL_
-
-      if( SCardGetStatusChange(Application::_hContext, 0, &readerStates, 1) == SCARD_S_SUCCESS)
-      {
-         if ((readerStates.dwEventState & SCARD_STATE_PRESENT) != SCARD_STATE_PRESENT)
-         {
-            // we not found a card in this reader
-            this->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-            //Log::log( "Slot::BuildToken - ((readerStates.dwEventState & SCARD_STATE_PRESENT) != SCARD_STATE_PRESENT)" );
-            Log::logCK_RV( "Slot::BuildToken", CKR_TOKEN_NOT_PRESENT );
-            return CKR_TOKEN_NOT_PRESENT;
-         }
-         else
-         {
-            // we found a card in this reader
-            this->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-         }
-      }
-
-#else // _XCL_
-
-      if (xCL_IsTokenPresent())
-      {
-          // we found a card in this reader
-          this->_slotInfo.flags |= CKF_TOKEN_PRESENT;
-      }
-      else
-      {
-          // we not found a card in this reader
-          this->_slotInfo.flags &= ~CKF_TOKEN_PRESENT;
-          return CKR_TOKEN_NOT_PRESENT;
-      }
-
-#endif // _XCL_
-
-      // TBD: Check if token is a .net smart card
-
-      // token is present in the slot
-      //Log::log( "Slot::BuildToken - new Token..." );
-      this->_token = new Token( this->_readerName );
-      //Log::log( "Slot::BuildToken - new Token ok"  );
-
-      //Log::logCK_RV( "Slot::BuildToken", CKR_OK );
-      //Log::end( "Slot::BuildToken" );
-   }
-
-   Log::end( "Slot::BuildToken" );
-
-   return CKR_OK;
-}
-
-
-CK_RV Slot::IsValidMechanism(CK_ULONG mechanism,CK_ULONG operation)
-{
-   size_t i = 0;
-
-   CK_BBOOL found = CK_FALSE;
-
-   for(;i<sizeof(MechanismList)/sizeof(CK_ULONG);i++){
-      if(MechanismList[i] == mechanism){
-         found = CK_TRUE;
-         break;
-      }
-   }
-
-   if(found == CK_FALSE){
-      return CKR_MECHANISM_INVALID;
-   }
-
-   if((MechanismInfo[i].flags & operation) != operation){
-      return CKR_MECHANISM_INVALID;
-   }
-
-   return CKR_OK;
-}
-
-CK_RV Slot::IsValidCryptoOperation(StorageObject* object,CK_ULONG operation)
-{
-   // Check if key is consistent
-   switch(operation)
-   {
-   case CKF_ENCRYPT:
-   case CKF_VERIFY:
-   case CKF_VERIFY_RECOVER:
-      if(object->_class != CKO_PUBLIC_KEY && object->_class != CKO_SECRET_KEY){
-         return CKR_KEY_TYPE_INCONSISTENT;
-      }
-      break;
-
-   case CKF_DECRYPT:
-   case CKF_SIGN:
-   case CKF_SIGN_RECOVER:
-      if(object->_class != CKO_PRIVATE_KEY && object->_class != CKO_SECRET_KEY){
-         return CKR_KEY_TYPE_INCONSISTENT;
-      }
-      break;
-   }
-
-   // Check if key supports the operation
-   switch(operation)
-   {
-   case CKF_ENCRYPT:
-      if(((object->_class == CKO_PUBLIC_KEY)&&(!((RSAPublicKeyObject*)object)->_encrypt))
-#ifdef ENABLE_SYMMETRIC
-         ||((object->_class == CKO_SECRET_KEY)&&(!((SecretKeyObject*)object)->_encrypt))
-#endif
-         ){
-            return CKR_KEY_FUNCTION_NOT_PERMITTED;
-      }
-      break;
-
-   case CKF_DECRYPT:
-      if(((object->_class == CKO_PRIVATE_KEY)&&(!((RSAPrivateKeyObject*)object)->_decrypt))
-#ifdef ENABLE_SYMMETRIC
-         ||((object->_class == CKO_SECRET_KEY)&&(!((SecretKeyObject*)object)->_decrypt))
-#endif
-         ){
-            return CKR_KEY_FUNCTION_NOT_PERMITTED;
-      }
-      break;
-
-   case CKF_VERIFY:
-      if(((object->_class == CKO_PUBLIC_KEY)&&(!((RSAPublicKeyObject*)object)->_verify))
-#ifdef ENABLE_SYMMETRIC
-         ||((object->_class == CKO_SECRET_KEY)&&(!((SecretKeyObject*)object)->_verify))
-#endif
-         ){
-            return CKR_KEY_FUNCTION_NOT_PERMITTED;
-      }
-      break;
-
-
-   case CKF_VERIFY_RECOVER:
-      if(((object->_class == CKO_PUBLIC_KEY)&&(!((RSAPublicKeyObject*)object)->_verifyRecover))){
-         return CKR_KEY_FUNCTION_NOT_PERMITTED;
-      }
-      break;
-
-
-   case CKF_SIGN:
-      if(((object->_class == CKO_PRIVATE_KEY)&&(!((RSAPrivateKeyObject*)object)->_sign))
-#ifdef ENABLE_SYMMETRIC
-         ||((object->_class == CKO_SECRET_KEY)&&(!((SecretKeyObject*)object)->_sign))
-#endif
-         ){
-            return CKR_KEY_FUNCTION_NOT_PERMITTED;
-      }
-      break;
-
-   case CKF_SIGN_RECOVER:
-      if(((object->_class == CKO_PRIVATE_KEY)&&(!((RSAPrivateKeyObject*)object)->_signRecover))){
-         return CKR_KEY_FUNCTION_NOT_PERMITTED;
-      }
-      break;
-
-   }
-
-   return CKR_OK;
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,413 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_slot_h
-#define _include_slot_h
-
-#include "sctoken.h"
-#include "critsect.h"
-
-#ifdef _XCL_
-#include "xcl_public.h"
-#include <xcl_utils.h>
-#endif // _XCL
-
-class CardMonitoringThread;
-
-class Slot {
-
-public:
-   CK_SLOT_ID              _slotId;
-   CK_SLOT_INFO            _slotInfo;
-   std::string*            _readerName;
-   CK_BBOOL                _event;
-   CardMonitoringThread*   _tracker;
-   vector<Session*>        _sessions;
-   Token*                  _token;
-
-private:
-   CK_LONG AddSession(Session* session);
-   void RemoveSession(CK_LONG sessionId);
-   CK_BBOOL HasReadOnlySession();
-   static /*bool*/ void checkConnection( Slot* a_pSlot );
-
-public:
-   Slot();
-   virtual ~Slot();
-
-   void UpdateSessionState();
-   //void UpdateAuthenticationState( void );
-   void UpdateSessionState( CK_ULONG ulRole );
-
-
-   static void ClearCache(void);
-   static CK_RV GetSlotAndSessionIdFromSessionHandle(CK_SESSION_HANDLE hSession,
-      Slot** slot,CK_ULONG_PTR sessionId);
-
-   static CK_RV IsValidMechanism(CK_ULONG mechanism,CK_ULONG operation);
-   static CK_RV IsValidCryptoOperation(StorageObject* object,CK_ULONG operation);
-
-   CK_BBOOL    GetEvent();
-   void        SetEvent(CK_BBOOL event);
-   CK_SLOT_ID  GetSlotId() { return _slotId;}
-   CK_BBOOL    IsCardPresent() { return ((_slotInfo.flags & CKF_TOKEN_PRESENT) == CKF_TOKEN_PRESENT);}
-   void        Clear(void);
-
-   CK_RV  BuildToken(void);
-
-   CK_RV  GetInfo(CK_SLOT_INFO_PTR pInfo);
-   CK_RV  GetTokenInfo(CK_TOKEN_INFO_PTR pInfo);
-   CK_RV  GetMechanismList(CK_MECHANISM_TYPE_PTR pMechanismList,CK_ULONG_PTR pulCount);
-   CK_RV  GetMechanismInfo(CK_MECHANISM_TYPE type,CK_MECHANISM_INFO_PTR pInfo);
-   CK_RV  OpenSession(CK_FLAGS flags,CK_VOID_PTR pApplication,CK_NOTIFY Notify,CK_SESSION_HANDLE_PTR phSession);
-   static CK_RV  CloseSession(CK_SESSION_HANDLE hSession);
-   CK_RV  CloseAllSessions(void);
-   static CK_RV  GetSessionInfo(CK_SESSION_HANDLE hSession,CK_SESSION_INFO_PTR pInfo);
-
-   static CK_RV  Login(CK_SESSION_HANDLE hSession,CK_USER_TYPE userType,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen);
-   static CK_RV  Logout(CK_SESSION_HANDLE hSession);
-
-   CK_RV InitToken(CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen,CK_UTF8CHAR_PTR pLabel);
-   static CK_RV  InitPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pPin,CK_ULONG ulPinLen);
-   static CK_RV  SetPIN(CK_SESSION_HANDLE hSession,CK_UTF8CHAR_PTR pOldPin,CK_ULONG ulOldLen,
-      CK_UTF8CHAR_PTR pNewPin,CK_ULONG ulNewLen);
-
-   static CK_RV  CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject);
-   static CK_RV  DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject);
-   static CK_RV  GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE  hObject,CK_ATTRIBUTE_PTR  pTemplate,CK_ULONG ulCount);
-   static CK_RV  SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-   static CK_RV  FindObjectsInit(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR  pTemplate,CK_ULONG ulCount);
-   static CK_RV  FindObjects(CK_SESSION_HANDLE  hSession, CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR  pulObjectCount);
-   static CK_RV  FindObjectsFinal(CK_SESSION_HANDLE hSession);
-
-   static CK_RV  GenerateRandom(CK_SESSION_HANDLE hSession,CK_BYTE_PTR RandomData,CK_ULONG ulRandomLen);
-
-   static CK_RV  GenerateKeyPair(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_ATTRIBUTE_PTR pPublicKeyTemplate,
-      CK_ULONG ulPublicKeyAttributeCount,CK_ATTRIBUTE_PTR pPrivateKeyTemplate,CK_ULONG ulPrivateKeyAttributeCount,
-      CK_OBJECT_HANDLE_PTR phPublicKey,CK_OBJECT_HANDLE_PTR phPrivateKey);
-
-   //static CK_RV  WrapKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR  pMechanism,
-   //                      CK_OBJECT_HANDLE  hWrappingKey,CK_OBJECT_HANDLE  hKey,
-   //                      CK_BYTE_PTR pWrappedKey,CK_ULONG_PTR pulWrappedKeyLen);
-
-   //static CK_RV  UnwrapKey(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,
-   //                       CK_OBJECT_HANDLE hUnwrappingKey,CK_BYTE_PTR pWrappedKey,
-   //                       CK_ULONG ulWrappedKeyLen,CK_ATTRIBUTE_PTR pTemplate,
-   //                       CK_ULONG ulAttributeCount,CK_OBJECT_HANDLE_PTR phKey);
-
-   static CK_RV  EncryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE  hKey);
-   static CK_RV  Encrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pEncryptedData,CK_ULONG_PTR pulEncryptedDataLen);
-
-   static CK_RV  DecryptInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR  pMechanism,CK_OBJECT_HANDLE  hKey);
-   static CK_RV  Decrypt(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pEncryptedData,CK_ULONG ulEncryptedDataLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen);
-
-   static CK_RV  SignInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey);
-   static CK_RV  Sign(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen);
-   static CK_RV  SignUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen);
-   static CK_RV  SignFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG_PTR pulSignatureLen);
-
-   static CK_RV  VerifyInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey);
-   static CK_RV  Verify(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen);
-   static CK_RV  VerifyUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen);
-   static CK_RV  VerifyFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen);
-   //static CK_RV  VerifyRecoverInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism,CK_OBJECT_HANDLE hKey);
-   //static CK_RV  VerifyRecover(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pSignature,CK_ULONG ulSignatureLen,CK_BYTE_PTR pData,CK_ULONG_PTR pulDataLen);
-
-   static CK_RV  DigestInit(CK_SESSION_HANDLE hSession,CK_MECHANISM_PTR pMechanism);
-   static CK_RV  Digest(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pData,CK_ULONG ulDataLen,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen);
-   static CK_RV  DigestUpdate(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pPart,CK_ULONG ulPartLen);
-   static CK_RV  DigestFinal(CK_SESSION_HANDLE hSession,CK_BYTE_PTR pDigest,CK_ULONG_PTR pulDigestLen);
-};
-
-#define CARD_PRESENT 1
-#define CARD_ABSENT  2
-
-#define CARD_DETECTION_INSERTED 1
-#define CARD_DETECTION_REMOVED  2
-
-
-#ifdef INCLUDE_EVENTING
-
-extern CCriticalSection _critSect;
-
-class CardMonitoringThread : public CThread
-{
-
-private:
-   CK_BYTE m_bCardState;
-   Slot*   m_slot;
-   SCARDCONTEXT m_hMonitoringContext;
-
-public:
-   // CThread override
-   void stop()
-   {
-      //printf( "%s - %d - %s - m_monitoringContext <%ld>\n", __FILE__, __LINE__, __FUNCTION__, m_hMonitoringContext );
-
-#ifndef _XCL_
-
-      if( 0 != m_hMonitoringContext )
-      {
-         SCardCancel(m_hMonitoringContext);
-         //printf( "%s - %d - %s - SCardCancel\n", __FILE__, __LINE__, __FUNCTION__);
-
-         //printf( "%s - %d - %s - SCardReleaseContext -->\n", __FILE__, __LINE__, __FUNCTION__);
-         //SCardReleaseContext(m_hMonitoringContext);
-         //printf( "%s - %d - %s - SCardReleaseContext <--\n", __FILE__, __LINE__, __FUNCTION__);
-         //m_hMonitoringContext = 0;
-      }
-
-#endif // _XCL_
-
-      CThread::stop();
-   }
-
-   //------------------------------------------------------------------------------
-   //------------------------------------------------------------------------------
-   CardMonitoringThread(const char* nm) //: m_hMonitoringContext(0)
-   {
-      m_hMonitoringContext = 0;
-      m_bCardState = CARD_ABSENT;
-      CThread::setName(nm);
-   }
-
-   //------------------------------------------------------------------------------
-   //------------------------------------------------------------------------------
-   void SetSlot(Slot* slot)
-   {
-      m_slot = slot;
-
-      if(slot->IsCardPresent() == CK_FALSE)
-      {
-         m_bCardState = CARD_ABSENT;
-      }
-      else
-      {
-         m_bCardState = CARD_PRESENT;
-      }
-   }
-
-   //------------------------------------------------------------------------------
-   //------------------------------------------------------------------------------
-   void run()
-   {
-      bool bTrue = true;
-      while( bTrue )
-      {
-         switch(m_bCardState)
-         {
-         case CARD_PRESENT:
-            if(Monitor(CARD_DETECTION_REMOVED) == false)
-            {
-               return;
-            }
-            m_bCardState = CARD_ABSENT;
-
-            // clean the slot, lock during session deletion
-            {
-               CCriticalSectionLocker cslock(_critSect);
-               m_slot->Clear();
-            }
-            break;
-
-         case CARD_ABSENT:
-            if(Monitor(CARD_DETECTION_INSERTED) == false)
-            {
-               return;
-            }
-            m_bCardState = CARD_PRESENT;
-            break;
-         }
-
-         // we fire the event from here
-         m_slot->SetEvent(CK_TRUE);
-         CryptokiEvent.Signal();
-      }
-   }
-
-   //------------------------------------------------------------------------------
-   //------------------------------------------------------------------------------
-
-#ifndef _XCL_
-
-   bool Monitor(BYTE detectionType)
-   {
-
-      // establish monitoring context
-      LONG lReturn = SCardEstablishContext( SCARD_SCOPE_USER, NULL, NULL, &m_hMonitoringContext );
-      //printf( "%s - %d - %s - SCardEstablishContext --> m_hMonitoringContext <%ld>\n", __FILE__, __LINE__,  __FUNCTION__, m_hMonitoringContext);
-
-      //LONG lReturn = SCardEstablishContext(0, NULL, NULL, (LPSCARDCONTEXT)&m_monitoringContext);
-
-      if(lReturn != SCARD_S_SUCCESS)
-      {
-         return false;
-      }
-
-      SCARD_READERSTATE readerStates;
-      readerStates.dwCurrentState = SCARD_STATE_UNAWARE;
-      readerStates.szReader       = this->getName()->c_str();
-      readerStates.pvUserData     = NULL;
-      readerStates.dwEventState   = 0;         // TO INSPECT THIS STATE
-
-      bool bTrue = true;
-      while( bTrue )
-      {
-
-         if((lReturn = SCardGetStatusChange( m_hMonitoringContext, 60*1000, &readerStates, 1 )) != SCARD_S_SUCCESS)
-         {
-            if(lReturn == (LONG)SCARD_E_TIMEOUT)
-            {
-               if(this->isStopRequested() == CK_TRUE)
-               {
-                  SCardReleaseContext(m_hMonitoringContext);
-                  //printf( "%s - %d - %s - SCardReleaseContext\n", __FILE__, __LINE__, __FUNCTION__ );
-                  m_hMonitoringContext = 0;
-                  return false;
-               }
-
-               goto resume;
-            }
-
-            SCardReleaseContext(m_hMonitoringContext);
-            //printf( "%s - %d - %s - SCardReleaseContext\n", __FILE__, __LINE__, __FUNCTION__ );
-            m_hMonitoringContext = 0;
-            return false;
-         }
-
-resume:
-         if((readerStates.dwEventState & SCARD_STATE_CHANGED) == SCARD_STATE_CHANGED)
-         {
-            if((readerStates.dwEventState & SCARD_STATE_UNAVAILABLE) == SCARD_STATE_UNAVAILABLE)
-            {
-               // reader removed
-               SCardReleaseContext(m_hMonitoringContext);
-               //printf( "%s - %d - %s - SCardReleaseContext\n", __FILE__, __LINE__, __FUNCTION__ );
-               m_hMonitoringContext = 0;
-               return true;
-            }
-            else if(((readerStates.dwCurrentState & SCARD_STATE_EMPTY) == SCARD_STATE_EMPTY) &&
-               ((readerStates.dwEventState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT))
-            {
-               if(detectionType == CARD_PRESENT)
-               {
-                  // card is inserted
-                  SCardReleaseContext(m_hMonitoringContext);
-                  //printf( "%s - %d - %s - SCardReleaseContext\n", __FILE__, __LINE__, __FUNCTION__ );
-                  m_hMonitoringContext = 0;
-                  return true;
-               }
-            }
-            else if(((readerStates.dwCurrentState & SCARD_STATE_PRESENT) == SCARD_STATE_PRESENT) &&
-               ((readerStates.dwEventState & SCARD_STATE_EMPTY) == SCARD_STATE_EMPTY))
-            {
-               if(detectionType == CARD_ABSENT)
-               {
-                  // card is removed
-                  SCardReleaseContext(m_hMonitoringContext);
-                  //printf( "%s - %d - %s - SCardReleaseContext\n", __FILE__, __LINE__, __FUNCTION__ );
-                  m_hMonitoringContext = 0;
-                  return true;
-               }
-            }
-         }
-
-         readerStates.dwCurrentState = readerStates.dwEventState ;
-      }
-
-      SCardReleaseContext(m_hMonitoringContext);
-      //printf( "%s - %d - %s - SCardReleaseContext\n", __FILE__, __LINE__, __FUNCTION__ );
-      m_hMonitoringContext = 0;
-      return false;
-   }
-
-#else // _XCL_
-
-    bool Monitor(BYTE detectionType)
-    {
-        BOOL initialTokenPresent;
-        BOOL currentTokenPresent;
-        UINT rv;
-        UINT deviceID2;
-        xCL_DeviceHandle deviceHandle2;
-
-        PRINT_MSG("IN Monitor top");
-
-        initialTokenPresent = false;
-        currentTokenPresent = false;
-
-        deviceHandle2 = 0;
-        deviceID2 = 0;
-        rv = xCL_CreateHandleFromDeviceID(deviceID2, &deviceHandle2);
-        if (rv == 0)
-        {
-            initialTokenPresent = true;
-            currentTokenPresent = true;
-        }
-        rv = xCL_CloseHandle(deviceHandle2);
-
-        while(true)
-        {
-            PRINT_MSG("IN Monitor loop");
-
-            // sleep for some time
-            sleep(500);
-
-            // See if token is present now
-            deviceHandle2 = 0;
-            deviceID2 = 0;
-            rv = xCL_CreateHandleFromDeviceID(deviceID2, &deviceHandle2);
-            if (rv == 0)
-            {
-                currentTokenPresent = true;
-                rv = xCL_CloseHandle(deviceHandle2);
-            }
-            else
-            {
-                currentTokenPresent = false;
-            }
-
-            if (initialTokenPresent == currentTokenPresent)
-            {
-                PRINT_MSG("IN Monitor no change");
-
-                // No change in token state
-                if(this->isStopRequested() == CK_TRUE)
-                {
-                    PRINT_MSG("IN Monitor no change exit");
-                    return false;
-                }
-            }
-            else
-            {
-                PRINT_MSG("IN Monitor yes change");
-                // There is a change ...
-                return true;
-            }
-        }
-    }
-
-#endif // _XCL_
-
-};
-#endif
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,41 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-
-// Determine Processor Endianess
-#include <limits.h>
-#if (UINT_MAX == 0xffffffffUL)
-   typedef unsigned int _u4;
-#else
-#  if (ULONG_MAX == 0xffffffffUL)
-     typedef unsigned long _u4;
-#  else
-#    if (USHRT_MAX == 0xffffffffUL)
-       typedef unsigned short _u4;
-#    endif
-#  endif
-#endif
-
-_u4 endian = 1;
-
-bool IS_LITTLE_ENDIAN = (*((unsigned char *)(&endian))) ? true  : false;
-bool IS_BIG_ENDIAN    = (*((unsigned char *)(&endian))) ? false : true;
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,52 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_stadfx_h
-#define _include_stadfx_h
-
-#ifdef WIN32
-    #include <windows.h>
-    #include <wincrypt.h>
-    #include <assert.h>
-#else
-    #include <stdio.h>
-    #include <stdlib.h>
-    #include <string.h>
-	#ifdef __APPLE__
-	#include <PCSC/winscard.h>
-	#include <PCSC/wintypes.h>
-    #else
-    #include <winscard.h>
-	#endif
-    typedef BYTE *PBYTE;
-#ifndef HAVE_LPCTSTR
-    typedef const char *LPCTSTR;
-#endif
-#ifndef HAVE_LPCSTR
-    typedef LPCTSTR LPCSTR;
-#endif
-
-#endif
-
-extern bool IS_BIG_ENDIAN;
-extern bool IS_LITTLE_ENDIAN;
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,373 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-#include "storageobject.h"
-#include "error.h"
-
-StorageObject::StorageObject()
-{
-    this->_version     = 0;
-    this->_uniqueId    = 0;
-    this->_tokenObject = CK_FALSE;
-    this->_private     = CK_FALSE;
-    this->_modifiable  = CK_TRUE;
-    this->_label       = NULL_PTR;
-}
-
-StorageObject::~StorageObject(){
-
-    if(this->_label != NULL_PTR)
-        delete this->_label;
-
-}
-
-bool StorageObject::IsEqual(const StorageObject * that) const
-{
-    if(_uniqueId != 0 && that->_uniqueId != 0)
-        return (_uniqueId == that->_uniqueId);
-
-    // Only objects that have been stored under p11 directory
-    // will have a non-zero _uniqueId. For other objects, do
-    // a deep comparison based on other attributes. In the base
-    // class, only negative comparison based on _class can be performed.
-    if(_class != that->_class)
-        return false;
-    else
-        throw CkError(CKR_FUNCTION_FAILED);
-}
-
-CK_BBOOL StorageObject::Compare(CK_ATTRIBUTE attribute)
-{
-    switch(attribute.type){
-        case CKA_CLASS:
-            return (this->_class == *(CK_ULONG*)attribute.pValue);
-
-        case CKA_PRIVATE:
-            return (this->_private == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_TOKEN:
-            return (this->_tokenObject == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_MODIFIABLE:
-            return (this->_modifiable == *(CK_BBOOL*)attribute.pValue);
-
-        case CKA_LABEL:
-            if(this->_label->GetLength() == attribute.ulValueLen){
-                return Util::CompareByteArrays(this->_label->GetBuffer(),(CK_BYTE_PTR)attribute.pValue,attribute.ulValueLen);
-            }
-            return CK_FALSE;
-
-        default:
-            return CK_FALSE;
-
-    }
-}
-
-CK_RV StorageObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-    CK_RV rv = CKR_OK;
-
-    if(objCreation == CK_FALSE){
-        switch(attribute.type){
-            case CKA_CLASS:
-            case CKA_PRIVATE:
-            case CKA_TOKEN:
-            case CKA_MODIFIABLE:
-                return CKR_ATTRIBUTE_READ_ONLY;
-        }
-    }
-
-    switch(attribute.type){
-        case CKA_CLASS:
-            break;
-
-        case CKA_PRIVATE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_private = btemp; }
-            }
-            break;
-
-        case CKA_TOKEN:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_tokenObject = btemp; }
-            }
-            break;
-
-        case CKA_MODIFIABLE:
-            {
-                CK_BBOOL btemp = StorageObject::ReadBBoolFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){ this->_modifiable = btemp; }
-            }
-            break;
-
-        case CKA_LABEL:
-            {
-                u1Array* stemp = StorageObject::ReadStringFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){
-                    if(this->_label != NULL_PTR){
-                        delete this->_label;
-                    }
-                    this->_label = stemp;
-                }
-            }
-            break;
-
-        default:
-            return CKR_ATTRIBUTE_TYPE_INVALID;
-
-    }
-
-    return rv;
-}
-
-CK_RV StorageObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-   CK_RV ulRet = CKR_OK;
-
-    switch(attribute->type)
-    {
-        case CKA_CLASS:
-            ulRet = StorageObject::PutULongInAttribute(this->_class,attribute);
-            break;
-
-        case CKA_PRIVATE:
-            ulRet = StorageObject::PutBBoolInAttribute(this->_private,attribute);
-            break;
-
-        case CKA_TOKEN:
-            ulRet = StorageObject::PutBBoolInAttribute(this->_tokenObject,attribute);
-            break;
-
-        case CKA_MODIFIABLE:
-            ulRet = StorageObject::PutBBoolInAttribute(this->_modifiable,attribute);
-            break;
-
-        case CKA_LABEL:
-            ulRet = StorageObject::PutU1ArrayInAttribute(this->_label,attribute);
-            break;
-
-        default:
-           attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-           ulRet = CKR_ATTRIBUTE_TYPE_INVALID;
-           break;
-    }
-
-    return ulRet;
-}
-
-void StorageObject::Serialize(std::vector<u1>* to)
-{
-    // serialize format version
-    Util::PushBBoolInVector(to,this->_version);
-
-    // serialize unique id
-    Util::PushULongLongInVector(to,this->_uniqueId);
-
-    // serialize class attribute
-    Util::PushULongInVector(to,this->_class);
-
-    // serialize private attribute
-    Util::PushBBoolInVector(to,this->_private);
-
-    // serialize token attribute
-    Util::PushBBoolInVector(to,this->_tokenObject);
-
-    // serialize modifiable attribute
-    Util::PushBBoolInVector(to,this->_modifiable);
-
-    // serialize label attribute
-    Util::PushByteArrayInVector(to,this->_label);
-}
-
-void StorageObject::Deserialize(std::vector<u1> from,CK_ULONG_PTR idx)
-{
-    this->_version = Util::ReadBBoolFromVector(from,idx);
-
-    this->_uniqueId = Util::ReadULongLongFromVector(from, idx);
-
-    this->_class = Util::ReadULongFromVector(from,idx);
-
-    this->_private = Util::ReadBBoolFromVector(from,idx);
-
-    this->_tokenObject = Util::ReadBBoolFromVector(from,idx);
-
-    this->_modifiable = Util::ReadBBoolFromVector(from,idx);
-
-    this->_label = Util::ReadByteArrayFromVector(from,idx);
-}
-
-CK_RV StorageObject::PutU1ArrayInAttribute(u1Array* value,CK_ATTRIBUTE_PTR attribute)
-{
-    if(attribute->pValue == NULL_PTR){
-        if(value == NULL_PTR){
-            attribute->ulValueLen = 0;
-        }else{
-            attribute->ulValueLen = value->GetLength();
-        }
-        return CKR_OK;
-    }
-    if(value == NULL_PTR){
-        // I am not sure about it (TBD: Check)
-        attribute->ulValueLen = 0;
-        return CKR_OK;
-    }
-    if(attribute->ulValueLen < value->GetLength()){
-        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-        return CKR_BUFFER_TOO_SMALL;
-    }
-
-    attribute->ulValueLen = value->GetLength();
-    memcpy((CK_BYTE_PTR)attribute->pValue,value->GetBuffer(),attribute->ulValueLen);
-
-    return CKR_OK;
-}
-
-CK_RV StorageObject::PutU4ArrayInAttribute(u4Array* value,CK_ATTRIBUTE_PTR attribute)
-{
-    if(attribute->pValue == NULL_PTR){
-        if(value == NULL_PTR){
-            attribute->ulValueLen = 0;
-        }else{
-            attribute->ulValueLen = (value->GetLength() * 4);
-        }
-        return CKR_OK;
-    }
-    if(value == NULL_PTR){
-        // I am not sure about it (TBD: Check)
-        attribute->ulValueLen = 0;
-        return CKR_OK;
-    }
-    if(attribute->ulValueLen < (value->GetLength() * 4)){
-        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-        return CKR_BUFFER_TOO_SMALL;
-    }
-
-    attribute->ulValueLen = value->GetLength() * 4;
-    memcpy((CK_BYTE_PTR)attribute->pValue,(u1*)value->GetBuffer(),attribute->ulValueLen);
-
-    return CKR_OK;
-}
-
-CK_RV StorageObject::PutBBoolInAttribute(CK_BBOOL value, CK_ATTRIBUTE_PTR attribute)
-{
-    if(attribute->pValue == NULL_PTR){
-        attribute->ulValueLen = sizeof(CK_BBOOL);
-        return CKR_OK;
-    }
-    if(attribute->ulValueLen < sizeof(CK_BBOOL)){
-        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-        return CKR_BUFFER_TOO_SMALL;
-    }
-    attribute->ulValueLen = sizeof(CK_BBOOL);
-    *(CK_BBOOL*)attribute->pValue = value;
-
-    return CKR_OK;
-}
-
-CK_RV StorageObject::PutULongInAttribute(CK_ULONG value, CK_ATTRIBUTE_PTR attribute)
-{
-    if(attribute->pValue == NULL_PTR){
-        attribute->ulValueLen = sizeof(CK_ULONG);
-        return CKR_OK;
-    }
-    if(attribute->ulValueLen < sizeof(CK_ULONG)){
-        attribute->ulValueLen = CK_UNAVAILABLE_INFORMATION; //(CK_LONG)-1;
-        return CKR_BUFFER_TOO_SMALL;
-    }
-    attribute->ulValueLen = sizeof(CK_ULONG);
-    *(CK_ULONG*)attribute->pValue = value;
-
-    return CKR_OK;
-}
-
-CK_ULONG StorageObject::ReadULongFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv)
-{
-    if(attribute.ulValueLen != sizeof(CK_ULONG)){
-        *rv = CKR_ATTRIBUTE_VALUE_INVALID;
-        return 0;
-    }
-
-    return *(CK_ULONG*)attribute.pValue;
-}
-
-CK_BBOOL StorageObject::ReadBBoolFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv)
-{
-    if(attribute.ulValueLen != sizeof(CK_BBOOL)){
-        *rv = CKR_ATTRIBUTE_VALUE_INVALID;
-        return 0;
-    }
-
-    CK_BBOOL val = *(CK_BBOOL*)attribute.pValue;
-
-    if(val != 0x00 && val != 0x01){
-        *rv = CKR_ATTRIBUTE_VALUE_INVALID;
-        return 0;
-    }
-
-    return val;
-}
-
-u1Array* StorageObject::ReadU1ArrayFromAttribute(CK_ATTRIBUTE attribute)
-{
-    u1Array* val = new u1Array(attribute.ulValueLen);
-    val->SetBuffer((CK_BYTE_PTR)attribute.pValue);
-
-    return val;
-}
-
-u1Array* StorageObject::ReadDateFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv)
-{
-    if(attribute.ulValueLen != 8){
-        *rv = CKR_ATTRIBUTE_VALUE_INVALID;
-        return NULL_PTR;
-    }
-
-    return StorageObject::ReadU1ArrayFromAttribute(attribute);
-}
-
-u1Array* StorageObject::ReadStringFromAttribute(CK_ATTRIBUTE attribute,CK_RV* /*rv*/)
-{
-
-    // [HB]: Shall support UTF-8
-
-    //for(u4 i=0;i<attribute.ulValueLen;i++){
-
-    //    CK_BYTE bval = ((CK_BYTE_PTR)attribute.pValue)[i];
-
-    //    if((bval < 0x20)||(bval > 0x7D)||(bval == 0x24)||(bval == 0x40)||(bval == 0x60)){
-    //        *rv = CKR_ATTRIBUTE_VALUE_INVALID;
-    //        return NULL_PTR;
-    //    }
-    //}
-
-    return StorageObject::ReadU1ArrayFromAttribute(attribute);
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,74 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_storageobject_h
-#define _include_storageobject_h
-
-#include <string>
-#include <MarshallerCfg.h>
-#include <Array.h>
-#include <vector>
-
-using namespace std;
-using namespace Marshaller;
-
-class StorageObject {
-
-
-public:
-    CK_BBOOL        _version;       // Version is used to manage evolution of the storage.
-    u8              _uniqueId;      // A random number that identifies this object
-    CK_ULONG		_class;
-    CK_BBOOL		_tokenObject;
-    CK_BBOOL		_private;
-    CK_BBOOL		_modifiable;
-    u1Array*		_label;
-
-    // extra fields (not part of PKCS#11 spec
-    std::string     _fileName;      // name of the file in the card which contains this object
-
-    StorageObject();
-    virtual ~StorageObject();
-
-    virtual bool IsEqual(const StorageObject * that) const;
-    virtual CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-    virtual CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-    virtual CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-    virtual void Serialize(vector<u1>* to);
-    virtual void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-protected:
-    static CK_RV PutU1ArrayInAttribute(u1Array* value,CK_ATTRIBUTE_PTR attribute);
-    static CK_RV PutU4ArrayInAttribute(u4Array* value,CK_ATTRIBUTE_PTR attribute);
-    static CK_RV PutULongInAttribute(CK_ULONG value, CK_ATTRIBUTE_PTR attribute);
-    static CK_RV PutBBoolInAttribute(CK_BBOOL value, CK_ATTRIBUTE_PTR attribute);
-
-    static CK_BBOOL ReadBBoolFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv);
-    static CK_ULONG ReadULongFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv);
-    static u1Array* ReadU1ArrayFromAttribute(CK_ATTRIBUTE attribute);
-    static u1Array* ReadDateFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv);
-    static u1Array* ReadStringFromAttribute(CK_ATTRIBUTE attribute,CK_RV* rv);
-};
-
-
-
-#endif
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,65 +18,82 @@
  *
  */
 
-#include "stdafx.h"
-#include "platconfig.h"
+
+#include <cstdlib>
+#include <cstring>
+
 #include "symmalgo.h"
+#include <memory>
 
-CSymmAlgo::CSymmAlgo(){
-    this->_cipherMode  = CIPHER_MODE_CBC;
-    this->_paddingMode = PADDING_MODE_PKCS7;
-    this->_iv          = NULL_PTR;
-    this->_key         = NULL_PTR;
+
+CSymmAlgo::CSymmAlgo( ) {
+
+    _cipherMode  = CIPHER_MODE_CBC;
+    
+    _paddingMode = PADDING_MODE_PKCS7;
+    
+    _iv          = NULL;
+    
+    _key         = NULL;
 }
 
-CSymmAlgo::~CSymmAlgo(){
-    if(this->_key != NULL_PTR)
-        free(this->_key);
+
+/*
+*/
+CSymmAlgo::~CSymmAlgo( ) {
+
+    if( _key )
+        free(_key);
 }
 
-void CSymmAlgo::SetKey(CK_BYTE_PTR key,CK_LONG keyLength){
-    this->_key       = (CK_BYTE_PTR)malloc(keyLength);
-    this->_keyLength = keyLength;
 
-    memcpy(this->_key,key,keyLength);
+/*
+*/
+void CSymmAlgo::SetKey( unsigned char* key, long keyLength ) {
+
+    _key = (unsigned char*)malloc(keyLength);
+    
+    _keyLength = keyLength;
+
+    memcpy(_key,key,keyLength);
 }
 
-void CSymmAlgo::SetIV(CK_BYTE_PTR iv){
-    this->_iv = iv;
+void CSymmAlgo::SetIV(unsigned char* iv){
+    _iv = iv;
 }
 
-void CSymmAlgo::SetEncryptMode(CK_LONG mode){
-    this->_encryptMode = mode;
+void CSymmAlgo::SetEncryptMode(long mode){
+    _encryptMode = mode;
 }
 
-void CSymmAlgo::SetCipherMode(CK_LONG cmode){
-    this->_cipherMode = cmode;
+void CSymmAlgo::SetCipherMode(long cmode){
+    _cipherMode = cmode;
 }
 
-void CSymmAlgo::SetPaddingMode(CK_LONG pmode){
-    this->_paddingMode = pmode;
+void CSymmAlgo::SetPaddingMode(long pmode){
+    _paddingMode = pmode;
 }
 
-CK_LONG CSymmAlgo::GetOutputLength(CK_LONG input_count){
+long CSymmAlgo::GetOutputLength(long input_count){
 
-    CK_LONG outputLen;
+    long outputLen;
 
-    if(this->_encryptMode == ENCRYPT){
-        outputLen = input_count & -this->_blockSize;
+    if(_encryptMode == ENCRYPT){
+        outputLen = input_count & -_blockSize;
 
-        switch(this->_paddingMode){
+        switch(_paddingMode){
 
             case PADDING_MODE_ISO9797M2:
             case PADDING_MODE_PKCS7:
                 // atleast 1 padding byte will be needed
                 if(input_count >= outputLen){
-                    outputLen += this->_blockSize;
+                    outputLen += _blockSize;
                 }
                 break;
 
             case PADDING_MODE_ZEROS:
                 if(input_count > outputLen){
-                    outputLen += this->_blockSize;
+                    outputLen += _blockSize;
                 }
                 break;
 
@@ -91,10 +108,10 @@
     return outputLen;
 }
 
-CK_LONG CSymmAlgo::TransformBlock(CK_BYTE_PTR input,CK_LONG input_offset,CK_LONG input_count,
-                                  CK_BYTE_PTR output,CK_LONG output_offset)
+long CSymmAlgo::TransformBlock(unsigned char* input,long input_offset,long input_count,
+                                  unsigned char* output,long output_offset)
 {
-    CK_LONG res = 0;
+    long res = 0;
     while (res != input_count)
     {
         TransformBlockInternal(_iv,_key,_encryptMode,input,input_offset,output,output_offset);
@@ -120,20 +137,20 @@
     return res;
 }
 
-CK_LONG CSymmAlgo::TransformFinalBlock(CK_BYTE_PTR input,CK_LONG input_offset,CK_LONG input_count,
-                                       CK_BYTE_PTR output,CK_LONG output_offset)
+long CSymmAlgo::TransformFinalBlock(unsigned char* input,long input_offset,long input_count,
+                                       unsigned char* output,long output_offset)
 {
-    CK_LONG workingLength;
+    long workingLength;
 
-    if (((this->_paddingMode == PADDING_MODE_NONE) ||
-         (this->_encryptMode == DECRYPT)) &&
-         (input_count % _blockSize != 0))
-    {
-        PKCS11_ASSERT(CK_FALSE);
-    }
+    //if (((_paddingMode == PADDING_MODE_NONE) ||
+    //     (_encryptMode == DECRYPT)) &&
+    //     (input_count % _blockSize != 0))
+    //{
+    //    PKCS11_ASSERT(CK_FALSE);
+    //}
 
     // prepare outbuffer in case of encryption
-    if (this->_encryptMode == ENCRYPT)
+    if (_encryptMode == ENCRYPT)
     {
         // ~ round_down(inputCount, _blockSizeByte)
         workingLength = input_count & -_blockSize;
@@ -154,15 +171,15 @@
         input_count -= workingLength;
     }
 
-    if (this->_encryptMode == DECRYPT)
+    if (_encryptMode == DECRYPT)
     {
-        switch (this->_paddingMode)
+        switch (_paddingMode)
         {
             case PADDING_MODE_PKCS7:
-                // check the padding value make sense
-                if (output[output_offset - 1] > _blockSize){
-                    PKCS11_ASSERT(CK_FALSE);
-                }
+                //// check the padding value make sense
+                //if (output[output_offset - 1] > _blockSize){
+                //    PKCS11_ASSERT(CK_FALSE);
+                //}
                 workingLength -= output[output_offset - 1];
                 break;
 
@@ -173,9 +190,9 @@
                     output_offset--;
                 }
                 // check initial byte is 0x80
-                if (output[output_offset - 1] != 0x80){
-                    PKCS11_ASSERT(CK_FALSE);
-                }
+                //if (output[output_offset - 1] != 0x80){
+                //    PKCS11_ASSERT(CK_FALSE);
+                //}
                 workingLength--;
                 break;
 
@@ -184,17 +201,17 @@
     }
     else
     {
-        if ((this->_paddingMode == PADDING_MODE_PKCS7)
-            || (this->_paddingMode == PADDING_MODE_ISO9797M2)
-            || ((this->_paddingMode == PADDING_MODE_ZEROS) && (input_count > 0)))
+        if ((_paddingMode == PADDING_MODE_PKCS7)
+            || (_paddingMode == PADDING_MODE_ISO9797M2)
+            || ((_paddingMode == PADDING_MODE_ZEROS) && (input_count > 0)))
         {
-            CK_BYTE_PTR paddedIntput = (CK_BYTE_PTR)malloc(_blockSize);
+            unsigned char* paddedIntput = (unsigned char*)malloc(_blockSize);
             memset(paddedIntput,0,_blockSize);
 
             memcpy(paddedIntput,&input[input_offset],input_count);
 
             // add padding information in buffer if relevant
-            switch (this->_paddingMode)
+            switch (_paddingMode)
             {
                 // set first bit to 1, all other bits already set to 0
                 case PADDING_MODE_ISO9797M2:
@@ -202,8 +219,8 @@
                     break;
 
                 case PADDING_MODE_PKCS7:
-                    CK_BYTE paddingValue = (CK_BYTE)(_blockSize - input_count);
-                    for (CK_LONG i = input_count; i < _blockSize; i++){
+                    unsigned char paddingValue = (unsigned char)(_blockSize - input_count);
+                    for (long i = input_count; i < _blockSize; i++){
                         paddedIntput[i] = paddingValue;
                     }
                     break;

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,9 +18,13 @@
  *
  */
 
-#ifndef _include_symmalgo_h
-#define _include_symmalgo_h
 
+#ifndef __GEMALTO_SYMMETRIC_ALGO__
+#define __GEMALTO_SYMMETRIC_ALGO__
+
+
+//#include "cryptoki.h"
+
 #define PADDING_MODE_ISO9797M2 1
 #define PADDING_MODE_NONE      2
 #define PADDING_MODE_PKCS7     3
@@ -32,41 +36,44 @@
 #define CIPHER_MODE_CBC 1
 #define CIPHER_MODE_ECB 2
 
-class CSymmAlgo
-{
 
-protected:
-    CK_BYTE_PTR _iv;
-    CK_BYTE_PTR _key;
-    CK_LONG     _keyLength;
-    CK_LONG     _blockSize;
-    CK_LONG     _cipherMode;
-    CK_LONG     _paddingMode;
-    CK_LONG     _encryptMode;
+/*
+*/
+class CSymmAlgo {
 
 protected:
-    virtual void TransformBlockInternal(CK_BYTE_PTR iv,CK_BYTE_PTR key,CK_LONG encryptMode,
-                                           CK_BYTE_PTR input,CK_LONG input_offset,
-                                           CK_BYTE_PTR output,CK_LONG output_offset) = 0;
+    
+    unsigned char* _iv;
+    unsigned char* _key;
+    long     _keyLength;
+    long     _blockSize;
+    long     _cipherMode;
+    long     _paddingMode;
+    long     _encryptMode;
 
+    virtual void TransformBlockInternal(unsigned char* iv,unsigned char* key,long encryptMode, unsigned char* input,long input_offset, unsigned char* output,long output_offset) = 0;
+
 public:
-    CSymmAlgo();
-    virtual ~CSymmAlgo();
 
-    void SetKey(CK_BYTE_PTR key,CK_LONG keyLength);
-    void SetIV(CK_BYTE_PTR iv);
-    void SetEncryptMode(CK_LONG mode);
-    void SetCipherMode(CK_LONG cmode);
-    void SetPaddingMode(CK_LONG pmode);
+    CSymmAlgo( );
+    
+    virtual ~CSymmAlgo( );
 
-    CK_LONG GetOutputLength(CK_LONG input_count);
+    void SetKey( unsigned char* key, long keyLength );
 
-    CK_LONG TransformBlock(CK_BYTE_PTR input,CK_LONG input_offset,CK_LONG input_count,
-                           CK_BYTE_PTR output,CK_LONG output_offset);
+    void SetIV( unsigned char* iv );
+    
+    void SetEncryptMode( long mode );
+    
+    void SetCipherMode( long cmode );
+    
+    void SetPaddingMode( long pmode );
 
-    CK_LONG TransformFinalBlock(CK_BYTE_PTR input,CK_LONG input_offset,CK_LONG input_count,
-                                CK_BYTE_PTR output,CK_LONG output_offset);
+    long GetOutputLength( long input_count );
+
+    long TransformBlock( unsigned char* input, long input_offset,long input_count, unsigned char* output,long output_offset);
+
+    long TransformFinalBlock(unsigned char* input,long input_offset,long input_count, unsigned char* output,long output_offset);
 };
 
-#endif
-
+#endif // 

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,36 +18,29 @@
  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
-#include "stdafx.h"
-#include "platconfig.h"
-#include "symmalgo.h"
+
+
 #include "tdes.h"
 
-CTripleDES::CTripleDES(){
-    this->_blockSize = 8;
-}
 
-CTripleDES::~CTripleDES(){
-}
+void CTripleDES::TransformBlockInternal( unsigned char* iv, unsigned char* key, long encryptMode, unsigned char* input, long input_offset, unsigned char* output, long output_offset ) {
 
-void CTripleDES::TransformBlockInternal(CK_BYTE_PTR iv,CK_BYTE_PTR key,CK_LONG encryptMode,
-                                        CK_BYTE_PTR input,CK_LONG input_offset,
-                                        CK_BYTE_PTR output,CK_LONG output_offset)
-{
     // encryprtMode == ENCRYPT then we need to XOR input with iv
-    if(iv != NULL_PTR && this->_encryptMode == ENCRYPT){
-        for(CK_LONG i=0;i<8;i++){
-            input[input_offset+i] ^= iv[i];
+    if( iv && ( _encryptMode == ENCRYPT ) ) {
+
+        for( long i = 0 ; i < 8 ; ++i ) {
+
+            input[ input_offset + i ] ^= iv[ i ];
         }
     }
 
-    algo_DES_3DESProcess((u1)_keyLength,key,&input[input_offset],&output[output_offset],(u1)encryptMode);
+    algo_DES_3DESProcess( (unsigned char)_keyLength, key, &input[ input_offset ], &output[ output_offset ], (unsigned char)encryptMode );
 
-    if(iv != NULL_PTR && this->_encryptMode == DECRYPT){
-        for(CK_LONG i=0;i<8;i++){
-            output[output_offset+i] ^= iv[i];
+    if( iv && ( _encryptMode == DECRYPT) ) {
+
+        for( long i = 0 ; i < 8 ; ++i ) {
+
+            output[ output_offset + i ] ^= iv[ i ];
         }
     }
 }
-
-

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,25 +18,28 @@
  *
  */
 
-#ifndef _include_tdes_h
-#define _include_tdes_h
 
-#include "MarshallerCfg.h"
+#ifndef __GEMALTO_3DES__
+#define __GEMALTO_3DES__
+
+
+//#include "MarshallerCfg.h"
 #include "algo_des.h"
+#include "symmalgo.h"
 
-class CTripleDES : public CSymmAlgo
-{
 
+class CTripleDES : public CSymmAlgo {
+
 public:
-    CTripleDES();
-    ~CTripleDES();
 
+    inline CTripleDES( ) { _blockSize = 8; }
+    
+    inline virtual ~CTripleDES( ) { }
+
 private:
-    void TransformBlockInternal(CK_BYTE_PTR iv,CK_BYTE_PTR key,CK_LONG encryptMode,
-                                CK_BYTE_PTR input,CK_LONG input_offset,
-                                CK_BYTE_PTR output,CK_LONG output_offset);
 
+    void TransformBlockInternal( unsigned char* iv, unsigned char* key, long encryptMode, unsigned char* input, long input_offset, unsigned char* output, long output_offset );
+
 };
 
-#endif
-
+#endif // __GEMALTO_3DES__

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,303 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "template.h"
-
-Template::Template(CK_ATTRIBUTE_PTR attrTemplate,CK_ULONG ulCount){
-
-
-   for(CK_ULONG i=0;i<ulCount;i++){
-      CK_ATTRIBUTE attribute;
-
-      attribute.type = attrTemplate[i].type;
-      attribute.ulValueLen = attrTemplate[i].ulValueLen;
-      attribute.pValue = NULL_PTR;
-
-      if(attribute.ulValueLen > 0) {
-         attribute.pValue = malloc(attribute.ulValueLen);
-         memcpy(attribute.pValue, attrTemplate[i].pValue, attribute.ulValueLen);
-      }
-
-      this->_attributes.push_back(attribute);
-   }
-}
-
-
-Template::~Template( )
-{
-   std::vector<CK_ATTRIBUTE>::size_type sz = _attributes.size( );
-   for( std::vector<CK_ATTRIBUTE>::size_type i = 0 ; i < sz ; i++ )
-   {
-      if( NULL_PTR != _attributes[ i ].pValue )
-      {
-         free( _attributes[ i ].pValue );
-      }
-   }
-}
-
-
-void Template::FixEndianness(CK_ATTRIBUTE attrTemplate)
-{
-   // Only for Little Endian processors
-   if (IS_LITTLE_ENDIAN)
-   {
-      // we need to fix the endianness if
-      // we are dealing with data on 2 or 4 or 8 bytes
-      switch(attrTemplate.ulValueLen)
-      {
-      case 2:
-      case 4:
-      case 8:
-         {
-            // fix up needs to be done for specific
-            // attributes. Byte arrays may have sizes of 2,4 or 8
-            switch(attrTemplate.type)
-            {
-               // CK_ULONG data types
-            case CKA_CLASS:
-            case CKA_CERTIFICATE_TYPE:
-            case CKA_JAVA_MIDP_SECURITY_DOMAIN:
-            case CKA_KEY_TYPE:
-            case CKA_KEY_GEN_MECHANISM:
-            case CKA_MODULUS_BITS:
-               {
-                  PKCS11_ASSERT(attrTemplate.ulValueLen == sizeof(CK_ULONG));
-                  CK_BYTE b1 = ((CK_BYTE_PTR)attrTemplate.pValue)[0];
-                  CK_BYTE b2 = ((CK_BYTE_PTR)attrTemplate.pValue)[1];
-                  CK_BYTE b3 = ((CK_BYTE_PTR)attrTemplate.pValue)[2];
-                  CK_BYTE b4 = ((CK_BYTE_PTR)attrTemplate.pValue)[3];
-                  ((CK_BYTE_PTR)attrTemplate.pValue)[3] = b1;
-                  ((CK_BYTE_PTR)attrTemplate.pValue)[2] = b2;
-                  ((CK_BYTE_PTR)attrTemplate.pValue)[1] = b3;
-                  ((CK_BYTE_PTR)attrTemplate.pValue)[0] = b4;
-               }
-               break;
-            }
-         }
-         break;
-
-      default:
-         break;
-      }
-   }
-}
-
-CK_ULONG Template::FindClassFromTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
-   CK_ULONG idx = 0;
-
-   for(idx=0;idx<ulCount;idx++)
-   {
-      if(pTemplate[idx].type == CKA_CLASS)
-      {
-         return *(CK_ULONG*)pTemplate[idx].pValue;
-      }
-   }
-
-   return (CK_ULONG)-1;
-}
-
-CK_ULONG Template::FindCertTypeFromTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
-   CK_ULONG idx = 0;
-
-   for(idx=0;idx<ulCount;idx++)
-   {
-      if(pTemplate[idx].type == CKA_CERTIFICATE_TYPE)
-      {
-         return *(CK_ULONG*)pTemplate[idx].pValue;
-      }
-   }
-
-   return (CK_ULONG)-1;
-}
-
-CK_BBOOL Template::FindTokenFromTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
-{
-   CK_ULONG idx = 0;
-
-   for(idx=0;idx<ulCount;idx++)
-   {
-      if(pTemplate[idx].type == CKA_TOKEN)
-      {
-         return *(CK_BBOOL*)pTemplate[idx].pValue;
-      }
-   }
-
-   return CK_FALSE;
-}
-
-CK_BBOOL Template::IsAttrInTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, CK_ATTRIBUTE_TYPE AttrType)
-{
-   CK_ULONG idx = 0;
-
-   for(idx=0;idx<ulCount;idx++)
-   {
-      if(pTemplate[idx].type == AttrType)
-      {
-         return CK_TRUE;
-      }
-   }
-
-   return CK_FALSE;
-}
-
-CK_RV Template::CheckTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, CK_BYTE bMode)
-{
-   CK_OBJECT_CLASS     ObjClass = (CK_ULONG)-1;
-   CK_CERTIFICATE_TYPE CertType = (CK_ULONG)-1;
-
-   // Get Object Class
-   ObjClass = FindClassFromTemplate(pTemplate, ulCount);
-
-   // Get Cert Type
-   if (ObjClass == CKO_CERTIFICATE)
-   {
-      CertType = FindCertTypeFromTemplate(pTemplate, ulCount);
-   }
-
-   // Check Creation Template
-   if (bMode == MODE_CREATE)
-   {
-      switch (ObjClass)
-      {
-      case CKO_DATA:
-         {
-            if (IsAttrInTemplate(pTemplate, ulCount, CKA_CLASS))
-            {
-               return CKR_OK;
-            }
-         }
-         break;
-
-      case CKO_CERTIFICATE:
-         {
-            if (CertType == CKC_X_509)
-            {
-               if (  (IsAttrInTemplate(pTemplate, ulCount, CKA_CLASS))
-                  &&(IsAttrInTemplate(pTemplate, ulCount, CKA_SUBJECT))
-                  &&(IsAttrInTemplate(pTemplate, ulCount, CKA_VALUE))
-                  )
-               {
-                  return CKR_OK;
-               }
-            }
-
-            else if (CertType == CKC_X_509_ATTR_CERT)
-            {
-               if (  (IsAttrInTemplate(pTemplate, ulCount, CKA_CLASS))
-                  &&(IsAttrInTemplate(pTemplate, ulCount, CKA_OWNER))
-                  &&(IsAttrInTemplate(pTemplate, ulCount, CKA_VALUE))
-                  )
-               {
-                  return CKR_OK;
-               }
-            }
-
-            else
-            {
-               return CKR_TEMPLATE_INCONSISTENT;
-            }
-         }
-         break;
-
-      case CKO_PUBLIC_KEY:
-         {
-            if (  ( IsAttrInTemplate(pTemplate, ulCount, CKA_CLASS))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_KEY_TYPE))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_LOCAL))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_KEY_GEN_MECHANISM))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_MODULUS))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_MODULUS_BITS))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_PUBLIC_EXPONENT))
-               )
-            {
-               return CKR_OK;
-            }
-         }
-         break;
-
-      case CKO_PRIVATE_KEY:
-         {
-            if (  ( IsAttrInTemplate(pTemplate, ulCount, CKA_CLASS))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_KEY_TYPE))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_LOCAL))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_KEY_GEN_MECHANISM))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_ALWAYS_SENSITIVE))
-               &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_NEVER_EXTRACTABLE))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_MODULUS))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_PRIVATE_EXPONENT))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_PRIME_1))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_PRIME_2))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_EXPONENT_1))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_EXPONENT_2))
-               &&( IsAttrInTemplate(pTemplate, ulCount, CKA_COEFFICIENT))
-               )
-            {
-               return CKR_OK;
-            }
-         }
-         break;
-
-      default:
-         return CKR_TEMPLATE_INCONSISTENT;
-      }
-   }
-
-   // Check Public Key Generation Template
-   else if (bMode == MODE_GENERATE_PUB)
-   {
-      if (  (!IsAttrInTemplate(pTemplate, ulCount, CKA_LOCAL))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_KEY_GEN_MECHANISM))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_MODULUS))
-         &&( IsAttrInTemplate(pTemplate, ulCount, CKA_MODULUS_BITS))
-         &&( IsAttrInTemplate(pTemplate, ulCount, CKA_PUBLIC_EXPONENT))
-         )
-      {
-         return CKR_OK;
-      }
-   }
-
-   // Check Private Key Generation Template
-   else if (bMode == MODE_GENERATE_PRIV)
-   {
-      if (  (!IsAttrInTemplate(pTemplate, ulCount, CKA_LOCAL))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_KEY_GEN_MECHANISM))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_ALWAYS_SENSITIVE))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_NEVER_EXTRACTABLE))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_MODULUS))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_PUBLIC_EXPONENT))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_PRIVATE_EXPONENT))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_PRIME_1))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_PRIME_2))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_EXPONENT_1))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_EXPONENT_2))
-         &&(!IsAttrInTemplate(pTemplate, ulCount, CKA_COEFFICIENT))
-         )
-      {
-         return CKR_OK;
-      }
-   }
-
-   return CKR_TEMPLATE_INCONSISTENT;
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/template.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/template.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/template.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,56 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_template_h
-#define _include_template_h
-
-#include <list>
-#include <vector>
-
-using namespace std;
-
-#define MODE_CREATE        0x01
-#define MODE_GENERATE_PUB  0x02
-#define MODE_GENERATE_PRIV 0x03
-
-class Template
-{
-
-public:
-    vector<CK_ATTRIBUTE> _attributes;
-
-public:
-    Template(CK_ATTRIBUTE_PTR temp,CK_ULONG ulCount);
-    ~Template();
-
-    static void FixEndianness(CK_ATTRIBUTE attrTemplate);
-
-    static CK_ULONG FindClassFromTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-    static CK_ULONG FindCertTypeFromTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-    static CK_BBOOL FindTokenFromTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount);
-    static CK_BBOOL IsAttrInTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, CK_ATTRIBUTE_TYPE AttrType);
-    static CK_RV CheckTemplate(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount, CK_BYTE bMode);
-
-};
-
-
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,312 +0,0 @@
-
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-#ifdef INCLUDE_EVENTING
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include <string>
-#ifndef WIN32
-#include <pthread.h>
-#endif
-#include "thread.h"
-
-#ifdef WIN32
-const CK_LONG CThread::P_ABOVE_NORMAL = THREAD_PRIORITY_ABOVE_NORMAL;
-const CK_LONG CThread::P_BELOW_NORMAL = THREAD_PRIORITY_BELOW_NORMAL;
-const CK_LONG CThread::P_HIGHEST      = THREAD_PRIORITY_HIGHEST;
-const CK_LONG CThread::P_IDLE         = THREAD_PRIORITY_IDLE;
-const CK_LONG CThread::P_LOWEST       = THREAD_PRIORITY_LOWEST;
-const CK_LONG CThread::P_NORMAL       = THREAD_PRIORITY_NORMAL;
-const CK_LONG CThread::P_CRITICAL     = THREAD_PRIORITY_TIME_CRITICAL;
-#endif
-
-CThread::CThread()
-{
-#ifdef WIN32
-    m_hThread = NULL;
-#endif
-    m_strName = NULL;
-    m_stopRequested = false;
-}
-
-CThread::CThread(const char* nm)
-{
-#ifdef WIN32
-    m_hThread = NULL;
-#endif
-    m_strName = new std::string(nm);
-}
-
-CThread::~CThread()
-{
-#ifdef WIN32
-    if(m_hThread != NULL)
-    {
-        if(m_strName != NULL)
-        {
-            delete m_strName;
-        }
-        stop();
-    }
-#else
-
-#endif
-}
-
-void CThread::setName(const char* nm)
-{
-    m_strName = new std::string(nm);
-}
-
-std::string* CThread::getName() const
-{
-    return m_strName;
-}
-
-void CThread::run()
-{
-    // Base run
-}
-
-void CThread::sleep(CK_LONG ms)
-{
-#ifdef WIN32
-    Sleep(ms);
-#else
-    usleep(ms*1000);
-#endif
-}
-
-void CThread::start()
-{
-
-#ifdef WIN32
-    DWORD tid = 0;
-    m_hThread = (unsigned long*)CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)_ou_thread_proc,(CThread*)this,0,&tid);
-
-    if(m_hThread == NULL)
-    {
-        assert(FALSE);
-        //throw ThreadException("Failed to create thread");
-    }
-    else
-    {
-        setPriority(CThread::P_NORMAL);
-    }
-
-#else
-
-    pthread_create(&m_hThread,0,_ou_thread_proc,(CThread*)this);
-
-#endif
-
-}
-
-void CThread::stop()
-{
-#ifdef WIN32
-    if(m_hThread == NULL) return;
-
-    m_stopRequested = true;
-
-    DWORD dwTimeout = 1000;
-    DWORD dwSleepTime = 10;
-    DWORD dwExitCode = STILL_ACTIVE;
-
-    for(DWORD i=0; i< dwTimeout/dwSleepTime; i++)
-    {
-        if(GetExitCodeThread(m_hThread, &dwExitCode))
-        {
-            if(dwExitCode!=STILL_ACTIVE)
-                break;
-        }
-        else
-            break; // Some error
-        Sleep(dwSleepTime);
-    }
-
-    if( dwExitCode == STILL_ACTIVE )
-        TerminateThread(m_hThread, 0);
-
-    // Never do this.
-    ///WaitForSingleObject(m_hThread,INFINITE);
-    CloseHandle(m_hThread);
-    m_hThread = NULL;
-
-    m_stopRequested = false;
-
-#else
-
-    m_stopRequested = true;
-
-    pthread_join(m_hThread,NULL);
-
-    m_stopRequested = false;
-
-#endif
-}
-
-CK_BBOOL CThread::isStopRequested()
-{
-    return m_stopRequested;
-}
-
-#ifdef WIN32
-void CThread::setPriority(CK_LONG tp)
-#else
-void CThread::setPriority( CK_LONG )
-#endif
-{
-#ifdef WIN32
-    if(m_hThread == NULL)
-    {
-        assert(FALSE);
-        //throw ThreadException("Thread object is null");
-    }
-    else
-    {
-        if(SetThreadPriority(m_hThread,tp) == 0)
-        {
-            assert(FALSE);
-            //throw ThreadException("Failed to set priority");
-        }
-    }
-#else
-#endif
-}
-
-void CThread::suspend()
-{
-
-#ifdef WIN32
-    if(m_hThread == NULL)
-    {
-        assert(FALSE);
-        //throw ThreadException("Thread object is null");
-    }
-    else
-    {
-        if((int)SuspendThread(m_hThread) < 0)
-        {
-            assert(FALSE);
-            //throw ThreadException("Failed to suspend thread");
-        }
-    }
-#else
-#endif
-}
-
-void CThread::resume()
-{
-#ifdef WIN32
-    if(m_hThread == NULL)
-    {
-        assert(FALSE);
-        //throw ThreadException("Thread object is null");
-    }
-    else
-    {
-        if((int)ResumeThread(m_hThread) < 0)
-        {
-            assert(FALSE);
-            //throw ThreadException("Failed to resume thread");
-        }
-    }
-#else
-#endif
-}
-
-#ifdef WIN32
-CK_BBOOL CThread::wait(const char* m,CK_LONG ms)
-#else
-CK_BBOOL CThread::wait( const char*, CK_LONG )
-#endif
-{
-#ifdef WIN32
-    HANDLE h = OpenMutex(MUTEX_ALL_ACCESS,FALSE,m);
-
-    if(h == NULL)
-    {
-        assert(FALSE);
-        //throw ThreadException("Mutex not found");
-    }
-    DWORD d = WaitForSingleObject(h,ms);
-
-    switch(d)
-    {
-    case WAIT_ABANDONED:
-        assert(FALSE);
-        //throw ThreadException("Mutex not signaled");
-        break;
-    case WAIT_OBJECT_0:
-        return true;
-    case WAIT_TIMEOUT:
-        assert(FALSE);
-        //throw ThreadException("Wait timed out");
-        break;
-    }
-    return false;
-#else
-    return false;
-#endif
-}
-
-#ifdef WIN32
-void CThread::release(const char* m)
-#else
-void CThread::release( const char* )
-#endif
-{
-#ifdef WIN32
-    HANDLE h = OpenMutex(MUTEX_ALL_ACCESS,FALSE,m);
-    if(h == NULL)
-    {
-        assert(FALSE);
-        //throw ThreadException("Invalid mutex handle");
-    }
-    if(ReleaseMutex(h) == 0)
-    {
-        assert(FALSE);
-        //throw ThreadException("Failed to release mutex");
-    }
-#else
-#endif
-}
-
-#ifdef WIN32
-// global thread caallback
-unsigned int _ou_thread_proc(void* param)
-{
-    CThread* tp = (CThread*)param;
-    tp->run();
-    return 0;
-}
-#else
-void* _ou_thread_proc(void* param)
-{
-    CThread* tp = (CThread*)param;
-    tp->run();
-    return NULL;
-}
-#endif
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,91 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_thread_h
-#define _include_thread_h
-
-#include <string>
-
-#ifdef INCLUDE_EVENTING
-
-using namespace std;
-
-class CThread
-{
-
-private:
-    // unsigned long* to the low-level thread object
-#ifdef WIN32
-    CK_ULONG_PTR m_hThread;
-#else
-    pthread_t 	 m_hThread;
-#endif
-
-    // a name to identify the thread
-    std::string* m_strName;
-    CK_BBOOL     m_stopRequested;
-
-public:
-    CThread();
-    CThread(const char* nm);
-    virtual ~CThread();
-
-    void setName(const char* nm);
-    std::string* getName() const;
-
-    void start();
-    virtual void run();
-    void sleep(CK_LONG ms);
-    void suspend();
-    void resume();
-    virtual void stop();
-
-    void setPriority(CK_LONG p);
-    CK_BBOOL isStopRequested();
-
-    CK_BBOOL wait(const char* m,CK_LONG ms=5000);
-    void release(const char* m);
-
-public:
-    // Thread priorities
-    static const CK_LONG P_ABOVE_NORMAL;
-    static const CK_LONG P_BELOW_NORMAL;
-    static const CK_LONG P_HIGHEST;
-    static const CK_LONG P_IDLE;
-    static const CK_LONG P_LOWEST;
-    static const CK_LONG P_NORMAL;
-    static const CK_LONG P_CRITICAL;
-};
-
-// global function called by the thread object.
-// this in turn calls the overridden run()
-extern "C"
-{
-#ifdef WIN32
-    unsigned int _ou_thread_proc(void* param);
-#else
-    void* _ou_thread_proc(void* param);
-#endif
-}
-
-#endif
-
-#endif
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,49 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "timer.h"
-
-#if defined(_WIN32)
-#include "Windows.h"
-#else
-#include <inttypes.h>
-#include <sys/time.h>
-#endif
-
-unsigned long CTimer::ClockTicks()
-{
-#if defined(_WIN32)
-    return GetTickCount();
-#else
-    static uint64_t startuptime = 0;
-    struct timeval t;
-
-    if(!startuptime) {
-        gettimeofday(&t,0);
-        startuptime = t.tv_sec*1000 + t.tv_usec/1000;
-    }
-
-    gettimeofday(&t,0);
-    uint64_t time = t.tv_sec*1000 + t.tv_usec/1000 - startuptime;
-    return (unsigned long)(time & 0xFFFFFFFF);
-
-#endif
-
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,31 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_timer_h
-#define _include_timer_h
-
-class CTimer
-{
-public:
-    static unsigned long ClockTicks();
-};
-
-#endif // _include_timer_h
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,57 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "transaction.h"
-#include "cardmoduleservice.h"
-
-#include "platconfig.h"
-#include "config.h"
-#include "thread.h"
-#include "event.h"
-#include "session.h"
-#include "slot.h"
-#include "sctoken.h"
-#include "error.h"
-
-
-Transaction::Transaction(Slot * slot) : _slot(slot)
-{
-
-    if(!slot || !slot->_token)
-        throw CkError(CKR_FUNCTION_FAILED);
-
-    _slot->_token->BeginTransaction();
-
-    // As a result of card re-set, user may have been logged out
-    _slot->UpdateSessionState();
-}
-
-Transaction::~Transaction() throw()
-{
-    if(!_slot || !_slot->_token)
-        return;
-
-    try
-    {
-        _slot->_token->EndTransaction();
-    }
-    catch(...) {}
-}

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,37 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#ifndef _include_transaction_h
-#define _include_transaction_h
-
-class Slot;
-
-/** Class that manages token transaction */
-class Transaction
-{
-public:
-    Transaction(Slot * slot);
-    ~Transaction() throw();
-
-private:
-    Slot * _slot;
-};
-
-#endif

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,17 +18,16 @@
  *
  */
 
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
+#include <cstdio>
+#include "cryptoki.h"
 #include "digest.h"
 #include "sha1.h"
-#include "error.h"
+#include "PKCS11Exception.hpp"
 #include "util.h"
 
 R_RANDOM_STRUCT Util::_randomStruct;
 
-void Util::SeedRandom(u1Array const & seed)
+void Util::SeedRandom(  Marshaller::u1Array const & seed)
 {
     InitRandomStruct(&_randomStruct);
     R_RandomUpdate(&_randomStruct, const_cast<unsigned char*>(seed.GetBuffer()), seed.GetLength());
@@ -44,49 +43,66 @@
     return (CK_ULONG)(((CK_ULONG)buffer[offset] << 24) | ((CK_ULONG)buffer[offset+1] << 16) | ((CK_ULONG)buffer[offset+2] << 8) | buffer[offset+3]);
 }
 
-CK_BBOOL Util::CompareByteArrays(CK_BYTE_PTR abuffer,CK_BYTE_PTR bbuffer,CK_ULONG len)
-{
-    for(CK_ULONG i=0;i<len;i++){
-        if(abuffer[i] != bbuffer[i])
-            return CK_FALSE;
-    }
 
+/*
+*/
+bool Util::compareByteArrays( unsigned char* a_pBuffer1, unsigned char* a_pBuffer2, const size_t& a_ulLen ) {
 
-    return CK_TRUE;
+	if( 0 == memcmp( a_pBuffer1, a_pBuffer2, a_ulLen ) ) {
+
+		return true;
+	}
+
+    /*for( CK_ULONG i = 0 ; i < a_ulLen ; ++i ) {
+
+        if( a_pBuffer1[ i ] != a_pBuffer2[ i ] ) {
+         
+			return false;
+		}
+    }*/
+
+    return false;
 }
 
-CK_BBOOL Util::CompareU1Arrays(u1Array* abuffer,CK_VOID_PTR bbuffer,CK_ULONG len)
-{
-    if((abuffer == NULL_PTR) && (bbuffer == NULL_PTR)){
-        return CK_TRUE;
+
+bool Util::compareU1Arrays( Marshaller::u1Array* abuffer, unsigned char* bbuffer, const size_t& len ) {
+
+    if( !abuffer && !bbuffer ) {
+
+        return true;
     }
 
-    if((abuffer != NULL_PTR) && (bbuffer != NULL_PTR)){
-        if(len == abuffer->GetLength()){
-            return Util::CompareByteArrays(abuffer->GetBuffer(),(CK_BYTE_PTR)bbuffer,len);
+    if( abuffer && bbuffer ) {
+
+        if( len == abuffer->GetLength( ) ) {
+        
+            return Util::compareByteArrays( abuffer->GetBuffer( ), bbuffer, len );
         }
     }
 
-    return CK_FALSE;
+    return false;
 }
 
 
-CK_BBOOL Util::CompareU4Arrays(u4Array* abuffer,CK_VOID_PTR bbuffer,CK_ULONG len)
-{
-    if((abuffer == NULL_PTR) && (bbuffer == NULL_PTR)){
-        return CK_TRUE;
+bool Util::compareU4Arrays(  Marshaller::u4Array* abuffer, unsigned char* bbuffer, const size_t& len ) {
+
+    if( !abuffer &&  !bbuffer ) {
+
+        return true;
     }
 
-    if((abuffer != NULL_PTR) && (bbuffer != NULL_PTR)){
-        if(len == abuffer->GetLength()){
-            return Util::CompareByteArrays((u1*)abuffer->GetBuffer(),(CK_BYTE_PTR)bbuffer,len);
+    if( abuffer && bbuffer ) {
+
+        if( len == abuffer->GetLength( ) ) {
+
+            return Util::compareByteArrays( (unsigned char*) abuffer->GetBuffer( ), bbuffer, len );
         }
     }
 
-    return CK_FALSE;
+    return false;
 }
 
-void Util::PushULongInVector(vector<u1>* to, CK_ULONG value)
+void Util::PushULongInVector( std::vector<u1>* to, CK_ULONG value)
 {
     to->push_back((u1)(value >> 24));
     to->push_back((u1)(value >> 16));
@@ -94,7 +110,7 @@
     to->push_back((u1)(value));
 }
 
-void Util::PushULongLongInVector(vector<u1>* to, u8 value)
+void Util::PushULongLongInVector( std::vector<u1>* to, u8 value)
 {
     to->push_back((u1)(value >> 56));
     to->push_back((u1)(value >> 48));
@@ -112,32 +128,50 @@
     to->push_back(value);
 }
 
-void Util::PushByteArrayInVector(std::vector<u1>* to, u1Array *value)
-{
-    if((value == NULL_PTR) || value->GetLength() == 0){
-        to->push_back(0);
-    }else{
-        Util::PushLengthInVector(to,value->GetLength());
-        for(u4 i=0;i<value->GetLength();i++){
-            to->push_back(value->GetBuffer()[i]);
+void Util::PushByteArrayInVector(std::vector<u1>* to,  Marshaller::u1Array *value) {
+
+    if( !value || !value->GetLength( ) ) {
+
+        to->push_back( 0 );
+    
+    } else {
+
+        int l = value->GetLength( );
+
+        Util::PushLengthInVector( to, l );
+        
+        u1* buffer = (u1*)value->GetBuffer( );
+
+        for (int i = 0 ; i < l; ++i ) {
+
+            to->push_back( buffer[ i ] );
         }
     }
 }
 
-void Util::PushIntArrayInVector(std::vector<u1>* to, u4Array *value)
-{
-    if((value == NULL_PTR) || value->GetLength() == 0){
+
+void Util::PushIntArrayInVector(std::vector<u1>* to,  Marshaller::u4Array *value) {
+
+    if( !value || !value ) {
+
         to->push_back(0);
-    }else{
-        Util::PushLengthInVector(to,(value->GetLength() * 4));
-        u1* buffer = (u1*)value->GetBuffer();
-        for(u4 i=0;i<(value->GetLength() * 4);i++){
-            to->push_back(buffer[i]);
+    
+    } else {
+
+        int l = value->GetLength( ) * 4;
+
+        Util::PushLengthInVector( to, l );
+        
+        u1* buffer = (u1*)value->GetBuffer( );
+
+        for( int i = 0 ; i < l ; ++i ) {
+
+            to->push_back( buffer[ i ] );
         }
     }
 }
 
-u1Array* Util::ReadByteArrayFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+ Marshaller::u1Array* Util::ReadByteArrayFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
 {
     CK_ULONG len = Util::ReadLengthFromVector(from,idx);
 
@@ -145,7 +179,7 @@
         return NULL_PTR;
     }
 
-    u1Array* val = new u1Array(len);
+    Marshaller::u1Array* val = new Marshaller::u1Array(len);
 
     for(u4 i=0;i<len;i++){
         val->SetU1At(i,from.at(*idx));
@@ -155,7 +189,7 @@
     return val;
 }
 
-u4Array* Util::ReadIntArrayFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+ Marshaller::u4Array* Util::ReadIntArrayFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
 {
     CK_ULONG len = Util::ReadLengthFromVector(from,idx);
 
@@ -163,7 +197,7 @@
         return NULL_PTR;
     }
 
-    u4Array* val = new u4Array(len/4);
+     Marshaller::u4Array* val = new  Marshaller::u4Array(len/4);
 
     for(u4 i=0;i<(len/4);i++){
 
@@ -183,11 +217,11 @@
     return val;
 }
 
-void Util::PushLengthInVector(std::vector<u1>* to, CK_USHORT len)
+void Util::PushLengthInVector(std::vector<u1>* to, CK_ULONG len)
 {
-    if(len < (CK_USHORT)0x80){
+    if(len < (CK_ULONG)0x80){
         to->push_back(len & 0x7F);
-    }else if(len <= (CK_USHORT)0xFF){
+    }else if(len <= (CK_ULONG)0xFF){
         to->push_back(0x81);
         to->push_back(len & 0xFF);
     }else{
@@ -199,9 +233,9 @@
 
 CK_ULONG Util::ReadLengthFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
 {
-    CK_USHORT val = (CK_USHORT)from.at(*idx);
+    CK_ULONG val = (CK_ULONG)from.at(*idx);
 
-    if(val < (CK_USHORT)0x80){
+    if(val < (CK_ULONG)0x80){
         *idx = *idx + 1;
         return val;
     }else if(val == 0x81){
@@ -218,7 +252,7 @@
         return val;
     }
 
-    PKCS11_ASSERT(CK_FALSE);
+    //PKCS11_ASSERT(CK_FALSE);
 
     return 0;
 }
@@ -231,6 +265,16 @@
     return val;
 }
 
+
+bool Util::ReadBoolFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+    bool val = ( from.at( *idx ) != 0 ) ? true : false;
+
+	*idx = *idx + 1;
+
+    return val;
+}
+
 CK_ULONG Util::ReadULongFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
 {
     CK_ULONG offset = *idx;
@@ -345,10 +389,11 @@
 {
     CSHA1 sha1;
     u1 hash[20];
-    sha1.HashCore(const_cast<unsigned char *>(pBuf), 0, length);
-    sha1.HashFinal(hash);
+    sha1.hashCore(const_cast<unsigned char *>(pBuf), 0, length);
+    sha1.hashFinal(hash);
     u8 val = 0;
-    for(size_t i = 0; i< sizeof(u8); ++i)
+    size_t l = sizeof(u8);
+    for(size_t i = 0; i< l; ++i)
         val = (val << 8) | hash[i];
     return val;
 }
@@ -357,17 +402,32 @@
 {
     unsigned char buf[8];
     if(R_GenerateBytes(buf, 8, &_randomStruct))
-        throw CkError(CKR_FUNCTION_FAILED);
+        throw PKCS11Exception( CKR_FUNCTION_FAILED );
     u8 * value = reinterpret_cast<u8*>(buf);
     return *value;
 }
 
-string Util::MakeIntString(unsigned int number, int width)
+std::string Util::MakeIntString(unsigned int number, int width)
 {
     if(width < 1)
-        return string();
+        return std::string();
     char temp[16];
     sprintf(temp, "%011d", number);
-    string s(temp);
+    std::string s(temp);
     return s.substr(s.size()-width, width);
 }
+
+
+/*
+*/
+void Util::toStringHex( const unsigned char& a_ucIn, std::string& a_stOut ) {
+
+    char h1 = a_ucIn / 16;
+    h1 += ( ( h1 <= 9 ) ? '0' : ( 'A'- 10 ) );
+    
+    char h2 = a_ucIn % 16;
+    h2 += ( ( h2 <= 9 ) ? '0' : ( 'A'- 10 ) );
+
+    a_stOut += h1;
+    a_stOut += h2;
+}

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/util.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/util.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/util.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -24,12 +24,11 @@
 #include <string>
 #include <vector>
 
-#include <MarshallerCfg.h>
-#include <Array.h>
-#include <cr_random.h>
+#include "MarshallerCfg.h"
+#include "Array.hpp"
+#include "cr_random.h"
+#include "cryptoki.h"
 
-using namespace std;
-using namespace Marshaller;
 
 // Very simple class similar to auto_ptr, but for arrays.
 // It means that it calls delete[] instead of delete.
@@ -71,32 +70,57 @@
 class Util{
 
 public:
-    static void SeedRandom(u1Array const & seed);
+    static void SeedRandom( Marshaller::u1Array const & seed);
+
     static R_RANDOM_STRUCT & RandomStruct();
 
-    static CK_ULONG MakeULong(CK_BYTE_PTR pValue,CK_ULONG offset);
-    static CK_BBOOL CompareByteArrays(CK_BYTE_PTR abuffer,CK_BYTE_PTR bbuffer,CK_ULONG len);
-    static void PushULongInVector(vector<u1>* to,CK_ULONG value);
-    static void PushULongLongInVector(vector<u1>* to,u8 value);
-    static void PushBBoolInVector(vector<u1>* to,CK_BBOOL value);
-    static void PushByteArrayInVector(vector<u1>* to,u1Array* value);
-    static void PushIntArrayInVector(vector<u1>* to,u4Array* value);
-    static void PushLengthInVector(vector<u1>* to,CK_USHORT len);
-    static CK_ULONG ReadLengthFromVector(vector<u1> from,CK_ULONG_PTR idx);
-    static CK_ULONG ReadULongFromVector(vector<u1> from,CK_ULONG_PTR idx);
-    static u8       ReadULongLongFromVector(vector<u1> from,CK_ULONG_PTR idx);
-    static CK_BBOOL ReadBBoolFromVector(vector<u1> from,CK_ULONG_PTR idx);
-    static u1Array* ReadByteArrayFromVector(vector<u1> from,CK_ULONG_PTR idx);
-    static u4Array* ReadIntArrayFromVector(vector<u1> from,CK_ULONG_PTR idx);
+    static CK_ULONG MakeULong( unsigned char* pValue, CK_ULONG offset);
 
-    static CK_BBOOL CompareU1Arrays(u1Array* abuffer,CK_VOID_PTR bbuffer,CK_ULONG len);
-    static CK_BBOOL CompareU4Arrays(u4Array* abuffer,CK_VOID_PTR bbuffer,CK_ULONG len);
-    static void ConvAscii(u1 *pIn, u4 dwLen,u1 *pOut);
-    static char* ItoA(s4 value, char* str, s4 radix);
-    static u8 MakeCheckValue(const unsigned char * pBuf, unsigned int length);
-    static u8 MakeUniqueId();
-    static std::string MakeIntString(unsigned int number, int width);
+    static bool compareByteArrays( unsigned char*, unsigned char*, const size_t& );
+ 
+	static bool compareU1Arrays( Marshaller::u1Array*, unsigned char*, const size_t& );
+    
+	static bool compareU4Arrays( Marshaller::u4Array*, unsigned char*, const size_t& );
+    
+	static void PushULongInVector( std::vector<u1>* to, CK_ULONG value);
+    
+	static void PushULongLongInVector( std::vector<u1>* to,u8 value);
+    
+	static void PushBBoolInVector( std::vector<u1>* to, CK_BBOOL value);
+    
+	static void PushByteArrayInVector( std::vector<u1>* to, Marshaller::u1Array* value);
 
+    static void PushIntArrayInVector( std::vector<u1>* to, Marshaller::u4Array* value);
+
+    static void PushLengthInVector( std::vector<u1>* to,/*CK_USHORT*/ CK_ULONG len);
+    
+	static CK_ULONG ReadLengthFromVector( std::vector<u1> from,CK_ULONG_PTR idx);
+    
+	static CK_ULONG ReadULongFromVector( std::vector<u1> from,CK_ULONG_PTR idx);
+    
+	static u8 ReadULongLongFromVector( std::vector<u1> from,CK_ULONG_PTR idx);
+    
+	static CK_BBOOL ReadBBoolFromVector( std::vector<u1> from,CK_ULONG_PTR idx);
+    
+	static  Marshaller::u1Array* ReadByteArrayFromVector( std::vector<u1> from,CK_ULONG_PTR idx);
+    
+	static  Marshaller::u4Array* ReadIntArrayFromVector( std::vector<u1> from,CK_ULONG_PTR idx);
+
+    static void ConvAscii( unsigned char* pIn, u4 dwLen, unsigned char* pOut );
+    
+	static char* ItoA(s4 value, char* str, s4 radix);
+    
+	static u8 MakeCheckValue(const unsigned char * pBuf, unsigned int length);
+    
+	static u8 MakeUniqueId();
+    
+	static std::string MakeIntString(unsigned int number, int width);
+
+	static bool ReadBoolFromVector(std::vector<u1> from, CK_ULONG_PTR idx);
+
+    static void toStringHex( const unsigned char& a_ucIn, std::string& a_stOut );
+
+
 private:
     static R_RANDOM_STRUCT _randomStruct;
 

Added: trunk/SmartCardServices/src/PKCS11dotNetV2/version.hpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/version.hpp	                        (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/version.hpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -0,0 +1,43 @@
+/*
+ *  PKCS#11 library for .Net smart cards
+ *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+
+#ifndef __GEMALTO_VERSION_HPP__
+#define __GEMALTO_VERSION_HPP__
+
+
+#define CRYPTOKIVERSION_LIBRARY_MAJOR 2
+
+#define CRYPTOKIVERSION_LIBRARY_MINOR 2
+
+#define CRYPTOKIVERSION_LIBRARY_MINOR2 0
+
+#define CRYPTOKIVERSION_LIBRARY_MINOR3 10
+
+//Same definitions in string format in order to be compliant with .rc file syntax
+#define STRCRYPTOKIVERSION_LIBRARY_MAJOR "2"
+
+#define STRCRYPTOKIVERSION_LIBRARY_MINOR "2"
+
+#define SRTCRYPTOKIVERSION_LIBRARY_MINOR2 "0"
+
+#define STRCRYPTOKIVERSION_LIBRARY_MINOR3 "10"
+
+#endif // __GEMALTO_VERSION_HPP__

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -18,15 +18,11 @@
  *
  */
 
-// This implementation is based on RFC 2459 which can be fetched from
-// http://www.ietf.org.
+// This implementation is based on RFC 2459 which can be fetched from http://www.ietf.org.
 
-// This code is based on class in ACS baseline.
 
-//#include "slbPki.h"
 #include "x509cert.h"
 
-using namespace std;
 
 X509Cert::X509Cert()
 {
@@ -46,7 +42,7 @@
 {
    m_Cert = BEROctet(BEROctet::Blob(buffer,size));
    if(size != m_Cert.Octet().size())
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
 
    Decode();
 }
@@ -63,27 +59,27 @@
 {
    m_Cert = BEROctet(buffer);
    if(buffer.size() != m_Cert.Octet().size())
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
    Decode();
 
    return *this;
 }
 
-// Returns whole DER string of Serial Number.
+// Returns whole DER std::string of Serial Number.
 
 BEROctet::Blob X509Cert::SerialNumber() const
 {
    return m_SerialNumber.Octet();
 }
 
-// Returns whole DER string of Issuer
+// Returns whole DER std::string of Issuer
 
 BEROctet::Blob X509Cert::Issuer() const
 {
    return m_Issuer.Octet();
 }
 
-// Returns whole string of Issuer in UTF8.
+// Returns whole std::string of Issuer in UTF8.
 
 BEROctet::Blob X509Cert::UTF8Issuer() const
 {
@@ -102,16 +98,18 @@
 
    m_Issuer.SearchOIDNext(OID_id_at_organizationName,orgOcts);
 
-   for(unsigned long i=0; i<orgOcts.size(); i++)
-      orgNames.push_back(string((char*)orgOcts[i]->Data().data(),orgOcts[i]->Data().size()));
+   size_t l = orgOcts.size( );
+   for( unsigned long i = 0; i < l ; ++i ) {
 
+      orgNames.push_back(std::string((char*)orgOcts[i]->Data().data(),orgOcts[i]->Data().size()));
+   }
    return orgNames;
 
 }
 
 // Returns list of attributes in Issuer matching id-at-organizationName.
 // List will be invalidated when object changes.
-// the string in the list is in UTF8 format.
+// the std::string in the list is in UTF8 format.
 
 std::vector<std::string> X509Cert::UTF8IssuerOrg() const
 {
@@ -121,23 +119,25 @@
 
    m_Issuer.SearchOIDNext(OID_id_at_organizationName,orgOcts);
 
-   for(unsigned long i=0; i<orgOcts.size(); i++)
-   {
-      BEROctet::Blob blbData = ToUTF8(orgOcts[i]->Tag(), orgOcts[i]->Data());
-      orgNames.push_back(string((char*)blbData.data(),blbData.size()));
+   size_t l = orgOcts.size( );
+   for( unsigned long i = 0; i < l ; ++i ) {
+
+       BEROctet::Blob blbData = ToUTF8(orgOcts[i]->Tag(), orgOcts[i]->Data());
+      
+       orgNames.push_back(std::string((char*)blbData.data(),blbData.size()));
    }
-
+	
    return orgNames;
 }
 
 
 // Returns Validity notBefore attribute as "YYYYMMDDHHMMSS"
 
-string X509Cert::ValidityNotBefore() const
+std::string X509Cert::ValidityNotBefore() const
 {
 
    if(m_Validity.SubOctetList().size()!=2)
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
 
    return m_Validity.SubOctetList()[0]->Time();
 
@@ -145,18 +145,18 @@
 
 // Returns Validity notAfter attribute as "YYYYMMDDHHMMSS"
 
-string X509Cert::ValidityNotAfter() const
+std::string X509Cert::ValidityNotAfter() const
 {
 
    if(m_Validity.SubOctetList().size()!=2)
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
 
    return m_Validity.SubOctetList()[1]->Time();
 
 }
 
 
-// Returns whole DER string of Subject
+// Returns whole DER std::string of Subject
 
 BEROctet::Blob X509Cert::Subject() const
 {
@@ -181,16 +181,19 @@
 
    m_Subject.SearchOIDNext(OID_id_at_commonName,cnOcts);
 
-   for(std::vector<BEROctet const*>::size_type i=0; i<cnOcts.size(); i++)
-      cnNames.push_back(string((char*)cnOcts[i]->Data().data(),cnOcts[i]->Data().size()));
+   std::vector<BEROctet const*>::size_type l = cnOcts.size( );
 
+   for( std::vector<BEROctet const*>::size_type i = 0; i< l; ++i ) {
+       
+       cnNames.push_back(std::string((char*)cnOcts[i]->Data().data(),cnOcts[i]->Data().size()));
+   }
    return cnNames;
 
 }
 
 // Returns list of attributes in Subject matching id-at-commonName
 // List will be invalidated when object changes.
-// string in list is in UTF8.
+// std::string in list is in UTF8.
 
 std::vector<std::string> X509Cert::UTF8SubjectCommonName() const
 {
@@ -200,10 +203,13 @@
 
    m_Subject.SearchOIDNext(OID_id_at_commonName,cnOcts);
 
-   for(std::vector<BEROctet const*>::size_type i=0; i<cnOcts.size(); i++)
-   {
-      BEROctet::Blob blbData = ToUTF8(cnOcts[i]->Tag(), cnOcts[i]->Data());
-      cnNames.push_back(string((char*)blbData.data(),blbData.size()));
+   std::vector<BEROctet const*>::size_type l = cnOcts.size( );
+
+   for( std::vector<BEROctet const*>::size_type i = 0; i< l; ++i ) {
+
+       BEROctet::Blob blbData = ToUTF8(cnOcts[i]->Tag(), cnOcts[i]->Data());
+      
+       cnNames.push_back(std::string((char*)blbData.data(),blbData.size()));
    }
 
    return cnNames;
@@ -230,20 +236,20 @@
 {
 
    if(m_SubjectPublicKeyInfo.SubOctetList().size()!=2)
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
 
    BEROctet PubKeyString = *(m_SubjectPublicKeyInfo.SubOctetList()[1]);
 
    BEROctet::Blob KeyBlob = PubKeyString.Data();
 
    if(KeyBlob[0])                                 // Expect number of unused bits in
-      throw runtime_error("X509CertFormatError");    // last octet to be zero.
+      throw std::runtime_error("X509CertFormatError");    // last octet to be zero.
 
 
 
    BEROctet PubKeyOct(KeyBlob.substr(1,BEROctet::Blob::npos));
 
-   if(PubKeyOct.SubOctetList().size()!=2) throw runtime_error("X509CertFormatError");
+   if(PubKeyOct.SubOctetList().size()!=2) throw std::runtime_error("X509CertFormatError");
 
    return PubKeyOct.SubOctetList()[0]->Data();
 
@@ -268,19 +274,19 @@
 {
 
    if(m_SubjectPublicKeyInfo.SubOctetList().size()!=2)
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
 
    BEROctet PubKeyString = *(m_SubjectPublicKeyInfo.SubOctetList()[1]);
 
    BEROctet::Blob KeyBlob = PubKeyString.Data();
 
    if(KeyBlob[0])                                  // Expect number of unused bits
-      throw runtime_error("X509CertFormatError");     // in last octet to be zero.
+      throw std::runtime_error("X509CertFormatError");     // in last octet to be zero.
 
 
    BEROctet PubKeyOct(KeyBlob.substr(1,BEROctet::Blob::npos));
 
-   if(PubKeyOct.SubOctetList().size()!=2) throw runtime_error("X509CertFormatError");
+   if(PubKeyOct.SubOctetList().size()!=2) throw std::runtime_error("X509CertFormatError");
 
    return PubKeyOct.SubOctetList()[1]->Data();
 
@@ -292,7 +298,7 @@
 {
 
    if(!m_Extensions.Data().size())
-      throw runtime_error("X509CertExtensionNotPresent");
+      throw std::runtime_error("X509CertExtensionNotPresent");
 
    unsigned long ReturnKeyUsage = 0;
 
@@ -303,7 +309,7 @@
    m_Extensions.SearchOID(OID_id_ce_keyUsage,ExtensionList);
 
    if(ExtensionList.size()!=1)
-      throw runtime_error("X509CertExtensionNotPresent"); // One and only one instance
+      throw std::runtime_error("X509CertExtensionNotPresent"); // One and only one instance
 
    BEROctet const* Extension = ExtensionList[0];
    BEROctet* extnValue = 0;
@@ -314,10 +320,10 @@
       extnValue = Extension->SubOctetList()[2];  // A "critical" attribute present
 
    else
-      throw runtime_error("X509CertFormatError");    // "Extensions" must contain either 2 or 3 octets
+      throw std::runtime_error("X509CertFormatError");    // "Extensions" must contain either 2 or 3 octets
 
-   BEROctet KeyUsage(extnValue->Data());
-   BEROctet::Blob KeyUsageBitString = KeyUsage.Data();
+   BEROctet v_KeyUsage(extnValue->Data());
+   BEROctet::Blob KeyUsageBitString = v_KeyUsage.Data();
 
    unsigned char UnusedBits = KeyUsageBitString[0];
    size_t NumBytes = KeyUsageBitString.size()-1;
@@ -328,9 +334,11 @@
    }
 
    unsigned long Shift = 24;
-   for(unsigned long i=0; i<NumBytes-1; i++)
-   {
+   unsigned long l = NumBytes - 1;
+   for( unsigned long i = 0 ; i < l ; ++i ) {
+
       ReturnKeyUsage |= (((unsigned long)KeyUsageBitString[i+1]) << Shift);
+      
       Shift -= 8;
    }
 
@@ -340,12 +348,12 @@
 
 }
 
-bool X509Cert::ExtendedKeyUsage(string const &strOID) const
+bool X509Cert::ExtendedKeyUsage(std::string const &strOID) const
 {
    if(!m_Extensions.Data().size())
       return false;
 
-   vector<BEROctet const*> veku;
+   std::vector<BEROctet const*> veku;
 
    m_Extensions.SearchOIDNext(OID_id_ce_extKeyUsage, veku);
    if(veku.size() != 1)
@@ -354,7 +362,7 @@
    try
    {
       BEROctet berEKU(veku[0]->Data());
-      vector<BEROctet const*> ekuOcts;
+      std::vector<BEROctet const*> ekuOcts;
       berEKU.SearchOID(strOID,ekuOcts);
       if(ekuOcts.size() > 0)
          return true;
@@ -385,18 +393,18 @@
    //const unsigned int dwTagSubjectUniqueID = 2;
    const unsigned int dwTagExtensions      = 3;
 
-   if(m_Cert.SubOctetList().size()!=3)  throw runtime_error("X509CertFormatError");
+   if(m_Cert.SubOctetList().size()!=3)  throw std::runtime_error("X509CertFormatError");
 
    BEROctet *tbsCert = m_Cert.SubOctetList()[0];
    size_t Size = tbsCert->SubOctetList().size();
-   if(!Size) throw runtime_error("X509CertFormatError");
+   if(!Size) throw std::runtime_error("X509CertFormatError");
 
    std::vector<BEROctet const*>::size_type  i = 0;
    BEROctet *first = tbsCert->SubOctetList()[i];
    if((first->Class()==tcContext) && (first->Tag()==dwTagVersion)) i++; // Version
 
    if(Size < static_cast<unsigned long>(6+i))
-      throw runtime_error("X509CertFormatError");
+      throw std::runtime_error("X509CertFormatError");
 
    m_SerialNumber = *(tbsCert->SubOctetList()[i]); i++;            // SerialNumber
    i++;                                                            // Signature (algorithm)
@@ -459,13 +467,13 @@
    switch(dwTag)
    {
    case dwBerBMPString:
-      //string in 2 byte Unicode Big Endian format.
+      //std::string in 2 byte Unicode Big Endian format.
       cUnicode = 2;
       bConvert = true;
       break;
    case dwBerUniversalString:
    case dwBerCharacterString:
-      //string in ISO10646, 4 byte unicode big endian format.
+      //std::string in ISO10646, 4 byte unicode big endian format.
       //this is hardly used but we never know.
       cUnicode = 4;
       bConvert = true;
@@ -476,12 +484,13 @@
    }
 
    if(bConvert)
-   {
-      unsigned char bAppend = 0;
-      for(size_t i = 0; i < blbData.size() / cUnicode; i++ )
-      {
+   {                                                                                                                                                                                                    
+      unsigned char bAppend = 0;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
+      size_t l = blbData.size() / cUnicode;
+      for(size_t i = 0; i < l; ++i ) {
+
          unsigned int dwUnicode = 0;
-         unsigned int dwTemp = 0;
+         unsigned int dwTemp = 0;                                                                                                                                                                           
          int nBytesInUTF8 = 0;
 
          //first get the Unicode unsigned int from BIG ENDIAN BYTES.
@@ -562,3 +571,12 @@
    }
    return blbReturn;
 }
+
+
+/* Check if the Smart Card Logon OID (1.3.6.1.4.1.311.20.2.2)
+is present in the Enhanced/Extended Key Usage
+*/
+bool X509Cert::isSmartCardLogon( void ) const
+{
+   return ExtendedKeyUsage( OID_ms_smartCardLogin );
+}

Modified: trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,24 +1,23 @@
 /*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
+*  PKCS#11 library for .Net smart cards
+*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
+*
+*  This library is free software; you can redistribute it and/or
+*  modify it under the terms of the GNU Lesser General Public
+*  License as published by the Free Software Foundation; either
+*  version 2.1 of the License, or (at your option) any later version.
+*
+*  This library is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+*  Lesser General Public License for more details.
+*
+*  You should have received a copy of the GNU Lesser General Public
+*  License along with this library; if not, write to the Free Software
+*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+*
+*/
 
-// This code is based on class in ACS baseline.
 
 #ifndef _include_x509cert_h
 #define _include_x509cert_h
@@ -32,49 +31,50 @@
 {
 
 public:
-    X509Cert();
-    X509Cert(const X509Cert &cert);
-    X509Cert(const BEROctet::Blob &buffer);
-    X509Cert(const unsigned char *buffer, const unsigned long size);
-    X509Cert& operator=(const X509Cert &cert);
-    X509Cert& operator=(const BEROctet::Blob &buffer);
+   X509Cert();
+   X509Cert(const X509Cert &cert);
+   X509Cert(const BEROctet::Blob &buffer);
+   X509Cert(const unsigned char *buffer, const unsigned long size);
+   X509Cert& operator=(const X509Cert &cert);
+   X509Cert& operator=(const BEROctet::Blob &buffer);
 
-    BEROctet::Blob SerialNumber() const;
-    BEROctet::Blob Issuer() const;
-    BEROctet::Blob UTF8Issuer() const;
-    std::vector<std::string> IssuerOrg() const;
-    std::vector<std::string> UTF8IssuerOrg() const;
-    std::string ValidityNotBefore() const;
-    std::string ValidityNotAfter() const;
-    BEROctet::Blob Subject() const;
-    BEROctet::Blob UTF8Subject() const;
-    std::vector<std::string> SubjectCommonName() const;
-    std::vector<std::string> UTF8SubjectCommonName() const;
-    BEROctet::Blob Modulus() const;
-    BEROctet::Blob RawModulus() const;
-    BEROctet::Blob PublicExponent() const;
-    BEROctet::Blob RawPublicExponent() const;
+   BEROctet::Blob SerialNumber() const;
+   BEROctet::Blob Issuer() const;
+   BEROctet::Blob UTF8Issuer() const;
+   std::vector<std::string> IssuerOrg() const;
+   std::vector<std::string> UTF8IssuerOrg() const;
+   std::string ValidityNotBefore() const;
+   std::string ValidityNotAfter() const;
+   BEROctet::Blob Subject() const;
+   BEROctet::Blob UTF8Subject() const;
+   std::vector<std::string> SubjectCommonName() const;
+   std::vector<std::string> UTF8SubjectCommonName() const;
+   BEROctet::Blob Modulus() const;
+   BEROctet::Blob RawModulus() const;
+   BEROctet::Blob PublicExponent() const;
+   BEROctet::Blob RawPublicExponent() const;
 
-    unsigned long KeyUsage() const;
-    bool ExtendedKeyUsage(std::string const &strOID) const;
-    bool IsCACert() const;
-    bool IsRootCert() const;
+   unsigned long KeyUsage() const;
+   bool ExtendedKeyUsage(std::string const &strOID) const;
+   bool IsCACert() const;
+   bool IsRootCert() const;
+   bool isSmartCardLogon( void ) const;
 
 private:
-    void Decode();
+   void Decode();
 
-    BEROctet::Blob ToUTF8( unsigned int dwTag, const BEROctet::Blob &blbData ) const;
+   BEROctet::Blob ToUTF8( unsigned int dwTag, const BEROctet::Blob &blbData ) const;
 
 private:
-    BEROctet m_Cert;
-    BEROctet m_SerialNumber;
-    BEROctet m_Issuer;
-    BEROctet m_Validity;
-    BEROctet m_Subject;
-    BEROctet m_SubjectPublicKeyInfo;
-    BEROctet m_Extensions;
-    bool     m_bCACert;
-    bool     m_bRootCert;
+   BEROctet m_Cert;
+   BEROctet m_SerialNumber;
+   BEROctet m_Issuer;
+   BEROctet m_Validity;
+   BEROctet m_Subject;
+   BEROctet m_SubjectPublicKeyInfo;
+   BEROctet m_Extensions;
+   bool     m_bCACert;
+   bool     m_bRootCert;
 
 
 };

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,265 +0,0 @@
-/*
- *  PKCS#11 library for .Net smart cards
- *  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include "stdafx.h"
-#include "platconfig.h"
-#include "config.h"
-#include "util.h"
-
-#include "x509pubkeycertobject.h"
-
-X509PubKeyCertObject::X509PubKeyCertObject() : CertificateObject()
-{
-    this->_subject              = NULL_PTR;
-    this->_id                   = NULL_PTR;
-    this->_issuer               = NULL_PTR;
-    this->_serialNumber         = NULL_PTR;
-    this->_value                = NULL_PTR;
-    this->_url                  = NULL_PTR;
-    this->_hashOfSubjectPubKey  = NULL_PTR;
-    this->_hashOfIssuerPubKey   = NULL_PTR;
-
-    this->_certType             = CKC_X_509;
-    this->_trusted              = CK_TRUE;
-}
-
-X509PubKeyCertObject::~X509PubKeyCertObject()
-{
-    if(this->_subject != NULL_PTR)
-        delete this->_subject;
-
-    if(this->_id != NULL_PTR)
-        delete this->_id;
-
-    if(this->_issuer != NULL_PTR)
-        delete this->_issuer;
-
-    if(this->_serialNumber != NULL_PTR)
-        delete this->_serialNumber;
-
-    if(this->_value != NULL_PTR)
-        delete this->_value;
-
-    if(this->_url != NULL_PTR)
-        delete this->_url;
-
-    if(this->_hashOfSubjectPubKey != NULL_PTR)
-        delete this->_hashOfSubjectPubKey;
-
-    if(this->_hashOfIssuerPubKey != NULL_PTR)
-        delete this->_hashOfIssuerPubKey;
-
-}
-
-CK_BBOOL X509PubKeyCertObject::Compare(CK_ATTRIBUTE attribute)
-{
-    switch(attribute.type){
-
-        case CKA_SUBJECT:
-            return Util::CompareU1Arrays(this->_subject,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_ID:
-            return Util::CompareU1Arrays(this->_id,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_ISSUER:
-            return Util::CompareU1Arrays(this->_issuer,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_SERIAL_NUMBER:
-            return Util::CompareU1Arrays(this->_serialNumber,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_VALUE:
-            return Util::CompareU1Arrays(this->_value,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_URL:
-            return Util::CompareU1Arrays(this->_url,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
-            return Util::CompareU1Arrays(this->_hashOfSubjectPubKey,attribute.pValue,attribute.ulValueLen);
-
-        case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
-            return Util::CompareU1Arrays(this->_hashOfIssuerPubKey,attribute.pValue,attribute.ulValueLen);
-
-        default:
-            return CertificateObject::Compare(attribute);
-    }
-}
-
-CK_RV X509PubKeyCertObject::SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation)
-{
-   if( 0 == attribute.ulValueLen )
-   {
-      return CKR_OK;
-   }
-
-   CK_RV rv = CKR_OK;
-
-    if(objCreation == CK_FALSE){
-        switch(attribute.type){
-            case CKA_SUBJECT:
-            case CKA_VALUE:
-                return CKR_ATTRIBUTE_READ_ONLY;
-        }
-    }
-
-    switch(attribute.type){
-
-        case CKA_SUBJECT:
-            if(this->_subject != NULL_PTR){
-                delete this->_subject;
-            }
-            this->_subject = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_ID:
-            if(this->_id != NULL_PTR){
-                delete this->_id;
-            }
-            this->_id = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_ISSUER:
-            if(this->_issuer != NULL_PTR){
-                delete this->_issuer;
-            }
-            this->_issuer = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_SERIAL_NUMBER:
-            if(this->_serialNumber != NULL_PTR){
-                delete this->_serialNumber;
-            }
-            this->_serialNumber = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_VALUE:
-            if(this->_value != NULL_PTR){
-                delete this->_value;
-            }
-            this->_value = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_URL:
-            {
-                u1Array* stemp = StorageObject::ReadStringFromAttribute(attribute,&rv);
-                if(rv == CKR_OK){
-                    if(this->_url != NULL_PTR){
-                        delete this->_url;
-                    }
-                    this->_url = stemp;
-                }
-            }
-            break;
-
-        case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
-            if(this->_hashOfSubjectPubKey != NULL_PTR){
-                delete this->_hashOfSubjectPubKey;
-            }
-            this->_hashOfSubjectPubKey = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
-            if(this->_hashOfIssuerPubKey != NULL_PTR){
-                delete this->_hashOfIssuerPubKey;
-            }
-            this->_hashOfIssuerPubKey = StorageObject::ReadU1ArrayFromAttribute(attribute);
-            break;
-
-        default:
-            return CertificateObject::SetAttribute(attribute,objCreation);
-    }
-
-    return rv;
-}
-
-CK_RV X509PubKeyCertObject::GetAttribute(CK_ATTRIBUTE_PTR attribute)
-{
-    switch(attribute->type){
-
-        case CKA_SUBJECT:
-            return StorageObject::PutU1ArrayInAttribute(this->_subject,attribute);
-
-        case CKA_ID:
-            return StorageObject::PutU1ArrayInAttribute(this->_id,attribute);
-
-        case CKA_ISSUER:
-            return StorageObject::PutU1ArrayInAttribute(this->_issuer,attribute);
-
-        case CKA_SERIAL_NUMBER:
-            return StorageObject::PutU1ArrayInAttribute(this->_serialNumber,attribute);
-
-        case CKA_VALUE:
-            return StorageObject::PutU1ArrayInAttribute(this->_value,attribute);
-
-        case CKA_URL:
-            return StorageObject::PutU1ArrayInAttribute(this->_url,attribute);
-
-        case CKA_HASH_OF_SUBJECT_PUBLIC_KEY:
-            return StorageObject::PutU1ArrayInAttribute(this->_hashOfSubjectPubKey,attribute);
-
-        case CKA_HASH_OF_ISSUER_PUBLIC_KEY:
-            return StorageObject::PutU1ArrayInAttribute(this->_hashOfIssuerPubKey,attribute);
-
-        default:
-            return CertificateObject::GetAttribute(attribute);
-    }
-}
-
-void X509PubKeyCertObject::Serialize(std::vector<u1> *to)
-{
-    CertificateObject::Serialize(to);
-
-    Util::PushByteArrayInVector(to,this->_subject);
-
-    Util::PushByteArrayInVector(to,this->_id);
-
-    Util::PushByteArrayInVector(to,this->_issuer);
-
-    Util::PushByteArrayInVector(to,this->_serialNumber);
-
-    Util::PushByteArrayInVector(to,this->_url);
-
-    Util::PushByteArrayInVector(to,this->_hashOfSubjectPubKey);
-
-    Util::PushByteArrayInVector(to,this->_hashOfIssuerPubKey);
-
-    PKCS11_ASSERT(!this->_certName.empty());
-
-}
-
-void X509PubKeyCertObject::Deserialize(std::vector<u1> from, CK_ULONG_PTR idx)
-{
-    CertificateObject::Deserialize(from,idx);
-
-    this->_subject = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_id = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_issuer = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_serialNumber = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_url = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_hashOfSubjectPubKey = Util::ReadByteArrayFromVector(from,idx);
-
-    this->_hashOfIssuerPubKey = Util::ReadByteArrayFromVector(from,idx);
-
-}
-

Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h	2012-02-20 13:52:47 UTC (rev 140)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h	2012-02-20 14:26:10 UTC (rev 141)
@@ -1,53 +0,0 @@
-/*
-*  PKCS#11 library for .Net smart cards
-*  Copyright (C) 2007-2009 Gemalto <support at gemalto.com>
-*
-*  This library is free software; you can redistribute it and/or
-*  modify it under the terms of the GNU Lesser General Public
-*  License as published by the Free Software Foundation; either
-*  version 2.1 of the License, or (at your option) any later version.
-*
-*  This library is distributed in the hope that it will be useful,
-*  but WITHOUT ANY WARRANTY; without even the implied warranty of
-*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-*  Lesser General Public License for more details.
-*
-*  You should have received a copy of the GNU Lesser General Public
-*  License along with this library; if not, write to the Free Software
-*  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*
-*/
-
-#ifndef _include_x509pubkeycertobject_h
-#define _include_x509pubkeycertobject_h
-
-#include "certificateobject.h"
-
-class X509PubKeyCertObject : public CertificateObject
-{
-
-public:
-   u1Array*    _subject;
-   u1Array*    _id;
-   u1Array*    _issuer;
-   u1Array*    _serialNumber;
-   u1Array*    _value;
-   u1Array*    _url;
-   u1Array*    _hashOfSubjectPubKey;
-   u1Array*    _hashOfIssuerPubKey;
-
-public:
-   X509PubKeyCertObject();
-   virtual ~X509PubKeyCertObject();
-
-   CK_BBOOL Compare(CK_ATTRIBUTE attribute);
-   CK_RV SetAttribute(CK_ATTRIBUTE attribute,CK_BBOOL objCreation);
-   CK_RV GetAttribute(CK_ATTRIBUTE_PTR attribute);
-
-   void Serialize(vector<u1>* to);
-   void Deserialize(vector<u1> from,CK_ULONG_PTR idx);
-
-};
-
-#endif
-
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/smartcardservices-changes/attachments/20120220/1f342c5b/attachment-0001.html>


More information about the SmartcardServices-Changes mailing list