[SmartcardServices-Changes] [140] trunk/SmartCardServices/src/PKCS11dotNetV2
source_changes at macosforge.org
source_changes at macosforge.org
Mon Feb 20 05:53:32 PST 2012
Revision: 140
http://trac.macosforge.org/projects/smartcardservices/changeset/140
Author: ludovic.rousseau at gmail.com
Date: 2012-02-20 05:52:47 -0800 (Mon, 20 Feb 2012)
Log Message:
-----------
Move all sources files in main directory
Added Paths:
-----------
trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h
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_sha256.h
trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.h
trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/application.h
trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.h
trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.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/cert_utils.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h
trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h
trunk/SmartCardServices/src/PKCS11dotNetV2/config.h
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.h
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_global.h
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.h
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.h
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.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/des.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/des.h
trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h
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/ha_config.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/md5.h
trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h
trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h
trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h
trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h
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/sha1.h
trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.h
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/symmalgo.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h
trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.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/util.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/util.h
trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h
trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp
trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h
Removed Paths:
-------------
trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am
trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/
trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/Array.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Array.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,974 @@
+/*
+ * 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>
+#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"
+
+// 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 isLittleEndian = (*((unsigned char *)(&_endian))) ? true : false;
+bool isBigEndian = (*((unsigned char *)(&_endian))) ? false : true;
+MARSHALLER_NS_BEGIN
+
+
+static u4 ToBigEndian(u4 val)
+{
+ if (isBigEndian)
+ {
+ return val;
+ }
+ else
+ {
+ u4 res;
+ res = val << 24;
+ res |= (val << 8) & 0x00FF0000;
+ res |= (val >> 8) & 0x0000FF00;
+ res |= val >> 24;
+
+ return res;
+ }
+}
+
+static u2 ToBigEndian(u2 val)
+{
+ if (isBigEndian)
+ {
+ return val;
+ }
+ else
+ {
+ return (u2)((val << 8) | (val >> 8));
+ }
+}
+
+static u8 ToBigEndian(u8 val)
+{
+ if (isBigEndian)
+ {
+ return val;
+ }
+ else
+ {
+ u4 val1 = (u4)(val >> 32);
+ u4 val2 = (u4)val;
+
+ val1 = ToBigEndian(val1);
+ val2 = ToBigEndian(val2);
+
+ return (u8)(((u8)val2 << 32) | val1);
+ }
+}
+
+u2 ComputeUTF8Length(M_SAL_IN lpCharPtr str)
+{
+ u4 nCharProcessed = 0;
+ u4 pair;
+ u4 count;
+ u2 leftOver;
+ u4 charIndex;
+
+ count = 0;
+ leftOver = 0;
+ charIndex = 0;
+
+ while (nCharProcessed < (u4)strlen(str)) {
+ u2 ch = (u2)str[charIndex++];
+
+ if (leftOver == 0) {
+ if ((ch >= 0xD800) && (ch <= 0xDBFF)) {
+ // This is a low-part of a surrogate pair.
+ leftOver = (u2)ch;
+ nCharProcessed++;
+ continue;
+ } else {
+ // This is a regular character.
+ pair = (u4)ch;
+ }
+ } else if ((ch >= 0xDC00) && (ch <= 0xDFFF)) {
+ // This is a high-part of a surrogate pair. We now have a complete surrogate pair.
+ pair = ((leftOver - (u4)0xD800) << 10) + (((u4)ch) - (u4)0xDC00) + (u4)0x10000;
+ leftOver = 0;
+ } else {
+ goto error;
+ }
+
+ // Encode the character pair value.
+ if (pair < (u4)0x0080) {
+ count++;
+ } else if (pair < (u4)0x0800) {
+ count += 2;
+ } else if (pair < (u4)0x10000) {
+ count += 3;
+ } else {
+ count += 4;
+ }
+
+ nCharProcessed++;
+ }
+
+ if (leftOver != 0) {
+ goto error;
+ }
+
+ return (u2)count;
+
+error:;
+ throw Exception("Error while compute UTF8 encoding length");
+}
+
+void UTF8Encode(M_SAL_IN lpCharPtr str, u1Array &utf8Data)
+{
+ u4 nCharProcessed = 0;
+ u4 pair;
+ u2 leftOver;
+ u1* bytes = utf8Data.GetBuffer();
+ u4 byteCount;
+ u4 byteIndex = 0;
+ u4 charIndex = 0;
+
+ byteCount = utf8Data.GetLength();
+
+ leftOver = 0;
+
+ while (nCharProcessed < (u4)strlen(str)) {
+ u2 ch = str[charIndex++];
+
+ if (leftOver == 0) {
+ if ((ch >= 0xD800) && (ch <= 0xDBFF)) {
+ // This is a low-part of a surrogate pair.
+ leftOver = (u2)ch;
+ nCharProcessed++;
+ continue;
+ } else {
+ // This is a regular character.
+ pair = (u4)ch;
+ }
+ } else if ((ch >= 0xDC00) && (ch <= 0xDFFF)) {
+ // This is a high-part of a surrogate pair. We now have a complete surrogate pair.
+ pair = ((leftOver - (u4)0xD800) << 10) + (((u4)ch) - (u4)0xDC00) + (u4)0x10000;
+ leftOver = 0;
+ } else {
+ goto error;
+ }
+
+ // Encode the character pair value.
+ if (pair < (u4)0x0080) {
+ if (byteIndex >= byteCount) {
+ goto end;
+ }
+ bytes[byteIndex++] = (u1)pair;
+ } else if (pair < (u4)0x0800) {
+ if ((byteIndex + 2) > byteCount) {
+ goto end;
+ }
+ bytes[byteIndex++] = (u1)(0xC0 | (pair >> 6));
+ bytes[byteIndex++] = (u1)(0x80 | (pair & 0x3F));
+ } else if (pair < (u4)0x10000) {
+ if ((byteIndex + 3) > byteCount) {
+ goto end;
+ }
+ bytes[byteIndex++] = (u1)(0xE0 | (pair >> 12));
+ bytes[byteIndex++] = (u1)(0x80 | ((pair >> 6) & 0x3F));
+ bytes[byteIndex++] = (u1)(0x80 | (pair & 0x3F));
+ } else {
+ if ((byteIndex + 4) > byteCount) {
+ goto end;
+ }
+ bytes[byteIndex++] = (u1)(0xF0 | (pair >> 18));
+ bytes[byteIndex++] = (u1)(0x80 | ((pair >> 12) & 0x3F));
+ bytes[byteIndex++] = (u1)(0x80 | ((pair >> 6) & 0x3F));
+ bytes[byteIndex++] = (u1)(0x80 | (pair & 0x3F));
+ }
+
+ nCharProcessed++;
+ }
+
+end:;
+ // we do accept byteIndex <= byteCount (dest buffer length > what is really necessary).
+ if (byteIndex > byteCount) {
+ goto error;
+ }
+
+ if (leftOver != 0) {
+ goto error;
+ }
+
+ return;
+
+error:;
+ throw Exception("Error while performing UTF8 encoding");
+}
+
+u2 ComputeLPSTRLength(u1Array &array, u4 offset, u4 len)
+{
+ if ((u8)(offset + len) > (u8)array.GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ } else {
+ u2 charlen = 0;
+ u4 i;
+ u1* buff = array.GetBuffer();
+
+ for (i = 0; i < len;) {
+ if ((buff[i + offset] & 0x80) == 0) {
+ i += 1;
+ }
+ else if ((buff[i + offset] & 0xE0) == 0xC0) {
+ i += 2;
+ }
+ else if ((buff[i + offset] & 0xF0) == 0xE0) {
+ i += 3;
+ }
+ else {
+ throw Exception("Error parsing UTF-8 bytes");
+ }
+ charlen++;
+ }
+ return charlen;
+ }
+}
+
+void UTF8Decode(u1Array &array, u4 offset, u4 len, M_SAL_INOUT lpCharPtr &charData)
+{
+ if ((u8)(offset + len) > (u8)array.GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ } else {
+ u4 i = 0;
+ u4 pos = 0;
+ u1* buff = array.GetBuffer();
+
+ for (i = 0; i < len;) {
+ if ((buff[i + offset] & 0x80) == 0) {
+ charData[pos] = buff[i + offset];
+ i += 1;
+ }
+ else if ((buff[i + offset] & 0xE0) == 0xC0) {
+ charData[pos] = ((buff[i + offset] & 0x1F) << 6) | (buff[i+1 + offset] & 0x3F);
+ i += 2;
+ }
+ else if ((buff[i + offset] & 0xF0) == 0xE0) {
+ charData[pos] = ((buff[i + offset] & 0x0F) << 12) | ((buff[i+1 + offset] & 0x3F) << 6) | (buff[i+2 + offset] & 0x3F);
+ i += 3;
+ }
+ else{
+ throw Exception("Error parsing UTF-8 bytes");
+ }
+ pos++;
+ }
+ }
+}
+
+// *******************
+// String Array class
+// *******************
+StringArray::StringArray(s4 nelement)
+{
+ this->_length = nelement;
+
+ if (nelement < 0) {
+ nelement = 0;
+ }
+
+ this->buffer = new std::string*[nelement];
+
+ // we need to initialize the buffer to zeros
+ for(s4 i=0;i<nelement;i++)
+ this->buffer[i] = NULL;
+
+}
+
+StringArray::StringArray(const StringArray &rhs)
+{
+ s4 len = rhs._length;
+ this->_length = len;
+ if (len < 0) {
+ len = 0;
+ }
+
+ this->buffer = new std::string*[len];
+
+ for(s4 i=0;i<len;i++)
+ this->buffer[i] = rhs.buffer[i];
+
+}
+
+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;
+}
+
+u1 StringArray::IsNull(void)
+{
+ return (this->_length < 0);
+}
+
+u4 StringArray::GetLength(void)
+{
+ if (IsNull()) {
+ return (u4)0;
+ } else {
+ return (u4)this->_length;
+ }
+}
+
+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;
+}
+
+// *******************
+// Byte Array class
+// *******************
+
+u1Array::u1Array()
+{
+ this->_length = 0;
+// JCD
+ this->buffer = NULL;//new u1[0];
+// JCD
+}
+
+u1Array::u1Array(s4 nelement)
+{
+ this->_length = nelement;
+ if (nelement < 0) {
+ nelement = 0;
+ }
+ this->buffer = new u1[nelement];
+}
+
+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);
+ }
+}
+
+u1Array::~u1Array(void)
+{
+ if (this->buffer != NULL) {
+ delete[] this->buffer;
+ this->buffer = NULL;
+ }
+}
+
+u1 u1Array::IsNull(void) const
+{
+ return (this->_length < 0);
+}
+
+void u1Array::SetU1At(u4 pos, u1 val)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ this->buffer[pos] = val;
+}
+
+
+u1 u1Array::ReadU1At(u4 pos) const
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ return this->buffer[pos];
+}
+
+u4 u1Array::GetLength(void) const
+{
+ if (IsNull()) {
+ return (u4)0;
+ } else {
+ return (u4)this->_length;
+ }
+}
+
+void u1Array::SetBuffer(const u1* buffer)
+{
+ memcpy(this->buffer, buffer, this->GetLength());
+}
+
+const u1* u1Array::GetBuffer(void) const
+{
+ return this->buffer;
+}
+
+u1* u1Array::GetBuffer(void)
+{
+ return this->buffer;
+}
+
+// 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;
+}
+
+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;
+}
+
+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);
+ 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);
+ 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;
+}
+
+
+// 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);
+ 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;
+ } else {
+ this->_length = this->GetLength() + bArray.GetLength();
+ }
+ return *this;
+}
+
+u1Array& u1Array::Append(std::string* str)
+{
+ if (str == NULL) {
+ *this += (u2)0xFFFF;
+ } else {
+ u2 strLen = ComputeUTF8Length((lpCharPtr)str->c_str());
+ *this += strLen;
+ u1Array strArray(strLen);
+ UTF8Encode((lpCharPtr)str->c_str(), strArray);
+ *this += strArray;
+ }
+ return *this;
+}
+
+// *******************
+// UShort Array class
+// *******************
+u2Array::u2Array(s4 nelement)
+{
+ this->_length = nelement;
+ if (nelement < 0) {
+ nelement = 0;
+ }
+ this->buffer = new u2[nelement];
+}
+
+u2Array::u2Array(const u2Array &rhs)
+{
+ s4 len = rhs._length;
+ this->_length = len;
+ if (len < 0) {
+ len = 0;
+ }
+ this->buffer = new u2[len];
+ memcpy(this->buffer, rhs.buffer, len * sizeof(u2));
+}
+
+u2Array::~u2Array(void)
+{
+ delete[] this->buffer;
+}
+
+u1 u2Array::IsNull(void)
+{
+ return (this->_length < 0);
+}
+
+void u2Array::SetU2At(u4 pos, u2 val)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ this->buffer[pos] = val;
+}
+
+u2 u2Array::ReadU2At(u4 pos)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ return this->buffer[pos];
+}
+
+u4 u2Array::GetLength(void)
+{
+ if (IsNull()) {
+ return (u4)0;
+ } else {
+ return (u4)this->_length;
+ }
+}
+
+void u2Array::SetBuffer(u2* buffer)
+{
+ memcpy(this->buffer, buffer, this->GetLength() * sizeof(u2));
+}
+
+u2* u2Array::GetBuffer(void)
+{
+ return this->buffer;
+}
+
+// 2 bytes add
+u2Array& u2Array::operator +(u2 val)
+{
+ u2Array* newArray = new u2Array(this->GetLength() + 1);
+ memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u2));
+ newArray->buffer[this->GetLength()] = val;
+ return *newArray;
+}
+
+u2Array& u2Array::operator +=(u2 val)
+{
+ 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;
+ return *this;
+}
+
+// Char array add
+u2Array& u2Array::operator +(u2Array &cArray)
+{
+ s4 len;
+ if (IsNull() && cArray.IsNull()) {
+ len = -1;
+ } else {
+ len = this->GetLength() + cArray.GetLength();
+ }
+ 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));
+ 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;
+ if (IsNull() && cArray.IsNull()) {
+ this->_length = -1;
+ } else {
+ this->_length = this->GetLength() + cArray.GetLength();
+ }
+ return *this;
+}
+
+// *******************
+// Int Array class
+// *******************
+u4Array::u4Array(s4 nelement)
+{
+ this->_length = nelement;
+ if (nelement < 0) {
+ nelement = 0;
+ }
+ this->buffer = new u4[nelement];
+}
+
+u4Array::u4Array(const u4Array &rhs)
+{
+ s4 len = rhs._length;
+ this->_length = len;
+ if (len < 0) {
+ len = 0;
+ }
+ this->buffer = new u4[len];
+ memcpy(this->buffer, rhs.buffer, len * sizeof(u4));
+}
+
+u4Array::~u4Array(void)
+{
+ delete[] this->buffer;
+}
+
+u1 u4Array::IsNull(void)
+{
+ return (this->_length < 0);
+}
+
+void u4Array::SetU4At(u4 pos, u4 val)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ this->buffer[pos] = val;
+}
+
+u4 u4Array::ReadU4At(u4 pos)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ return this->buffer[pos];
+}
+
+u4 u4Array::GetLength(void)
+{
+ if (IsNull()) {
+ return (u4)0;
+ } else {
+ return (u4)this->_length;
+ }
+}
+
+void u4Array::SetBuffer(u4* buffer)
+{
+ memcpy(this->buffer, buffer, this->GetLength() * sizeof(u4));
+}
+
+u4* u4Array::GetBuffer(void)
+{
+ return this->buffer;
+}
+
+// 4 bytes add
+u4Array& u4Array::operator +(u4 val)
+{
+ u4Array* newArray = new u4Array(this->GetLength() + 1);
+ memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u4));
+ newArray->buffer[this->GetLength()] = val;
+ return *newArray;
+}
+
+u4Array& u4Array::operator +=(u4 val)
+{
+ 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;
+ return *this;
+}
+
+// UInt array add
+u4Array& u4Array::operator +(u4Array &iArray)
+{
+ s4 len;
+ if (IsNull() && iArray.IsNull()) {
+ len = -1;
+ } else {
+ len = this->GetLength() + iArray.GetLength();
+ }
+ 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));
+ 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;
+ if (IsNull() && iArray.IsNull()) {
+ this->_length = -1;
+ } else {
+ this->_length = this->GetLength() + iArray.GetLength();
+ }
+ return *this;
+}
+
+
+// *******************
+// Long Array class
+// *******************
+u8Array::u8Array(s4 nelement)
+{
+ this->_length = nelement;
+ if (nelement < 0) {
+ nelement = 0;
+ }
+ this->buffer = new u8[nelement];
+}
+
+u8Array::u8Array(const u8Array &rhs)
+{
+ s4 len = rhs._length;
+ this->_length = len;
+ if (len < 0) {
+ len = 0;
+ }
+ this->buffer = new u8[len];
+ memcpy(this->buffer, rhs.buffer, len * sizeof(u8));
+}
+
+u8Array::~u8Array(void)
+{
+ delete[] this->buffer;
+}
+
+u1 u8Array::IsNull(void)
+{
+ return (this->_length < 0);
+}
+
+void u8Array::SetU8At(u4 pos, u8 val)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ this->buffer[pos] = val;
+}
+
+u8 u8Array::ReadU8At(u4 pos)
+{
+ if (pos >= GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+ return this->buffer[pos];
+}
+
+u4 u8Array::GetLength(void)
+{
+ if (IsNull()) {
+ return (u4)0;
+ } else {
+ return (u4)this->_length;
+ }
+}
+
+void u8Array::SetBuffer(u8* buffer)
+{
+ memcpy(this->buffer, buffer, this->GetLength() * sizeof(u8));
+}
+
+u8* u8Array::GetBuffer(void)
+{
+ return this->buffer;
+}
+
+u8Array& u8Array::operator +(u8 val)
+{
+ u8Array* newArray = new u8Array(this->GetLength() + 1);
+ memcpy(newArray->buffer, this->buffer, this->GetLength() * sizeof(u8));
+ newArray->buffer[this->GetLength()] = val;
+ return *newArray;
+}
+
+u8Array& u8Array::operator +=(u8 val)
+{
+ 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;
+ return *this;
+}
+
+u8Array& u8Array::operator +(u8Array &iArray)
+{
+ s4 len;
+ if (IsNull() && iArray.IsNull()) {
+ len = -1;
+ } else {
+ len = this->GetLength() + iArray.GetLength();
+ }
+ 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));
+ 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;
+ if (IsNull() && iArray.IsNull()) {
+ this->_length = -1;
+ } else {
+ this->_length = this->GetLength() + iArray.GetLength();
+ }
+ return *this;
+}
+
+MARSHALLER_NS_END
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/Array.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Array.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,180 @@
+/*
+ * 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/Except.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/Except.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Except.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Except.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,338 @@
+/*
+ * 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
+
+// .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();
+ }
+};
+
+class SystemException : public Exception{
+
+public:
+ explicit SystemException(std::string msg) : Exception(msg) { }
+ explicit SystemException(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 : "") { }
+
+};
+
+class ArgumentNullException : public Exception{
+
+public:
+ explicit ArgumentNullException(std::string msg) : Exception(msg) { }
+ explicit ArgumentNullException();
+ explicit ArgumentNullException(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 : "") { }
+
+};
+
+class IndexOutOfRangeException : public Exception{
+
+public:
+ explicit IndexOutOfRangeException(std::string msg) : Exception(msg) { }
+ explicit IndexOutOfRangeException(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 : "") { }
+
+};
+
+class InvalidOperationException : public Exception{
+
+public:
+ explicit InvalidOperationException(std::string msg) : Exception(msg) { }
+ explicit InvalidOperationException(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 : "") { }
+
+};
+
+class NotSupportedException : public Exception{
+
+public:
+ explicit NotSupportedException(std::string msg) : Exception(msg) { }
+ explicit NotSupportedException(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 : "") { }
+
+};
+
+class OutOfMemoryException : public Exception{
+
+public:
+ explicit OutOfMemoryException(std::string msg) : Exception(msg) { }
+ explicit OutOfMemoryException(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 : "") { }
+
+};
+
+class ObjectDisposedException : public Exception{
+
+public:
+ explicit ObjectDisposedException(std::string msg) : Exception(msg) { }
+ explicit ObjectDisposedException(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 : "") { }
+
+};
+
+class ArithmeticException : public Exception{
+
+public:
+ explicit ArithmeticException(std::string msg) : Exception(msg) { }
+ explicit ArithmeticException(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 : "") { }
+
+};
+
+class BadImageFormatException : public Exception{
+
+public:
+ explicit BadImageFormatException(std::string msg) : Exception(msg) { }
+ explicit BadImageFormatException(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 : "") { }
+
+};
+
+class DirectoryNotFoundException : public Exception{
+
+public:
+ explicit DirectoryNotFoundException(std::string msg) : Exception(msg) { }
+ explicit DirectoryNotFoundException(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 : "") { }
+
+};
+
+class FileNotFoundException : public Exception{
+
+public:
+ explicit FileNotFoundException(std::string msg) : Exception(msg) { }
+ explicit FileNotFoundException(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 : "") { }
+
+};
+
+class IOException : public Exception{
+
+public:
+ explicit IOException(std::string msg) : Exception(msg) { }
+ explicit IOException(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 : "") { }
+
+};
+
+class RemotingException : public Exception{
+
+private:
+ s4 resultCode; // this code is for PCSC releated error/success codes
+
+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;
+ }
+};
+
+class StackOverflowException : public Exception{
+
+public:
+ explicit StackOverflowException(std::string msg) : Exception(msg) { }
+ explicit StackOverflowException(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 : "") { }
+
+};
+
+class MemberAccessException : public Exception{
+
+public:
+ explicit MemberAccessException(std::string msg) : Exception(msg) { }
+ explicit MemberAccessException(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 : "") { }
+
+};
+
+class MissingMemberException : public Exception{
+
+public:
+ explicit MissingMemberException(std::string msg) : Exception(msg) { }
+ explicit MissingMemberException(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 : "") { }
+
+};
+
+class OverflowException : public Exception{
+
+public:
+ explicit OverflowException(std::string msg) : Exception(msg) { }
+ explicit OverflowException(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 : "") { }
+
+};
+
+class VerificationException : public Exception{
+
+public:
+ explicit VerificationException(std::string msg) : Exception(msg) { }
+ explicit VerificationException(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 : "") { }
+
+};
+
+MARSHALLER_NS_END
+
+#endif
+
Deleted: trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am 2011-03-21 14:21:33 UTC (rev 139)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am 2012-02-20 13:52:47 UTC (rev 140)
@@ -1,3 +0,0 @@
-SUBDIRS = PKCS11Module2
-
-EXTRA_DIST = autogen.sh c-mac.sh LGPL-2.1
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/Makefile.am)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Makefile.am 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,136 @@
+lib_LTLIBRARIES = libgtop11dotnet.la
+
+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 \
+ algo_md5.h \
+ algo_sha1.cpp \
+ algo_sha1.h \
+ algo_sha256.cpp \
+ algo_sha256.h \
+ algo_utils.cpp \
+ algo_utils.h \
+ application.cpp \
+ application.h \
+ attrcert.cpp \
+ attrcert.h \
+ beroctet.cpp \
+ beroctet.h \
+ cardcache.cpp \
+ cardcache.h \
+ cardmoduleservice.cpp \
+ cardmoduleservice.h \
+ certificateobject.cpp \
+ certificateobject.h \
+ cert_utils.cpp \
+ cert_utils.h \
+ config.h \
+ critsect.cpp \
+ critsect.h \
+ dataobject.cpp \
+ dataobject.h \
+ des.cpp \
+ des.h \
+ digest.cpp \
+ digest.h \
+ error.cpp \
+ error.h \
+ event.cpp \
+ event.h \
+ keyobject.cpp \
+ keyobject.h \
+ md5.cpp \
+ md5.h \
+ mutex.cpp \
+ mutex.h \
+ pkcs11.cpp \
+ pkcs11f.h \
+ pkcs11.h \
+ 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 \
+ sha1.h \
+ sha256.cpp \
+ sha256.h \
+ slot.cpp \
+ slot.h \
+ stdafx.cpp \
+ stdafx.h \
+ storageobject.cpp \
+ storageobject.h \
+ symmalgo.cpp \
+ symmalgo.h \
+ tdes.cpp \
+ tdes.h \
+ template.cpp \
+ template.h \
+ thread.cpp \
+ thread.h \
+ timer.cpp \
+ timer.h \
+ transaction.cpp \
+ transaction.h \
+ util.cpp \
+ util.h \
+ x509cert.cpp \
+ x509cert.h \
+ x509pubkeycertobject.cpp \
+ x509pubkeycertobject.h \
+ log.h \
+ log.cpp
+
+AM_CPPFLAGS = -DINCLUDE_EVENTING=1 -DCRYPTOKI_EXPORTS=1 \
+ -DUNIX $(PTHREAD_CFLAGS) \
+ -Wall \
+ -Wextra \
+ -pedantic
+
+INCLUDES = \
+ -I$(top_srcdir)/cppMarshaller \
+ -I$(top_srcdir)/PKCS11Module2 \
+ -I$(top_srcdir)/PKCS11Module2/rsa \
+ $(PCSC_CFLAGS)
+
+LIBS = $(PCSC_LIBS) $(PTHREAD_LIBS) -lz
+
+# see http://wiki.cacert.org/wiki/Pkcs11TaskForce
+install-exec-hook:
+ $(MKDIR_P) $(DESTDIR)/$(prefix)/lib/pkcs11
+ cd $(DESTDIR)/$(prefix)/lib/pkcs11 ; rm -f libgtop11dotnet. at DYN_LIB_EXT@ ; $(LN_S) ../libgtop11dotnet. at DYN_LIB_EXT@
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/Marshaller.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,1782 @@
+/*
+ * 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>
+#pragma warning(push)
+#pragma warning(disable:4201)
+#else
+#define DBG_UNREFERENCED_LOCAL_VARIABLE(a)
+#endif
+
+#ifdef INCLUDE_VLD
+#include <vld.h>
+#endif
+
+#ifdef __APPLE__
+#include <PCSC/winscard.h>
+#else
+#include <winscard.h>
+#endif
+
+#ifndef WIN32
+#include <strings.h>
+#endif
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdexcept>
+#include "MarshallerCfg.h"
+#include "Array.h"
+#ifndef _XCL_
+#include "PCSC.h"
+#else // _XCL_
+#include "xcl_broker.h"
+#endif // _XCL_
+#include "Marshaller.h"
+#include "Except.h"
+
+#include "log.h"
+
+MARSHALLER_NS_BEGIN
+
+#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
+
+#ifdef SMARTCARDMARSHALLER_EXPORTS
+
+BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+{
+ UNREFERENCED_PARAMETER(hModule);
+ UNREFERENCED_PARAMETER(lpReserved);
+
+ 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))
+ {
+#else
+ if ((readerName == NULL) || (strncasecmp("selfdiscover", readerName->c_str(),readerName->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;
+ }
+
+ //Log::end( "SmartCardMarshaller::SmartCardMarshaller" );
+}
+
+std::string* SmartCardMarshaller::GetReaderName(void)
+{
+ return this->pcsc->GetReaderName();
+}
+
+SCARDHANDLE SmartCardMarshaller::GetCardHandle(void)
+{
+ return this->pcsc->GetCardHandle();
+}
+
+void SmartCardMarshaller::DoTransact(bool flag)
+{
+ this->pcsc->DoTransact(flag);
+}
+
+SmartCardMarshaller::~SmartCardMarshaller(void)
+{
+ if (this->uri != NULL) {
+ delete this->uri;
+ this->uri = NULL;
+ }
+
+ if (this->pcsc != NULL) {
+ delete this->pcsc;
+ this->pcsc = 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;
+
+ switch (type) {
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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)"");
+ }
+
+ 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 {
+
+ u4 len = ComReadU4At(*dataArray, offset);
+ offset += sizeof(u4);
+
+ u1Array* refArray = NULL;
+
+ 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;
+ }
+
+ if (*val != NULL) {
+ // perform cleanup
+ delete *val;
+ }
+
+ *val = refArray;
+ }
+ }
+ break;
+
+ case MARSHALLER_TYPE_REF_S2ARRAY:
+ case MARSHALLER_TYPE_REF_U2ARRAY:
+ {
+ u2Array** val = va_arg(/*marker*/*markerPtr, u2Array**);
+ if (val == NULL) {
+ throw NullReferenceException((lpCharPtr)"");
+ }
+
+ 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 {
+
+ u4 len = ComReadU4At(*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(*dataArray, offset));
+ offset += sizeof(u2);
+ }
+ }
+ } catch (...) {
+ if (refArray != NULL) {
+ delete refArray;
+ }
+ throw;
+ }
+
+ if (*val != NULL) {
+ // perform cleanup
+ delete *val;
+ }
+
+ *val = refArray;
+ }
+ }
+ break;
+
+ case MARSHALLER_TYPE_REF_S4ARRAY:
+ case MARSHALLER_TYPE_REF_U4ARRAY:
+ {
+ u4Array** val = va_arg(/*marker*/*markerPtr, u4Array**);
+ if (val == NULL) {
+ throw NullReferenceException((lpCharPtr)"");
+ }
+
+ 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 {
+
+ u4 len = ComReadU4At(*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(*dataArray, offset));
+ offset += sizeof(u4);
+ }
+ }
+ } catch (...) {
+ if (refArray != NULL) {
+ delete refArray;
+ }
+ throw;
+ }
+
+ if (*val != NULL) {
+ // perform cleanup
+ delete *val;
+ }
+
+ *val = refArray;
+ }
+ }
+ break;
+
+ case MARSHALLER_TYPE_REF_S8ARRAY:
+ case MARSHALLER_TYPE_REF_U8ARRAY:
+ {
+ u8Array** val = va_arg(/*marker*/*markerPtr, u8Array**);
+ if (val == NULL) {
+ throw NullReferenceException((lpCharPtr)"");
+ }
+
+ 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 {
+
+ u4 len = ComReadU4At(*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(*dataArray, offset));
+ offset += sizeof(u4);
+ }
+ }
+ } catch (...) {
+ if (refArray != NULL) {
+ delete refArray;
+ }
+ throw;
+ }
+
+ if (*val != NULL) {
+ // perform cleanup
+ delete *val;
+ }
+
+ *val = refArray;
+ }
+ }
+ break;
+
+ default:
+ {
+ if (isIn == TRUE) {
+ throw Exception("Un-recognized input argument type");
+ } else {
+ throw Exception("Un-recognized byref argument type");
+ }
+ }
+ break;
+ }
+
+ //*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;
+
+ u4 subCommandMaxAllowed = APDU_TO_CARD_MAX_SIZE -1 - 2 - 8;
+
+ u4 length = dataToSendLength > subCommandMaxAllowed ? subCommandMaxAllowed : dataToSendLength;
+
+ u1Array subApdu(0);
+
+ if(first == TRUE){
+ u4 usefulDataLength = length -1 - 2 -1 -4 -2 -2 -2 - uriArray.GetLength();
+
+ subApdu += (u1)0xD8;
+ subApdu += (u2)0xFFFF;
+ subApdu += encodedSize;
+ subApdu += usefulDataLength;
+
+ if ((u8)(invokeApduStartOffset + length) > (u8)invokeAPDU.GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+
+ for(u4 j = invokeApduStartOffset; j < (invokeApduStartOffset + length); j++) {
+ subApdu += invokeAPDU.GetBuffer()[j];
+ }
+
+ first = FALSE;
+ offset += usefulDataLength;
+
+ }else{
+
+ subApdu += (u1)0xD8;
+ subApdu += (u2)0xFFFF;
+ subApdu += encodedOffset;
+ subApdu += length;
+
+ if ((u8)(invokeApduStartOffset + length) > (u8)invokeAPDU.GetLength()) {
+ throw ArgumentOutOfRangeException((lpCharPtr)"");
+ }
+
+ for(u4 j = invokeApduStartOffset; j < (invokeApduStartOffset + length); j++) {
+ subApdu += invokeAPDU.GetBuffer()[j];
+ }
+
+ offset += length;
+ }
+
+ size = 0;
+ invokeApduStartOffset = invokeApduStartOffset + length;
+ dataToSendLength = dataToSendLength - length;
+
+ u1Array apduToSend(5);
+
+ apduToSend.GetBuffer()[0] = 0x80;
+ apduToSend.GetBuffer()[1] = 0xC2;
+ apduToSend.GetBuffer()[2] = 0x00;
+ apduToSend.GetBuffer()[3] = 0x00;
+ apduToSend.GetBuffer()[4] = (u1)subApdu.GetLength();
+ apduToSend += subApdu;
+
+ this->pcsc->ExchangeData(apduToSend, answer_o);
+ }
+ }else{
+
+ // 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->ExchangeData(apdu, answer_o);
+ }
+ } catch (...) {
+ this->pcsc->EndTransaction();
+ throw;
+ }
+
+ this->pcsc->EndTransaction();
+
+ u1Array answer(0);
+
+ if ((ProcessOutputStream != NULL) && (answer_o.GetLength() > 0) && (answer_o.ReadU1At(0) == 0x01)){
+ u1Array answerI(0);
+ u1Array answerM(0);
+
+ for(u4 i = 1; i < answer_o.GetLength(); i++){
+ answerI += answer_o.GetBuffer()[i];
+ }
+
+ ProcessOutputStream(answerI, answerM);
+
+ answer += answer_o.GetBuffer()[0];
+
+ for(u4 i=0;i<answerM.GetLength();i++){
+ answer += answerM.GetBuffer()[i];
+ }
+
+ } else {
+ for(u4 i=0;i<answer_o.GetLength();i++)
+ answer += answer_o.GetBuffer()[i];
+ }
+
+ // analyze return type
+ u4 offset = 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);
+ ProcessOutputArguments(type, &answer, &offset, &marker);
+ }
+ }
+
+ va_end(marker);
+}
+
+void SmartCardMarshaller::SetInputStream(pCommunicationStream inStream){
+ this->ProcessInputStream = inStream;
+}
+
+void SmartCardMarshaller::SetOutputStream(pCommunicationStream outStream){
+ this->ProcessOutputStream = outStream;
+}
+
+MARSHALLER_NS_END
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/Marshaller.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/Marshaller.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,77 @@
+/*
+ * 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_h
+#define _include_marshaller_h
+
+#ifdef _XCL_
+#include "xcl_broker.h"
+#endif // _XCL_
+
+MARSHALLER_NS_BEGIN
+
+typedef void (*pCommunicationStream)(u1Array& st,u1Array& stM);
+
+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;
+
+public:
+ // Existing PCSC connection
+ SmartCardMarshaller(SCARDHANDLE pcscCardHandle, u2 portNumber,M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode);
+
+ // PCSC compatible readers
+ SmartCardMarshaller(M_SAL_IN std::string* readerName, u2 portNumber,M_SAL_IN std::string* uri, u4 nameSpaceHivecode, u2 typeHivecode, u4 index);
+
+ // destructor
+ ~SmartCardMarshaller(void);
+
+ // Remoting marshalling method
+ void Invoke(s4 nParam, ...);
+
+ void UpdatePCSCCardHandle(SCARDHANDLE hCard);
+
+ void SetInputStream(pCommunicationStream inStream);
+ void SetOutputStream(pCommunicationStream outStream);
+
+ std::string* GetReaderName();
+ SCARDHANDLE GetCardHandle();
+ void DoTransact(bool flag);
+
+};
+
+MARSHALLER_NS_END
+
+#endif
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/MarshallerCfg.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/MarshallerCfg.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,167 @@
+/*
+ * 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_marshallercfg_h
+#define _include_marshallercfg_h
+
+#ifdef SMARTCARDMARSHALLER_EXPORTS
+ #define SMARTCARDMARSHALLER_DLLAPI __declspec(dllexport)
+#else
+ #define SMARTCARDMARSHALLER_DLLAPI
+#endif
+
+#ifdef M_SAL_ANNOTATIONS
+#include <specstrings.h>
+#define M_SAL_IN __in
+#define M_SAL_OUT __out
+#define M_SAL_INOUT __inout
+#else
+#define M_SAL_IN
+#define M_SAL_OUT
+#define M_SAL_INOUT
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef WIN32
+#include <inttypes.h>
+#endif
+
+// data types
+typedef unsigned char u1;
+typedef unsigned short u2;
+typedef unsigned int u4;
+typedef char s1;
+typedef short s2;
+typedef int s4;
+
+#ifdef WIN32
+typedef unsigned __int64 u8;
+typedef __int64 s8;
+typedef LPSTR lpCharPtr;
+typedef LPTSTR lpTCharPtr;
+typedef LPBYTE lpByte;
+typedef const lpByte lpCByte;
+#else
+typedef uint64_t u8;
+typedef int64_t s8;
+typedef char* lpTCharPtr;
+typedef char* lpCharPtr;
+typedef unsigned char* lpByte;
+typedef const lpByte lpCByte;
+#endif
+
+// Marshaller argument type constants
+#define MARSHALLER_TYPE_IN_VOID 0
+#define MARSHALLER_TYPE_IN_BOOL 1
+#define MARSHALLER_TYPE_IN_S1 2
+#define MARSHALLER_TYPE_IN_U1 3
+#define MARSHALLER_TYPE_IN_CHAR 4
+#define MARSHALLER_TYPE_IN_S2 5
+#define MARSHALLER_TYPE_IN_U2 6
+#define MARSHALLER_TYPE_IN_S4 7
+#define MARSHALLER_TYPE_IN_U4 8
+#define MARSHALLER_TYPE_IN_S8 9
+#define MARSHALLER_TYPE_IN_U8 10
+#define MARSHALLER_TYPE_IN_STRING 11
+
+#define MARSHALLER_TYPE_IN_BOOLARRAY 21
+#define MARSHALLER_TYPE_IN_S1ARRAY 22
+#define MARSHALLER_TYPE_IN_U1ARRAY 23
+#define MARSHALLER_TYPE_IN_CHARARRAY 24
+#define MARSHALLER_TYPE_IN_S2ARRAY 25
+#define MARSHALLER_TYPE_IN_U2ARRAY 26
+#define MARSHALLER_TYPE_IN_S4ARRAY 27
+#define MARSHALLER_TYPE_IN_U4ARRAY 28
+#define MARSHALLER_TYPE_IN_S8ARRAY 29
+#define MARSHALLER_TYPE_IN_U8ARRAY 30
+#define MARSHALLER_TYPE_IN_STRINGARRAY 31
+
+#define MARSHALLER_TYPE_IN_MEMORYSTREAM 40
+
+#define MARSHALLER_TYPE_REF_BOOL 50
+#define MARSHALLER_TYPE_REF_S1 51
+#define MARSHALLER_TYPE_REF_U1 52
+#define MARSHALLER_TYPE_REF_CHAR 53
+#define MARSHALLER_TYPE_REF_S2 54
+#define MARSHALLER_TYPE_REF_U2 55
+#define MARSHALLER_TYPE_REF_S4 56
+#define MARSHALLER_TYPE_REF_U4 57
+#define MARSHALLER_TYPE_REF_S8 58
+#define MARSHALLER_TYPE_REF_U8 59
+#define MARSHALLER_TYPE_REF_STRING 60
+
+#define MARSHALLER_TYPE_REF_BOOLARRAY 61
+#define MARSHALLER_TYPE_REF_S1ARRAY 62
+#define MARSHALLER_TYPE_REF_U1ARRAY 63
+#define MARSHALLER_TYPE_REF_CHARARRAY 64
+#define MARSHALLER_TYPE_REF_S2ARRAY 65
+#define MARSHALLER_TYPE_REF_U2ARRAY 66
+#define MARSHALLER_TYPE_REF_S4ARRAY 67
+#define MARSHALLER_TYPE_REF_U4ARRAY 68
+#define MARSHALLER_TYPE_REF_S8ARRAY 69
+#define MARSHALLER_TYPE_REF_U8ARRAY 70
+#define MARSHALLER_TYPE_REF_STRINGARRAY 71
+
+// Marshaller return type arguments
+#define MARSHALLER_TYPE_RET_VOID MARSHALLER_TYPE_IN_VOID
+#define MARSHALLER_TYPE_RET_BOOL MARSHALLER_TYPE_IN_BOOL
+#define MARSHALLER_TYPE_RET_S1 MARSHALLER_TYPE_IN_S1
+#define MARSHALLER_TYPE_RET_U1 MARSHALLER_TYPE_IN_U1
+#define MARSHALLER_TYPE_RET_CHAR MARSHALLER_TYPE_IN_CHAR
+#define MARSHALLER_TYPE_RET_S2 MARSHALLER_TYPE_IN_S2
+#define MARSHALLER_TYPE_RET_U2 MARSHALLER_TYPE_IN_U2
+#define MARSHALLER_TYPE_RET_S4 MARSHALLER_TYPE_IN_S4
+#define MARSHALLER_TYPE_RET_U4 MARSHALLER_TYPE_IN_U4
+#define MARSHALLER_TYPE_RET_S8 MARSHALLER_TYPE_IN_S8
+#define MARSHALLER_TYPE_RET_U8 MARSHALLER_TYPE_IN_U8
+#define MARSHALLER_TYPE_RET_STRING MARSHALLER_TYPE_IN_STRING
+
+#define MARSHALLER_TYPE_RET_BOOLARRAY MARSHALLER_TYPE_IN_BOOLARRAY
+#define MARSHALLER_TYPE_RET_S1ARRAY MARSHALLER_TYPE_IN_S1ARRAY
+#define MARSHALLER_TYPE_RET_U1ARRAY MARSHALLER_TYPE_IN_U1ARRAY
+#define MARSHALLER_TYPE_RET_CHARARRAY MARSHALLER_TYPE_IN_CHARARRAY
+#define MARSHALLER_TYPE_RET_S2ARRAY MARSHALLER_TYPE_IN_S2ARRAY
+#define MARSHALLER_TYPE_RET_U2ARRAY MARSHALLER_TYPE_IN_U2ARRAY
+#define MARSHALLER_TYPE_RET_S4ARRAY MARSHALLER_TYPE_IN_S4ARRAY
+#define MARSHALLER_TYPE_RET_U4ARRAY MARSHALLER_TYPE_IN_U4ARRAY
+#define MARSHALLER_TYPE_RET_S8ARRAY MARSHALLER_TYPE_IN_S8ARRAY
+#define MARSHALLER_TYPE_RET_U8ARRAY MARSHALLER_TYPE_IN_U8ARRAY
+#define MARSHALLER_TYPE_RET_STRINGARRAY MARSHALLER_TYPE_IN_STRINGARRAY
+
+#define MARSHALLER_TYPE_RET_MEMORYSTREAM MARSHALLER_TYPE_IN_MEMORYSTREAM
+
+// namespace for the module
+// in case compiler does not support namespace, the defines can be undefined
+#define MARSHALLER_NS_BEGIN namespace Marshaller {
+#define MARSHALLER_NS_END }
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/PCSC.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,559 @@
+/*
+ * 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>
+#pragma warning(push)
+#pragma warning(disable : 4201)
+#else
+#define DBG_UNREFERENCED_LOCAL_VARIABLE(a)
+#endif
+
+#ifdef __APPLE__
+#include <PCSC/wintypes.h>
+#include <PCSC/winscard.h>
+#else
+#include <winscard.h>
+#endif
+
+#ifndef WIN32
+#include <strings.h>
+#endif
+#include <string.h>
+#include <stdexcept>
+#include "MarshallerCfg.h"
+#include "Array.h"
+#include "PCSC.h"
+#include "Except.h"
+
+
+#ifdef __sun
+typedef LPSTR LPTSTR;
+#endif
+
+// JCD
+#include "log.h"
+
+
+
+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};
+
+#define APDU_TO_CARD_MAX_SIZE 0xFF
+#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_NAMESPACE_SYSTEM 0x00D25D1C
+#define HIVECODE_TYPE_SYSTEM_INT32 0x61C0
+
+
+// *******************
+// PCSC class
+// *******************
+PCSC::PCSC(M_SAL_IN std::string* readerName)
+{
+ DWORD activeProtocol;
+ LONG lReturn;
+
+ this->hContext = 0;
+ this->hCard = 0;
+
+ lReturn = SCardEstablishContext(0, NULL, NULL, &this->hContext);
+ if(lReturn != SCARD_S_SUCCESS) {
+ throw RemotingException((lpCharPtr)"PCSC: SCardEstablishContext error",lReturn);
+ }
+
+ 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);
+ }
+
+ this->readerName = new std::string(readerName->c_str());
+}
+
+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;
+
+ if (inputReaderName == NULL) {
+ inputReaderName = &selfDiscover;
+ }
+
+ identifiedReaderName = NULL;
+ this->hContext = 0;
+ this->hCard = 0;
+
+ 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);
+ }
+
+ // self-discovery mechanism
+#ifdef WIN32
+ if (_stricmp("selfdiscover", inputReaderName->c_str()) == 0) {
+#else
+ if (strncasecmp("selfdiscover", inputReaderName->c_str(),inputReaderName->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.
+#ifdef WIN32
+ DWORD readerListCharLength = SCARD_AUTOALLOCATE;
+ lReturn = SCardListReaders(this->hContext, NULL, (LPTSTR)&pReaderList, &readerListCharLength);
+ Log::log( "PCSC::PCSC - SCardListReaders <%#02x>", lReturn );
+
+#else
+ DWORD readerListCharLength = 0;
+
+ lReturn = SCardListReaders(this->hContext,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);
+#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;
+ }
+
+ identifiedReaderName = new std::string((lpCharPtr)pReader);
+ DWORD activeProtocol;
+
+ 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 );
+
+ if (lReturn == SCARD_S_SUCCESS)
+ {
+ // try to identify if we're dealing with a .NetCard
+ u1 answerData[258];
+ DWORD answerLen = 258;
+
+ 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 );
+
+ 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);
+
+ // 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..." );
+ this->ExchangeData(apdu, answer);
+ Log::log( "PCSC::PCSC - ExchangeData ok" );
+
+ Log::log( "PCSC::PCSC - CheckForException..." );
+ u4 protocolOffset = CheckForException(answer, HIVECODE_NAMESPACE_SYSTEM, HIVECODE_TYPE_SYSTEM_INT32);
+ Log::log( "PCSC::PCSC - CheckForException ok" );
+
+ u4 discoveredPortNumber = ComReadU4At(answer, protocolOffset);
+ if ((*portNumber == 0) || (discoveredPortNumber == *portNumber))
+ {
+ *portNumber = (u2)discoveredPortNumber;
+
+ 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");
+
+ Log::error( "PCSC::PCSC", errorMessage );
+
+ throw RemotingException(errorMessage);
+ }
+ }
+
+ foundReader = TRUE;
+ finalCardHandle = this->hCard;
+
+ // Advance to the next value.
+ count++;
+
+ if (count == 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
+ }
+ }
+
+ SCardDisconnect(this->hCard, SCARD_LEAVE_CARD);
+ this->hCard = 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" );
+ }
+ }
+ else
+ {
+ Log::error( "PCSC::PCSC", "SCARD_STATE_PRESENT not present" );
+ }
+ }
+ 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;
+ }
+
+#ifdef WIN32
+ lReturn = SCardFreeMemory(this->hContext, pReaderList);
+ if(lReturn != SCARD_S_SUCCESS) {
+ throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
+ }
+#else
+ if(pReaderList != NULL)
+ free(pReaderList);
+#endif
+ throw;
+ }
+
+ // have we found anything ?
+ if (foundReader == FALSE) {
+ if (identifiedReaderName != NULL) {
+ delete identifiedReaderName;
+ }
+
+#ifdef WIN32
+ lReturn = SCardFreeMemory(this->hContext, pReaderList);
+ if(lReturn != SCARD_S_SUCCESS) {
+ throw RemotingException((lpCharPtr)"PCSC: SCardFreeMemory error",lReturn);
+ }
+#else
+ if(pReaderList != NULL)
+ free(pReaderList);
+#endif
+
+ throw RemotingException((lpCharPtr)"Could not find any Cryptoflex .NET smart card",SCARD_E_NO_SMARTCARD);
+ }
+
+ this->hCard = finalCardHandle;
+ }
+
+ this->readerName = new std::string(identifiedReaderName->c_str());
+
+ delete identifiedReaderName;
+
+ } else {
+ this->readerName = new std::string(inputReaderName->c_str());
+ }
+
+ 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::BeginTransaction(void)
+{
+ if(fDoTransact) // TODO: TEST RETURN CODE!!
+ SCardBeginTransaction(this->hCard);
+}
+
+void PCSC::EndTransaction(void)
+{
+ if(fDoTransact) // TODO: TEST RETURN CODE!!
+ SCardEndTransaction(this->hCard, SCARD_LEAVE_CARD);
+}
+
+SCARDHANDLE PCSC::GetCardHandle(void)
+{
+ return this->hCard;
+}
+
+void PCSC::SetCardHandle(SCARDHANDLE hCard)
+{
+ this->hCard = hCard;
+}
+
+void PCSC::DoTransact(bool flag)
+{
+ this->fDoTransact = flag;
+}
+
+void PCSC::ExchangeData(u1Array &dataIn, u1Array &dataout)
+{
+ u1 answerData[258];
+
+ // check validity of handle
+ if (this->hCard == 0) {
+ throw RemotingException((lpCharPtr)"PCSC: Invalid card handle", SCARD_E_INVALID_HANDLE);
+ }
+
+#ifdef __DEBUG_APDU__
+ //FILE *pFile = fopen("C:\\AxaltoProtocolAnalyzer.txt","a");
+ FILE *pFile = fopen("C:\\Gemalto.NET.PKCS11.log","a");
+#endif
+
+ try {
+
+ BeginTransaction();
+
+ DWORD answerLen = sizeof(answerData);
+
+#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
+
+ 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);
+ }
+
+ if (answerLen < 2) {
+ 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;
+#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
+ }
+
+ u1 sw1 = answerData[answerLen - 2];
+ u1 sw2 = answerData[answerLen - 1];
+
+#ifdef __DEBUG_APDU__
+ fprintf( pFile, "Cmd Status => %02x%02x\n", sw1, sw2 );
+ fprintf( pFile, "Cmd Time => %ld ms\n", GetTickCount( ) - ulStart );
+#endif
+
+ 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;
+
+#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
+
+ 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);
+ }
+
+ if (answerLen < 2) {
+ 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;
+#ifdef __DEBUG_APDU__
+ fprintf(pFile, "GetResponse DataOut\n");
+ for(int i=0; i< (s4)temp.GetLength(); i++) {
+ fprintf(pFile, "%02x ",temp.GetBuffer()[i]);
+ }
+ fprintf(pFile, "\n");
+
+#endif
+ }
+ sw1 = answerData[answerLen - 2];
+ 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 );
+#endif
+ }
+ } catch (...) {
+#ifdef __DEBUG_APDU__
+ fflush(pFile);
+ fclose(pFile);
+#endif
+ EndTransaction();
+ throw;
+ }
+
+#ifdef __DEBUG_APDU__
+ fflush(pFile);
+ fclose(pFile);
+#endif
+
+ 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;
+ }
+}
+
+MARSHALLER_NS_END
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/cppMarshaller/PCSC.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/PCSC.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _include_marshaller_pcsc_h
+#define _include_marshaller_pcsc_h
+
+MARSHALLER_NS_BEGIN
+
+class PCSC
+{
+
+private:
+ SCARDCONTEXT hContext;
+ SCARDHANDLE hCard;
+ std::string* readerName;
+ bool fDoTransact;
+
+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);
+
+};
+
+MARSHALLER_NS_END
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_des.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,410 @@
+/*
+ * 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 "MarshallerCfg.h"
+#include "algo_des.h"
+
+typedef struct _DES_Context
+{
+ u4 encrypt_subkeys[32];
+ u4 decrypt_subkeys[32];
+} _DES_Context;
+
+typedef struct _3DES_Context
+{
+ u4 encrypt_subkeys[96];
+ u4 decrypt_subkeys[96];
+} _3DES_Context;
+
+/*
+ * The s-box values are permuted according to the 'primitive function P'
+ * and are rotated one bit to the left.
+ */
+static const u4 sbox1[64] =
+{
+ 0x01010400, 0x00000000, 0x00010000, 0x01010404, 0x01010004, 0x00010404, 0x00000004, 0x00010000,
+ 0x00000400, 0x01010400, 0x01010404, 0x00000400, 0x01000404, 0x01010004, 0x01000000, 0x00000004,
+ 0x00000404, 0x01000400, 0x01000400, 0x00010400, 0x00010400, 0x01010000, 0x01010000, 0x01000404,
+ 0x00010004, 0x01000004, 0x01000004, 0x00010004, 0x00000000, 0x00000404, 0x00010404, 0x01000000,
+ 0x00010000, 0x01010404, 0x00000004, 0x01010000, 0x01010400, 0x01000000, 0x01000000, 0x00000400,
+ 0x01010004, 0x00010000, 0x00010400, 0x01000004, 0x00000400, 0x00000004, 0x01000404, 0x00010404,
+ 0x01010404, 0x00010004, 0x01010000, 0x01000404, 0x01000004, 0x00000404, 0x00010404, 0x01010400,
+ 0x00000404, 0x01000400, 0x01000400, 0x00000000, 0x00010004, 0x00010400, 0x00000000, 0x01010004
+};
+
+static const u4 sbox2[64] =
+{
+ 0x80108020, 0x80008000, 0x00008000, 0x00108020, 0x00100000, 0x00000020, 0x80100020, 0x80008020,
+ 0x80000020, 0x80108020, 0x80108000, 0x80000000, 0x80008000, 0x00100000, 0x00000020, 0x80100020,
+ 0x00108000, 0x00100020, 0x80008020, 0x00000000, 0x80000000, 0x00008000, 0x00108020, 0x80100000,
+ 0x00100020, 0x80000020, 0x00000000, 0x00108000, 0x00008020, 0x80108000, 0x80100000, 0x00008020,
+ 0x00000000, 0x00108020, 0x80100020, 0x00100000, 0x80008020, 0x80100000, 0x80108000, 0x00008000,
+ 0x80100000, 0x80008000, 0x00000020, 0x80108020, 0x00108020, 0x00000020, 0x00008000, 0x80000000,
+ 0x00008020, 0x80108000, 0x00100000, 0x80000020, 0x00100020, 0x80008020, 0x80000020, 0x00100020,
+ 0x00108000, 0x00000000, 0x80008000, 0x00008020, 0x80000000, 0x80100020, 0x80108020, 0x00108000
+};
+
+static const u4 sbox3[64] =
+{
+ 0x00000208, 0x08020200, 0x00000000, 0x08020008, 0x08000200, 0x00000000, 0x00020208, 0x08000200,
+ 0x00020008, 0x08000008, 0x08000008, 0x00020000, 0x08020208, 0x00020008, 0x08020000, 0x00000208,
+ 0x08000000, 0x00000008, 0x08020200, 0x00000200, 0x00020200, 0x08020000, 0x08020008, 0x00020208,
+ 0x08000208, 0x00020200, 0x00020000, 0x08000208, 0x00000008, 0x08020208, 0x00000200, 0x08000000,
+ 0x08020200, 0x08000000, 0x00020008, 0x00000208, 0x00020000, 0x08020200, 0x08000200, 0x00000000,
+ 0x00000200, 0x00020008, 0x08020208, 0x08000200, 0x08000008, 0x00000200, 0x00000000, 0x08020008,
+ 0x08000208, 0x00020000, 0x08000000, 0x08020208, 0x00000008, 0x00020208, 0x00020200, 0x08000008,
+ 0x08020000, 0x08000208, 0x00000208, 0x08020000, 0x00020208, 0x00000008, 0x08020008, 0x00020200
+};
+
+static const u4 sbox4[64] =
+{
+ 0x00802001, 0x00002081, 0x00002081, 0x00000080, 0x00802080, 0x00800081, 0x00800001, 0x00002001,
+ 0x00000000, 0x00802000, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00800080, 0x00800001,
+ 0x00000001, 0x00002000, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002001, 0x00002080,
+ 0x00800081, 0x00000001, 0x00002080, 0x00800080, 0x00002000, 0x00802080, 0x00802081, 0x00000081,
+ 0x00800080, 0x00800001, 0x00802000, 0x00802081, 0x00000081, 0x00000000, 0x00000000, 0x00802000,
+ 0x00002080, 0x00800080, 0x00800081, 0x00000001, 0x00802001, 0x00002081, 0x00002081, 0x00000080,
+ 0x00802081, 0x00000081, 0x00000001, 0x00002000, 0x00800001, 0x00002001, 0x00802080, 0x00800081,
+ 0x00002001, 0x00002080, 0x00800000, 0x00802001, 0x00000080, 0x00800000, 0x00002000, 0x00802080
+};
+
+static const u4 sbox5[64] =
+{
+ 0x00000100, 0x02080100, 0x02080000, 0x42000100, 0x00080000, 0x00000100, 0x40000000, 0x02080000,
+ 0x40080100, 0x00080000, 0x02000100, 0x40080100, 0x42000100, 0x42080000, 0x00080100, 0x40000000,
+ 0x02000000, 0x40080000, 0x40080000, 0x00000000, 0x40000100, 0x42080100, 0x42080100, 0x02000100,
+ 0x42080000, 0x40000100, 0x00000000, 0x42000000, 0x02080100, 0x02000000, 0x42000000, 0x00080100,
+ 0x00080000, 0x42000100, 0x00000100, 0x02000000, 0x40000000, 0x02080000, 0x42000100, 0x40080100,
+ 0x02000100, 0x40000000, 0x42080000, 0x02080100, 0x40080100, 0x00000100, 0x02000000, 0x42080000,
+ 0x42080100, 0x00080100, 0x42000000, 0x42080100, 0x02080000, 0x00000000, 0x40080000, 0x42000000,
+ 0x00080100, 0x02000100, 0x40000100, 0x00080000, 0x00000000, 0x40080000, 0x02080100, 0x40000100
+};
+
+static const u4 sbox6[64] =
+{
+ 0x20000010, 0x20400000, 0x00004000, 0x20404010, 0x20400000, 0x00000010, 0x20404010, 0x00400000,
+ 0x20004000, 0x00404010, 0x00400000, 0x20000010, 0x00400010, 0x20004000, 0x20000000, 0x00004010,
+ 0x00000000, 0x00400010, 0x20004010, 0x00004000, 0x00404000, 0x20004010, 0x00000010, 0x20400010,
+ 0x20400010, 0x00000000, 0x00404010, 0x20404000, 0x00004010, 0x00404000, 0x20404000, 0x20000000,
+ 0x20004000, 0x00000010, 0x20400010, 0x00404000, 0x20404010, 0x00400000, 0x00004010, 0x20000010,
+ 0x00400000, 0x20004000, 0x20000000, 0x00004010, 0x20000010, 0x20404010, 0x00404000, 0x20400000,
+ 0x00404010, 0x20404000, 0x00000000, 0x20400010, 0x00000010, 0x00004000, 0x20400000, 0x00404010,
+ 0x00004000, 0x00400010, 0x20004010, 0x00000000, 0x20404000, 0x20000000, 0x00400010, 0x20004010
+};
+
+static const u4 sbox7[64] =
+{
+ 0x00200000, 0x04200002, 0x04000802, 0x00000000, 0x00000800, 0x04000802, 0x00200802, 0x04200800,
+ 0x04200802, 0x00200000, 0x00000000, 0x04000002, 0x00000002, 0x04000000, 0x04200002, 0x00000802,
+ 0x04000800, 0x00200802, 0x00200002, 0x04000800, 0x04000002, 0x04200000, 0x04200800, 0x00200002,
+ 0x04200000, 0x00000800, 0x00000802, 0x04200802, 0x00200800, 0x00000002, 0x04000000, 0x00200800,
+ 0x04000000, 0x00200800, 0x00200000, 0x04000802, 0x04000802, 0x04200002, 0x04200002, 0x00000002,
+ 0x00200002, 0x04000000, 0x04000800, 0x00200000, 0x04200800, 0x00000802, 0x00200802, 0x04200800,
+ 0x00000802, 0x04000002, 0x04200802, 0x04200000, 0x00200800, 0x00000000, 0x00000002, 0x04200802,
+ 0x00000000, 0x00200802, 0x04200000, 0x00000800, 0x04000002, 0x04000800, 0x00000800, 0x00200002
+};
+
+static const u4 sbox8[64] =
+{
+ 0x10001040, 0x00001000, 0x00040000, 0x10041040, 0x10000000, 0x10001040, 0x00000040, 0x10000000,
+ 0x00040040, 0x10040000, 0x10041040, 0x00041000, 0x10041000, 0x00041040, 0x00001000, 0x00000040,
+ 0x10040000, 0x10000040, 0x10001000, 0x00001040, 0x00041000, 0x00040040, 0x10040040, 0x10041000,
+ 0x00001040, 0x00000000, 0x00000000, 0x10040040, 0x10000040, 0x10001000, 0x00041040, 0x00040000,
+ 0x00041040, 0x00040000, 0x10041000, 0x00001000, 0x00000040, 0x10040040, 0x00001000, 0x00041040,
+ 0x10001000, 0x00000040, 0x10000040, 0x10040000, 0x10040040, 0x10000000, 0x00040000, 0x10001040,
+ 0x00000000, 0x10041040, 0x00040040, 0x10000040, 0x10040000, 0x10001000, 0x10001040, 0x00000000,
+ 0x10041040, 0x00041000, 0x00041000, 0x00001040, 0x00001040, 0x00040040, 0x10000000, 0x10041000
+};
+
+static const u4 leftkey_swap[16] =
+{
+ 0x00000000, 0x00000001, 0x00000100, 0x00000101,
+ 0x00010000, 0x00010001, 0x00010100, 0x00010101,
+ 0x01000000, 0x01000001, 0x01000100, 0x01000101,
+ 0x01010000, 0x01010001, 0x01010100, 0x01010101
+};
+
+static const u4 rightkey_swap[16] =
+{
+ 0x00000000, 0x01000000, 0x00010000, 0x01010000,
+ 0x00000100, 0x01000100, 0x00010100, 0x01010100,
+ 0x00000001, 0x01000001, 0x00010001, 0x01010001,
+ 0x00000101, 0x01000101, 0x00010101, 0x01010101,
+};
+
+static const u1 encrypt_rotate_tab[16] =
+{
+ 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
+};
+
+#define DO_PERMUTATION(a, temp, b, offset, mask) \
+ temp = ((a>>offset) ^ b) & mask; \
+ b ^= temp; \
+ a ^= temp<<offset;
+
+#define INITIAL_PERMUTATION(left, temp, right) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ right = (right << 1) | (right >> 31); \
+ temp = (left ^ right) & 0xaaaaaaaa; \
+ right ^= temp; \
+ left ^= temp; \
+ left = (left << 1) | (left >> 31);
+
+#define FINAL_PERMUTATION(left, temp, right) \
+ left = (left << 31) | (left >> 1); \
+ temp = (left ^ right) & 0xaaaaaaaa; \
+ left ^= temp; \
+ right ^= temp; \
+ right = (right << 31) | (right >> 1); \
+ DO_PERMUTATION(right, temp, left, 8, 0x00ff00ff) \
+ DO_PERMUTATION(right, temp, left, 2, 0x33333333) \
+ DO_PERMUTATION(left, temp, right, 16, 0x0000ffff) \
+ DO_PERMUTATION(left, temp, right, 4, 0x0f0f0f0f)
+
+#define DES_ROUND(from, to, work, subkey) \
+ work = from ^ *subkey++; \
+ to ^= sbox8[ work & 0x3f ]; \
+ to ^= sbox6[ (work>>8) & 0x3f ]; \
+ to ^= sbox4[ (work>>16) & 0x3f ]; \
+ to ^= sbox2[ (work>>24) & 0x3f ]; \
+ work = ((from << 28) | (from >> 4)) ^ *subkey++; \
+ to ^= sbox7[ work & 0x3f ]; \
+ to ^= sbox5[ (work>>8) & 0x3f ]; \
+ to ^= sbox3[ (work>>16) & 0x3f ]; \
+ to ^= sbox1[ (work>>24) & 0x3f ];
+
+#define READ_64BIT_DATA(data, left, right) \
+ left = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; \
+ right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+
+#define WRITE_64BIT_DATA(data, left, right) \
+ data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff; \
+ data[2] = (left >> 8) &0xff; data[3] = left &0xff; \
+ data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff; \
+ data[6] = (right >> 8) &0xff; data[7] = right &0xff;
+
+
+static void algo_DES_KeySchedule(const u1 * rawkey, u4 * subkey)
+{
+ u4 left, right, work;
+ u1 round;
+
+ READ_64BIT_DATA (rawkey, left, right)
+
+ DO_PERMUTATION (right, work, left, 4, 0x0f0f0f0f)
+ DO_PERMUTATION (right, work, left, 0, 0x10101010)
+
+ left = (leftkey_swap[(left >> 0) & 0xf] << 3) | (leftkey_swap[(left >> 8) & 0xf] << 2)
+ | (leftkey_swap[(left >> 16) & 0xf] << 1) | (leftkey_swap[(left >> 24) & 0xf])
+ | (leftkey_swap[(left >> 5) & 0xf] << 7) | (leftkey_swap[(left >> 13) & 0xf] << 6)
+ | (leftkey_swap[(left >> 21) & 0xf] << 5) | (leftkey_swap[(left >> 29) & 0xf] << 4);
+
+ left &= 0x0fffffff;
+
+ right = (rightkey_swap[(right >> 1) & 0xf] << 3) | (rightkey_swap[(right >> 9) & 0xf] << 2)
+ | (rightkey_swap[(right >> 17) & 0xf] << 1) | (rightkey_swap[(right >> 25) & 0xf])
+ | (rightkey_swap[(right >> 4) & 0xf] << 7) | (rightkey_swap[(right >> 12) & 0xf] << 6)
+ | (rightkey_swap[(right >> 20) & 0xf] << 5) | (rightkey_swap[(right >> 28) & 0xf] << 4);
+
+ right &= 0x0fffffff;
+
+ for (round = 0; round < 16; ++round) {
+
+ left = ((left << encrypt_rotate_tab[round]) | (left >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+ right = ((right << encrypt_rotate_tab[round]) | (right >> (28 - encrypt_rotate_tab[round]))) & 0x0fffffff;
+
+ *subkey++ = ((left << 4) & 0x24000000)
+ | ((left << 28) & 0x10000000)
+ | ((left << 14) & 0x08000000)
+ | ((left << 18) & 0x02080000)
+ | ((left << 6) & 0x01000000)
+ | ((left << 9) & 0x00200000)
+ | ((left >> 1) & 0x00100000)
+ | ((left << 10) & 0x00040000)
+ | ((left << 2) & 0x00020000)
+ | ((left >> 10) & 0x00010000)
+ | ((right >> 13) & 0x00002000)
+ | ((right >> 4) & 0x00001000)
+ | ((right << 6) & 0x00000800)
+ | ((right >> 1) & 0x00000400)
+ | ((right >> 14) & 0x00000200)
+ | (right & 0x00000100)
+ | ((right >> 5) & 0x00000020)
+ | ((right >> 10) & 0x00000010)
+ | ((right >> 3) & 0x00000008)
+ | ((right >> 18) & 0x00000004)
+ | ((right >> 26) & 0x00000002)
+ | ((right >> 24) & 0x00000001);
+
+ *subkey++ = ((left << 15) & 0x20000000)
+ | ((left << 17) & 0x10000000)
+ | ((left << 10) & 0x08000000)
+ | ((left << 22) & 0x04000000)
+ | ((left >> 2) & 0x02000000)
+ | ((left << 1) & 0x01000000)
+ | ((left << 16) & 0x00200000)
+ | ((left << 11) & 0x00100000)
+ | ((left << 3) & 0x00080000)
+ | ((left >> 6) & 0x00040000)
+ | ((left << 15) & 0x00020000)
+ | ((left >> 4) & 0x00010000)
+ | ((right >> 2) & 0x00002000)
+ | ((right << 8) & 0x00001000)
+ | ((right >> 14) & 0x00000808)
+ | ((right >> 9) & 0x00000400)
+ | ((right) & 0x00000200)
+ | ((right << 7) & 0x00000100)
+ | ((right >> 7) & 0x00000020)
+ | ((right >> 3) & 0x00000011)
+ | ((right << 2) & 0x00000004)
+ | ((right >> 21) & 0x00000002);
+ }
+}
+
+static void algo_DES_Setkey(_DES_Context *ctx, const u1 * key)
+{
+ u1 i;
+
+ algo_DES_KeySchedule(key, ctx->encrypt_subkeys);
+
+ for(i = 0; i < 32; i += 2) {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+ }
+}
+
+static void algo_DES_Set2keys(_3DES_Context *ctx, const u1 * key1, const u1 * key2)
+{
+ u1 i;
+
+ algo_DES_KeySchedule(key1, ctx->encrypt_subkeys);
+ algo_DES_KeySchedule(key2, &(ctx->decrypt_subkeys[32]));
+
+ for(i = 0; i < 32; i += 2) {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[31-i];
+
+ ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+ ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
+
+ ctx->encrypt_subkeys[i+64] = ctx->encrypt_subkeys[i];
+ ctx->encrypt_subkeys[i+65] = ctx->encrypt_subkeys[i+1];
+
+ ctx->decrypt_subkeys[i+64] = ctx->decrypt_subkeys[i];
+ ctx->decrypt_subkeys[i+65] = ctx->decrypt_subkeys[i+1];
+ }
+}
+
+static void algo_DES_Set3keys(_3DES_Context *ctx, const u1 * key1, const u1 * key2, const u1 * key3)
+{
+ u1 i;
+
+ algo_DES_KeySchedule(key1, ctx->encrypt_subkeys);
+ algo_DES_KeySchedule(key2, &(ctx->decrypt_subkeys[32]));
+ algo_DES_KeySchedule(key3, &(ctx->encrypt_subkeys[64]));
+
+ for(i = 0; i < 32; i += 2) {
+ ctx->decrypt_subkeys[i] = ctx->encrypt_subkeys[94-i];
+ ctx->decrypt_subkeys[i+1] = ctx->encrypt_subkeys[95-i];
+ ctx->encrypt_subkeys[i+32] = ctx->decrypt_subkeys[62-i];
+ ctx->encrypt_subkeys[i+33] = ctx->decrypt_subkeys[63-i];
+ ctx->decrypt_subkeys[i+64] = ctx->encrypt_subkeys[30-i];
+ ctx->decrypt_subkeys[i+65] = ctx->encrypt_subkeys[31-i];
+ }
+}
+
+void algo_DES_DESProcess(u1* key, u1* from, u1* to, u1 mode)
+{
+ _DES_Context ctx;
+ u4 left, right, work;
+ u4 *keys;
+
+ algo_DES_Setkey(&ctx, key);
+
+ keys = (mode == TRUE) ? ctx.encrypt_subkeys : ctx.decrypt_subkeys;
+
+ READ_64BIT_DATA(from, left, right)
+ INITIAL_PERMUTATION(left, work, right)
+
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+
+ FINAL_PERMUTATION(right, work, left)
+ WRITE_64BIT_DATA(to, right, left)
+}
+
+void algo_DES_3DESProcess(u1 keyLength, u1* key, u1 * from, u1 * to, u1 mode)
+{
+ _3DES_Context ctx;
+ u4 left, right, work;
+ u4 *keys;
+
+ if (keyLength == 0x10) {
+ algo_DES_Set2keys(&ctx, &key[0], &key[8]);
+ } else {
+ algo_DES_Set3keys(&ctx, &key[0], &key[8], &key[16]);
+ }
+
+ keys = (mode == TRUE) ? ctx.encrypt_subkeys : ctx.decrypt_subkeys;
+
+ READ_64BIT_DATA(from, left, right)
+ INITIAL_PERMUTATION(left, work, right)
+
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+ DES_ROUND(left, right, work, keys) DES_ROUND(right, left, work, keys)
+
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+ DES_ROUND(right, left, work, keys) DES_ROUND(left, right, work, keys)
+
+ FINAL_PERMUTATION(right, work, left)
+ WRITE_64BIT_DATA(to, right, left)
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_des.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_des.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,28 @@
+/*
+ * 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_algo_des_h
+#define _include_algo_des_h
+
+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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_md5.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,225 @@
+/*
+ * 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 "MarshallerCfg.h"
+#include "algo_utils.h"
+#include "algo_md5.h"
+
+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,
+ 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, 0
+};
+
+#define md5_S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define md5_P(a,b,c,d,k,s,t) {a += F(b,c,d) + data[k] + t; a = md5_S(a,s) + b;}
+
+void algo_md5_starts(algo_md5_context* ctx)
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->digest[0] = 0x67452301;
+ ctx->digest[1] = 0xEFCDAB89;
+ ctx->digest[2] = 0x98BADCFE;
+ ctx->digest[3] = 0x10325476;
+}
+
+
+static void algo_md5_compress(algo_md5_context *ctx, u4* data)
+{
+ u4 A, B, C, D;
+
+ // big endian processing
+ if (IS_BIG_ENDIAN)
+ {
+ u1 i;
+ for (i = 0; i < (MD5_BLOCK_LENGTH / sizeof(u4)); i++) {
+ data[i] = swapbytes_u4(data[i]);
+ }
+ }
+
+ A = ctx->digest[0];
+ B = ctx->digest[1];
+ C = ctx->digest[2];
+ D = ctx->digest[3];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+
+ md5_P(A, B, C, D, 0, 7, 0xD76AA478);
+ md5_P(D, A, B, C, 1, 12, 0xE8C7B756);
+ md5_P(C, D, A, B, 2, 17, 0x242070DB);
+ md5_P(B, C, D, A, 3, 22, 0xC1BDCEEE);
+ md5_P(A, B, C, D, 4, 7, 0xF57C0FAF);
+ md5_P(D, A, B, C, 5, 12, 0x4787C62A);
+ md5_P(C, D, A, B, 6, 17, 0xA8304613);
+ md5_P(B, C, D, A, 7, 22, 0xFD469501);
+ md5_P(A, B, C, D, 8, 7, 0x698098D8);
+ md5_P(D, A, B, C, 9, 12, 0x8B44F7AF);
+ md5_P(C, D, A, B, 10, 17, 0xFFFF5BB1);
+ md5_P(B, C, D, A, 11, 22, 0x895CD7BE);
+ md5_P(A, B, C, D, 12, 7, 0x6B901122);
+ md5_P(D, A, B, C, 13, 12, 0xFD987193);
+ md5_P(C, D, A, B, 14, 17, 0xA679438E);
+ md5_P(B, C, D, A, 15, 22, 0x49B40821);
+
+#undef F
+
+#define F(x,y,z) (y ^ (z & (x ^ y)))
+
+ md5_P(A, B, C, D, 1, 5, 0xF61E2562);
+ md5_P(D, A, B, C, 6, 9, 0xC040B340);
+ md5_P(C, D, A, B, 11, 14, 0x265E5A51);
+ md5_P(B, C, D, A, 0, 20, 0xE9B6C7AA);
+ md5_P(A, B, C, D, 5, 5, 0xD62F105D);
+ md5_P(D, A, B, C, 10, 9, 0x02441453);
+ md5_P(C, D, A, B, 15, 14, 0xD8A1E681);
+ md5_P(B, C, D, A, 4, 20, 0xE7D3FBC8);
+ md5_P(A, B, C, D, 9, 5, 0x21E1CDE6);
+ md5_P(D, A, B, C, 14, 9, 0xC33707D6);
+ md5_P(C, D, A, B, 3, 14, 0xF4D50D87);
+ md5_P(B, C, D, A, 8, 20, 0x455A14ED);
+ md5_P(A, B, C, D, 13, 5, 0xA9E3E905);
+ md5_P(D, A, B, C, 2, 9, 0xFCEFA3F8);
+ md5_P(C, D, A, B, 7, 14, 0x676F02D9);
+ md5_P(B, C, D, A, 12, 20, 0x8D2A4C8A);
+
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+
+ md5_P(A, B, C, D, 5, 4, 0xFFFA3942);
+ md5_P(D, A, B, C, 8, 11, 0x8771F681);
+ md5_P(C, D, A, B, 11, 16, 0x6D9D6122);
+ md5_P(B, C, D, A, 14, 23, 0xFDE5380C);
+ md5_P(A, B, C, D, 1, 4, 0xA4BEEA44);
+ md5_P(D, A, B, C, 4, 11, 0x4BDECFA9);
+ md5_P(C, D, A, B, 7, 16, 0xF6BB4B60);
+ md5_P(B, C, D, A, 10, 23, 0xBEBFBC70);
+ md5_P(A, B, C, D, 13, 4, 0x289B7EC6);
+ md5_P(D, A, B, C, 0, 11, 0xEAA127FA);
+ md5_P(C, D, A, B, 3, 16, 0xD4EF3085);
+ md5_P(B, C, D, A, 6, 23, 0x04881D05);
+ md5_P(A, B, C, D, 9, 4, 0xD9D4D039);
+ md5_P(D, A, B, C, 12, 11, 0xE6DB99E5);
+ md5_P(C, D, A, B, 15, 16, 0x1FA27CF8);
+ md5_P(B, C, D, A, 2, 23, 0xC4AC5665);
+
+#undef F
+
+#define F(x,y,z) (y ^ (x | ~z))
+
+ md5_P(A, B, C, D, 0, 6, 0xF4292244);
+ md5_P(D, A, B, C, 7, 10, 0x432AFF97);
+ md5_P(C, D, A, B, 14, 15, 0xAB9423A7);
+ md5_P(B, C, D, A, 5, 21, 0xFC93A039);
+ md5_P(A, B, C, D, 12, 6, 0x655B59C3);
+ md5_P(D, A, B, C, 3, 10, 0x8F0CCC92);
+ md5_P(C, D, A, B, 10, 15, 0xFFEFF47D);
+ md5_P(B, C, D, A, 1, 21, 0x85845DD1);
+ md5_P(A, B, C, D, 8, 6, 0x6FA87E4F);
+ md5_P(D, A, B, C, 15, 10, 0xFE2CE6E0);
+ md5_P(C, D, A, B, 6, 15, 0xA3014314);
+ md5_P(B, C, D, A, 13, 21, 0x4E0811A1);
+ md5_P(A, B, C, D, 4, 6, 0xF7537E82);
+ md5_P(D, A, B, C, 11, 10, 0xBD3AF235);
+ md5_P(C, D, A, B, 2, 15, 0x2AD7D2BB);
+ md5_P(B, C, D, A, 9, 21, 0xEB86D391);
+
+#undef F
+
+ ctx->digest[0] += A;
+ ctx->digest[1] += B;
+ ctx->digest[2] += C;
+ ctx->digest[3] += D;
+}
+
+void algo_md5_update(algo_md5_context* ctx, u1* input, u4 length)
+{
+ u4 left, fill;
+
+ if (!length) return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = MD5_BLOCK_LENGTH - left;
+
+ ctx->total[0] += length;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if(ctx->total[0] < length) {
+ ctx->total[1]++;
+ }
+
+ if (left && (length >= fill)) {
+ memcpy(ctx->input + left,input,fill);
+ algo_md5_compress(ctx, (u4*)ctx->input);
+ length -= fill;
+ input += fill;
+ left = 0;
+ }
+
+ while(length >= MD5_BLOCK_LENGTH) {
+ algo_md5_compress(ctx, (u4*)input);
+ length -= MD5_BLOCK_LENGTH;
+ input += MD5_BLOCK_LENGTH;
+ }
+
+ if (length) {
+ memcpy(ctx->input + left,input,length);
+ }
+}
+
+void algo_md5_finish(algo_md5_context *ctx)
+{
+ u4 last, padn;
+ u4 msglen[2];
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ msglen[0] = (ctx->total[0] << 3);
+ msglen[1] = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
+ }
+ // big endian processing
+ else
+ {
+ msglen[0] = swapbytes_u4((ctx->total[0] >> 29) | (ctx->total[1] << 3));
+ msglen[1] = swapbytes_u4((ctx->total[0] << 3));
+ }
+
+ last = ctx->total[0] & 0x3F;
+ padn = (last < (MD5_BLOCK_LENGTH - sizeof(msglen))) ? ((MD5_BLOCK_LENGTH - sizeof(msglen)) - last) : (((2 * MD5_BLOCK_LENGTH) - sizeof(msglen)) - last);
+
+ algo_md5_update(ctx, (u1*)md5_padding, padn);
+ algo_md5_update(ctx, (u1*)msglen, sizeof(msglen));
+
+ // big endian processing
+ if (IS_BIG_ENDIAN)
+ {
+ u1 i;
+ for (i = 0; i < (MD5_HASH_LENGTH / sizeof(u4)); i++) {
+ ctx->digest[i] = swapbytes_u4(ctx->digest[i]);
+ }
+ }
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_md5.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_md5.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,38 @@
+/*
+ * 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_algo_md5_h
+#define _include_algo_md5_h
+
+typedef struct algo_md5_context{
+ u4 total[2];
+ u4* digest;
+ u1* input;
+} algo_md5_context;
+
+#define MD5_HASH_LENGTH 16
+#define MD5_BLOCK_LENGTH 64
+
+extern void algo_md5_starts(algo_md5_context* ctx);
+extern void algo_md5_update(algo_md5_context* ctx, u1* input, u4 length);
+extern void algo_md5_finish(algo_md5_context* ctx);
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_sha1.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,254 @@
+/*
+ * 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 "MarshallerCfg.h"
+#include "algo_utils.h"
+#include "algo_sha1.h"
+
+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,
+ 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, 0
+};
+
+#define sha1_S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define sha1_R(t) (temp = data[(t - 3) & 0x0F] ^ data[(t - 8) & 0x0F] ^ data[(t - 14) & 0x0F] ^ data[t & 0x0F], (data[t & 0x0F] = sha1_S(temp,1)))
+
+#define sha1_P(a,b,c,d,e,x) {e += sha1_S(a,5) + F(b,c,d) + K + x; b = sha1_S(b,30);}
+
+void algo_sha1_starts(algo_sha1_context *ctx)
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->digest[0] = 0x67452301;
+ ctx->digest[1] = 0xEFCDAB89;
+ ctx->digest[2] = 0x98BADCFE;
+ ctx->digest[3] = 0x10325476;
+ ctx->digest[4] = 0xC3D2E1F0;
+}
+
+static void algo_sha1_compress(algo_sha1_context *ctx, u4* data)
+{
+ u4 temp, A, B, C, D, E;
+ u1 i;
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ for (i = 0; i < (SHA1_BLOCK_LENGTH / sizeof(u4)); i++) {
+ data[i] = swapbytes_u4(data[i]);
+ }
+ }
+
+ A = ctx->digest[0];
+ B = ctx->digest[1];
+ C = ctx->digest[2];
+ D = ctx->digest[3];
+ E = ctx->digest[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+ sha1_P(A, B, C, D, E, data[0]);
+ sha1_P(E, A, B, C, D, data[1]);
+ sha1_P(D, E, A, B, C, data[2]);
+ sha1_P(C, D, E, A, B, data[3]);
+ sha1_P(B, C, D, E, A, data[4]);
+ sha1_P(A, B, C, D, E, data[5]);
+ sha1_P(E, A, B, C, D, data[6]);
+ sha1_P(D, E, A, B, C, data[7]);
+ sha1_P(C, D, E, A, B, data[8]);
+ sha1_P(B, C, D, E, A, data[9]);
+ sha1_P(A, B, C, D, E, data[10]);
+ sha1_P(E, A, B, C, D, data[11]);
+ sha1_P(D, E, A, B, C, data[12]);
+ sha1_P(C, D, E, A, B, data[13]);
+ sha1_P(B, C, D, E, A, data[14]);
+ sha1_P(A, B, C, D, E, data[15]);
+ sha1_P(E, A, B, C, D, sha1_R(16));
+ sha1_P(D, E, A, B, C, sha1_R(17));
+ sha1_P(C, D, E, A, B, sha1_R(18));
+ sha1_P(B, C, D, E, A, sha1_R(19));
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+ sha1_P(A, B, C, D, E, sha1_R(20));
+ sha1_P(E, A, B, C, D, sha1_R(21));
+ sha1_P(D, E, A, B, C, sha1_R(22));
+ sha1_P(C, D, E, A, B, sha1_R(23));
+ sha1_P(B, C, D, E, A, sha1_R(24));
+ sha1_P(A, B, C, D, E, sha1_R(25));
+ sha1_P(E, A, B, C, D, sha1_R(26));
+ sha1_P(D, E, A, B, C, sha1_R(27));
+ sha1_P(C, D, E, A, B, sha1_R(28));
+ sha1_P(B, C, D, E, A, sha1_R(29));
+ sha1_P(A, B, C, D, E, sha1_R(30));
+ sha1_P(E, A, B, C, D, sha1_R(31));
+ sha1_P(D, E, A, B, C, sha1_R(32));
+ sha1_P(C, D, E, A, B, sha1_R(33));
+ sha1_P(B, C, D, E, A, sha1_R(34));
+ sha1_P(A, B, C, D, E, sha1_R(35));
+ sha1_P(E, A, B, C, D, sha1_R(36));
+ sha1_P(D, E, A, B, C, sha1_R(37));
+ sha1_P(C, D, E, A, B, sha1_R(38));
+ sha1_P(B, C, D, E, A, sha1_R(39));
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+ sha1_P(A, B, C, D, E, sha1_R(40));
+ sha1_P(E, A, B, C, D, sha1_R(41));
+ sha1_P(D, E, A, B, C, sha1_R(42));
+ sha1_P(C, D, E, A, B, sha1_R(43));
+ sha1_P(B, C, D, E, A, sha1_R(44));
+ sha1_P(A, B, C, D, E, sha1_R(45));
+ sha1_P(E, A, B, C, D, sha1_R(46));
+ sha1_P(D, E, A, B, C, sha1_R(47));
+ sha1_P(C, D, E, A, B, sha1_R(48));
+ sha1_P(B, C, D, E, A, sha1_R(49));
+ sha1_P(A, B, C, D, E, sha1_R(50));
+ sha1_P(E, A, B, C, D, sha1_R(51));
+ sha1_P(D, E, A, B, C, sha1_R(52));
+ sha1_P(C, D, E, A, B, sha1_R(53));
+ sha1_P(B, C, D, E, A, sha1_R(54));
+ sha1_P(A, B, C, D, E, sha1_R(55));
+ sha1_P(E, A, B, C, D, sha1_R(56));
+ sha1_P(D, E, A, B, C, sha1_R(57));
+ sha1_P(C, D, E, A, B, sha1_R(58));
+ sha1_P(B, C, D, E, A, sha1_R(59));
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+ sha1_P(A, B, C, D, E, sha1_R(60));
+ sha1_P(E, A, B, C, D, sha1_R(61));
+ sha1_P(D, E, A, B, C, sha1_R(62));
+ sha1_P(C, D, E, A, B, sha1_R(63));
+ sha1_P(B, C, D, E, A, sha1_R(64));
+ sha1_P(A, B, C, D, E, sha1_R(65));
+ sha1_P(E, A, B, C, D, sha1_R(66));
+ sha1_P(D, E, A, B, C, sha1_R(67));
+ sha1_P(C, D, E, A, B, sha1_R(68));
+ sha1_P(B, C, D, E, A, sha1_R(69));
+ sha1_P(A, B, C, D, E, sha1_R(70));
+ sha1_P(E, A, B, C, D, sha1_R(71));
+ sha1_P(D, E, A, B, C, sha1_R(72));
+ sha1_P(C, D, E, A, B, sha1_R(73));
+ sha1_P(B, C, D, E, A, sha1_R(74));
+ sha1_P(A, B, C, D, E, sha1_R(75));
+ sha1_P(E, A, B, C, D, sha1_R(76));
+ sha1_P(D, E, A, B, C, sha1_R(77));
+ sha1_P(C, D, E, A, B, sha1_R(78));
+ sha1_P(B, C, D, E, A, sha1_R(79));
+
+#undef K
+#undef F
+
+ ctx->digest[0] += A;
+ ctx->digest[1] += B;
+ ctx->digest[2] += C;
+ ctx->digest[3] += D;
+ ctx->digest[4] += E;
+}
+
+void algo_sha1_update(algo_sha1_context* ctx, u1* input, u4 length)
+{
+ u4 left, fill;
+
+ if (!length) return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = SHA1_BLOCK_LENGTH - left;
+
+ ctx->total[0] += length;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if(ctx->total[0] < length) {
+ ctx->total[1]++;
+ }
+
+ if (left && (length >= fill)) {
+ //CopyVolatile(input, ctx->input + left, fill);
+ memcpy(ctx->input + left,input,fill);
+ algo_sha1_compress(ctx, (u4*)ctx->input);
+ length -= fill;
+ input += fill;
+ left = 0;
+ }
+
+ while(length >= SHA1_BLOCK_LENGTH) {
+ algo_sha1_compress(ctx, (u4*)input);
+ length -= SHA1_BLOCK_LENGTH;
+ input += SHA1_BLOCK_LENGTH;
+ }
+
+ if (length) {
+ //CopyVolatile(input, ctx->input + left, length);
+ memcpy(ctx->input + left,input,length);
+ }
+}
+
+void algo_sha1_finish(algo_sha1_context *ctx)
+{
+ u4 last, padn;
+ u4 msglen[2];
+ u1 i;
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ msglen[0] = swapbytes_u4((ctx->total[0] >> 29) | (ctx->total[1] << 3));
+ msglen[1] = swapbytes_u4((ctx->total[0] << 3));
+ }
+ else
+ {
+ msglen[0] = (ctx->total[0] << 3);
+ msglen[1] = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
+ }
+
+ last = ctx->total[0] & 0x3F;
+ padn = (last < (SHA1_BLOCK_LENGTH - sizeof(msglen))) ? ((SHA1_BLOCK_LENGTH - sizeof(msglen)) - last) : (((2 * SHA1_BLOCK_LENGTH) - sizeof(msglen)) - last);
+
+ algo_sha1_update(ctx, (u1*)sha1_padding, padn);
+ algo_sha1_update(ctx, (u1*)msglen, 8);
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ for (i = 0; i < (SHA1_HASH_LENGTH / sizeof(u4)); i++) {
+ ctx->digest[i] = swapbytes_u4(ctx->digest[i]);
+ }
+ }
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_sha1.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha1.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,39 @@
+/*
+ * 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_algo_sha1_h
+#define _include_algo_sha1_h
+
+typedef struct algo_sha1_context
+{
+ u4 total[2];
+ u4* digest;
+ u1* 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);
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_sha256.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,370 @@
+/*
+ * 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 "MarshallerCfg.h"
+#include "algo_utils.h"
+#include "algo_sha256.h"
+
+const u1 sha256_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,
+ 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, 0
+};
+
+#define SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define SHA256_S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3))
+#define SHA256_S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10))
+#define SHA256_S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define SHA256_S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define SHA256_F0(x,y,z) ((x & y) | (z & (x | y)))
+#define SHA256_F1(x,y,z) (z ^ (x & (y ^ z)))
+
+void algo_sha256_starts(algo_sha256_context *ctx )
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->digest[0] = 0x6A09E667;
+ ctx->digest[1] = 0xBB67AE85;
+ ctx->digest[2] = 0x3C6EF372;
+ ctx->digest[3] = 0xA54FF53A;
+ ctx->digest[4] = 0x510E527F;
+ ctx->digest[5] = 0x9B05688C;
+ ctx->digest[6] = 0x1F83D9AB;
+ ctx->digest[7] = 0x5BE0CD19;
+}
+
+#ifdef _SHA256_SIZE_OPTIMIZED_VERSION
+
+ static algo_sha256_context* algo_sha256_tmpCtx;
+
+ static void sha256_P(u4 a, u4 b, u4 c, u4* d, u4 e, u4 f, u4 g, u4* h, u1 i, u4 K)
+ {
+ u4 temp1;
+ u4 temp2;
+
+ if (i > 15) {
+ algo_sha256_tmpCtx->processingBuffer[i] = SHA256_S1(algo_sha256_tmpCtx->processingBuffer[i - 2]) + algo_sha256_tmpCtx->processingBuffer[i - 7] + SHA256_S0(algo_sha256_tmpCtx->processingBuffer[i - 15]) + algo_sha256_tmpCtx->processingBuffer[i - 16];
+ }
+
+ temp1 = *h + SHA256_S3(e) + SHA256_F1(e,f,g) + K + algo_sha256_tmpCtx->processingBuffer[i];
+ temp2 = SHA256_S2(a) + SHA256_F0(a,b,c);
+
+ *d += temp1;
+ *h = temp1 + temp2;
+ }
+
+ static void algo_sha256_compress(algo_sha256_context *ctx, u4* input)
+ {
+
+ u4 A, B, C, D, E, F, G, H;
+ u1 i;
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ for (i = 0; i < (SHA256_BLOCK_LENGTH / sizeof(u4)); i++) {
+ ctx->processingBuffer[i] = swapbytes_u4(input[i]);
+ }
+ }
+ A = ctx->digest[0];
+ B = ctx->digest[1];
+ C = ctx->digest[2];
+ D = ctx->digest[3];
+ E = ctx->digest[4];
+ F = ctx->digest[5];
+ G = ctx->digest[6];
+ H = ctx->digest[7];
+
+ algo_sha256_tmpCtx = ctx;
+
+ sha256_P(A, B, C, &D, E, F, G, &H, 0, 0x428A2F98);
+ sha256_P(H, A, B, &C, D, E, F, &G, 1, 0x71374491);
+ sha256_P(G, H, A, &B, C, D, E, &F, 2, 0xB5C0FBCF);
+ sha256_P(F, G, H, &A, B, C, D, &E, 3, 0xE9B5DBA5);
+ sha256_P(E, F, G, &H, A, B, C, &D, 4, 0x3956C25B);
+ sha256_P(D, E, F, &G, H, A, B, &C, 5, 0x59F111F1);
+ sha256_P(C, D, E, &F, G, H, A, &B, 6, 0x923F82A4);
+ sha256_P(B, C, D, &E, F, G, H, &A, 7, 0xAB1C5ED5);
+ sha256_P(A, B, C, &D, E, F, G, &H, 8, 0xD807AA98);
+ sha256_P(H, A, B, &C, D, E, F, &G, 9, 0x12835B01);
+ sha256_P(G, H, A, &B, C, D, E, &F, 10, 0x243185BE);
+ sha256_P(F, G, H, &A, B, C, D, &E, 11, 0x550C7DC3);
+ sha256_P(E, F, G, &H, A, B, C, &D, 12, 0x72BE5D74);
+ sha256_P(D, E, F, &G, H, A, B, &C, 13, 0x80DEB1FE);
+ sha256_P(C, D, E, &F, G, H, A, &B, 14, 0x9BDC06A7);
+ sha256_P(B, C, D, &E, F, G, H, &A, 15, 0xC19BF174);
+ sha256_P(A, B, C, &D, E, F, G, &H, 16, 0xE49B69C1);
+ sha256_P(H, A, B, &C, D, E, F, &G, 17, 0xEFBE4786);
+ sha256_P(G, H, A, &B, C, D, E, &F, 18, 0x0FC19DC6);
+ sha256_P(F, G, H, &A, B, C, D, &E, 19, 0x240CA1CC);
+ sha256_P(E, F, G, &H, A, B, C, &D, 20, 0x2DE92C6F);
+ sha256_P(D, E, F, &G, H, A, B, &C, 21, 0x4A7484AA);
+ sha256_P(C, D, E, &F, G, H, A, &B, 22, 0x5CB0A9DC);
+ sha256_P(B, C, D, &E, F, G, H, &A, 23, 0x76F988DA);
+ sha256_P(A, B, C, &D, E, F, G, &H, 24, 0x983E5152);
+ sha256_P(H, A, B, &C, D, E, F, &G, 25, 0xA831C66D);
+ sha256_P(G, H, A, &B, C, D, E, &F, 26, 0xB00327C8);
+ sha256_P(F, G, H, &A, B, C, D, &E, 27, 0xBF597FC7);
+ sha256_P(E, F, G, &H, A, B, C, &D, 28, 0xC6E00BF3);
+ sha256_P(D, E, F, &G, H, A, B, &C, 29, 0xD5A79147);
+ sha256_P(C, D, E, &F, G, H, A, &B, 30, 0x06CA6351);
+ sha256_P(B, C, D, &E, F, G, H, &A, 31, 0x14292967);
+ sha256_P(A, B, C, &D, E, F, G, &H, 32, 0x27B70A85);
+ sha256_P(H, A, B, &C, D, E, F, &G, 33, 0x2E1B2138);
+ sha256_P(G, H, A, &B, C, D, E, &F, 34, 0x4D2C6DFC);
+ sha256_P(F, G, H, &A, B, C, D, &E, 35, 0x53380D13);
+ sha256_P(E, F, G, &H, A, B, C, &D, 36, 0x650A7354);
+ sha256_P(D, E, F, &G, H, A, B, &C, 37, 0x766A0ABB);
+ sha256_P(C, D, E, &F, G, H, A, &B, 38, 0x81C2C92E);
+ sha256_P(B, C, D, &E, F, G, H, &A, 39, 0x92722C85);
+ sha256_P(A, B, C, &D, E, F, G, &H, 40, 0xA2BFE8A1);
+ sha256_P(H, A, B, &C, D, E, F, &G, 41, 0xA81A664B);
+ sha256_P(G, H, A, &B, C, D, E, &F, 42, 0xC24B8B70);
+ sha256_P(F, G, H, &A, B, C, D, &E, 43, 0xC76C51A3);
+ sha256_P(E, F, G, &H, A, B, C, &D, 44, 0xD192E819);
+ sha256_P(D, E, F, &G, H, A, B, &C, 45, 0xD6990624);
+ sha256_P(C, D, E, &F, G, H, A, &B, 46, 0xF40E3585);
+ sha256_P(B, C, D, &E, F, G, H, &A, 47, 0x106AA070);
+ sha256_P(A, B, C, &D, E, F, G, &H, 48, 0x19A4C116);
+ sha256_P(H, A, B, &C, D, E, F, &G, 49, 0x1E376C08);
+ sha256_P(G, H, A, &B, C, D, E, &F, 50, 0x2748774C);
+ sha256_P(F, G, H, &A, B, C, D, &E, 51, 0x34B0BCB5);
+ sha256_P(E, F, G, &H, A, B, C, &D, 52, 0x391C0CB3);
+ sha256_P(D, E, F, &G, H, A, B, &C, 53, 0x4ED8AA4A);
+ sha256_P(C, D, E, &F, G, H, A, &B, 54, 0x5B9CCA4F);
+ sha256_P(B, C, D, &E, F, G, H, &A, 55, 0x682E6FF3);
+ sha256_P(A, B, C, &D, E, F, G, &H, 56, 0x748F82EE);
+ sha256_P(H, A, B, &C, D, E, F, &G, 57, 0x78A5636F);
+ sha256_P(G, H, A, &B, C, D, E, &F, 58, 0x84C87814);
+ sha256_P(F, G, H, &A, B, C, D, &E, 59, 0x8CC70208);
+ sha256_P(E, F, G, &H, A, B, C, &D, 60, 0x90BEFFFA);
+ sha256_P(D, E, F, &G, H, A, B, &C, 61, 0xA4506CEB);
+ sha256_P(C, D, E, &F, G, H, A, &B, 62, 0xBEF9A3F7);
+ sha256_P(B, C, D, &E, F, G, H, &A, 63, 0xC67178F2);
+
+ ctx->digest[0] += A;
+ ctx->digest[1] += B;
+ ctx->digest[2] += C;
+ ctx->digest[3] += D;
+ ctx->digest[4] += E;
+ ctx->digest[5] += F;
+ ctx->digest[6] += G;
+ ctx->digest[7] += H;
+ }
+
+#else
+
+ #define SHA256_R(t) \
+ ( \
+ ctx->processingBuffer[t] = SHA256_S1(ctx->processingBuffer[t - 2]) + ctx->processingBuffer[t - 7] + \
+ SHA256_S0(ctx->processingBuffer[t - 15]) + ctx->processingBuffer[t - 16] \
+ )
+
+ #define SHA256_P(a,b,c,d,e,f,g,h,x,K) \
+ { \
+ temp1 = h + SHA256_S3(e) + SHA256_F1(e,f,g) + K + x; \
+ temp2 = SHA256_S2(a) + SHA256_F0(a,b,c); \
+ d += temp1; h = temp1 + temp2; \
+ }
+
+ static void algo_sha256_compress(algo_sha256_context *ctx, u4* input)
+ {
+ u4 temp1, temp2;
+ u4 A, B, C, D, E, F, G, H;
+ u1 i;
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ for (i = 0; i < (SHA256_BLOCK_LENGTH / sizeof(u4)); i++) {
+ ctx->processingBuffer[i] = swapbytes_u4(input[i]);
+ }
+ }
+ else
+ {
+ for (i = 0; i < (SHA256_BLOCK_LENGTH / sizeof(u4)); i++) {
+ ctx->processingBuffer[i] = input[i];
+ }
+ }
+
+ A = ctx->digest[0];
+ B = ctx->digest[1];
+ C = ctx->digest[2];
+ D = ctx->digest[3];
+ E = ctx->digest[4];
+ F = ctx->digest[5];
+ G = ctx->digest[6];
+ H = ctx->digest[7];
+
+ SHA256_P( A, B, C, D, E, F, G, H, ctx->processingBuffer[ 0], 0x428A2F98 );
+ SHA256_P( H, A, B, C, D, E, F, G, ctx->processingBuffer[ 1], 0x71374491 );
+ SHA256_P( G, H, A, B, C, D, E, F, ctx->processingBuffer[ 2], 0xB5C0FBCF );
+ SHA256_P( F, G, H, A, B, C, D, E, ctx->processingBuffer[ 3], 0xE9B5DBA5 );
+ SHA256_P( E, F, G, H, A, B, C, D, ctx->processingBuffer[ 4], 0x3956C25B );
+ SHA256_P( D, E, F, G, H, A, B, C, ctx->processingBuffer[ 5], 0x59F111F1 );
+ SHA256_P( C, D, E, F, G, H, A, B, ctx->processingBuffer[ 6], 0x923F82A4 );
+ SHA256_P( B, C, D, E, F, G, H, A, ctx->processingBuffer[ 7], 0xAB1C5ED5 );
+ SHA256_P( A, B, C, D, E, F, G, H, ctx->processingBuffer[ 8], 0xD807AA98 );
+ SHA256_P( H, A, B, C, D, E, F, G, ctx->processingBuffer[ 9], 0x12835B01 );
+ SHA256_P( G, H, A, B, C, D, E, F, ctx->processingBuffer[10], 0x243185BE );
+ SHA256_P( F, G, H, A, B, C, D, E, ctx->processingBuffer[11], 0x550C7DC3 );
+ SHA256_P( E, F, G, H, A, B, C, D, ctx->processingBuffer[12], 0x72BE5D74 );
+ SHA256_P( D, E, F, G, H, A, B, C, ctx->processingBuffer[13], 0x80DEB1FE );
+ SHA256_P( C, D, E, F, G, H, A, B, ctx->processingBuffer[14], 0x9BDC06A7 );
+ SHA256_P( B, C, D, E, F, G, H, A, ctx->processingBuffer[15], 0xC19BF174 );
+ SHA256_P( A, B, C, D, E, F, G, H, SHA256_R(16), 0xE49B69C1 );
+ SHA256_P( H, A, B, C, D, E, F, G, SHA256_R(17), 0xEFBE4786 );
+ SHA256_P( G, H, A, B, C, D, E, F, SHA256_R(18), 0x0FC19DC6 );
+ SHA256_P( F, G, H, A, B, C, D, E, SHA256_R(19), 0x240CA1CC );
+ SHA256_P( E, F, G, H, A, B, C, D, SHA256_R(20), 0x2DE92C6F );
+ SHA256_P( D, E, F, G, H, A, B, C, SHA256_R(21), 0x4A7484AA );
+ SHA256_P( C, D, E, F, G, H, A, B, SHA256_R(22), 0x5CB0A9DC );
+ SHA256_P( B, C, D, E, F, G, H, A, SHA256_R(23), 0x76F988DA );
+ SHA256_P( A, B, C, D, E, F, G, H, SHA256_R(24), 0x983E5152 );
+ SHA256_P( H, A, B, C, D, E, F, G, SHA256_R(25), 0xA831C66D );
+ SHA256_P( G, H, A, B, C, D, E, F, SHA256_R(26), 0xB00327C8 );
+ SHA256_P( F, G, H, A, B, C, D, E, SHA256_R(27), 0xBF597FC7 );
+ SHA256_P( E, F, G, H, A, B, C, D, SHA256_R(28), 0xC6E00BF3 );
+ SHA256_P( D, E, F, G, H, A, B, C, SHA256_R(29), 0xD5A79147 );
+ SHA256_P( C, D, E, F, G, H, A, B, SHA256_R(30), 0x06CA6351 );
+ SHA256_P( B, C, D, E, F, G, H, A, SHA256_R(31), 0x14292967 );
+ SHA256_P( A, B, C, D, E, F, G, H, SHA256_R(32), 0x27B70A85 );
+ SHA256_P( H, A, B, C, D, E, F, G, SHA256_R(33), 0x2E1B2138 );
+ SHA256_P( G, H, A, B, C, D, E, F, SHA256_R(34), 0x4D2C6DFC );
+ SHA256_P( F, G, H, A, B, C, D, E, SHA256_R(35), 0x53380D13 );
+ SHA256_P( E, F, G, H, A, B, C, D, SHA256_R(36), 0x650A7354 );
+ SHA256_P( D, E, F, G, H, A, B, C, SHA256_R(37), 0x766A0ABB );
+ SHA256_P( C, D, E, F, G, H, A, B, SHA256_R(38), 0x81C2C92E );
+ SHA256_P( B, C, D, E, F, G, H, A, SHA256_R(39), 0x92722C85 );
+ SHA256_P( A, B, C, D, E, F, G, H, SHA256_R(40), 0xA2BFE8A1 );
+ SHA256_P( H, A, B, C, D, E, F, G, SHA256_R(41), 0xA81A664B );
+ SHA256_P( G, H, A, B, C, D, E, F, SHA256_R(42), 0xC24B8B70 );
+ SHA256_P( F, G, H, A, B, C, D, E, SHA256_R(43), 0xC76C51A3 );
+ SHA256_P( E, F, G, H, A, B, C, D, SHA256_R(44), 0xD192E819 );
+ SHA256_P( D, E, F, G, H, A, B, C, SHA256_R(45), 0xD6990624 );
+ SHA256_P( C, D, E, F, G, H, A, B, SHA256_R(46), 0xF40E3585 );
+ SHA256_P( B, C, D, E, F, G, H, A, SHA256_R(47), 0x106AA070 );
+ SHA256_P( A, B, C, D, E, F, G, H, SHA256_R(48), 0x19A4C116 );
+ SHA256_P( H, A, B, C, D, E, F, G, SHA256_R(49), 0x1E376C08 );
+ SHA256_P( G, H, A, B, C, D, E, F, SHA256_R(50), 0x2748774C );
+ SHA256_P( F, G, H, A, B, C, D, E, SHA256_R(51), 0x34B0BCB5 );
+ SHA256_P( E, F, G, H, A, B, C, D, SHA256_R(52), 0x391C0CB3 );
+ SHA256_P( D, E, F, G, H, A, B, C, SHA256_R(53), 0x4ED8AA4A );
+ SHA256_P( C, D, E, F, G, H, A, B, SHA256_R(54), 0x5B9CCA4F );
+ SHA256_P( B, C, D, E, F, G, H, A, SHA256_R(55), 0x682E6FF3 );
+ SHA256_P( A, B, C, D, E, F, G, H, SHA256_R(56), 0x748F82EE );
+ SHA256_P( H, A, B, C, D, E, F, G, SHA256_R(57), 0x78A5636F );
+ SHA256_P( G, H, A, B, C, D, E, F, SHA256_R(58), 0x84C87814 );
+ SHA256_P( F, G, H, A, B, C, D, E, SHA256_R(59), 0x8CC70208 );
+ SHA256_P( E, F, G, H, A, B, C, D, SHA256_R(60), 0x90BEFFFA );
+ SHA256_P( D, E, F, G, H, A, B, C, SHA256_R(61), 0xA4506CEB );
+ SHA256_P( C, D, E, F, G, H, A, B, SHA256_R(62), 0xBEF9A3F7 );
+ SHA256_P( B, C, D, E, F, G, H, A, SHA256_R(63), 0xC67178F2 );
+
+ ctx->digest[0] += A;
+ ctx->digest[1] += B;
+ ctx->digest[2] += C;
+ ctx->digest[3] += D;
+ ctx->digest[4] += E;
+ ctx->digest[5] += F;
+ ctx->digest[6] += G;
+ ctx->digest[7] += H;
+ }
+
+#endif
+
+
+void algo_sha256_update(algo_sha256_context *ctx, u1 *input, u4 length )
+{
+ u4 left, fill;
+
+ if(!length ) return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = SHA256_BLOCK_LENGTH - left;
+
+ ctx->total[0] += length;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if( ctx->total[0] < length )
+ ctx->total[1]++;
+
+ if( left && length >= fill )
+ {
+ memcpy(ctx->input + left,input,fill);
+
+ algo_sha256_compress( ctx,(u4*)ctx->input );
+ length -= fill;
+ input += fill;
+ left = 0;
+ }
+
+ while( length >= SHA256_BLOCK_LENGTH )
+ {
+ algo_sha256_compress( ctx, (u4*)input );
+ length -= SHA256_BLOCK_LENGTH;
+ input += SHA256_BLOCK_LENGTH;
+ }
+
+ if( length ){
+ memcpy(ctx->input + left,input,length);
+ }
+}
+
+void algo_sha256_finish(algo_sha256_context *ctx)
+{
+ u4 last, padn;
+ u4 msglen[2];
+ u1 i;
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ msglen[0] = swapbytes_u4((ctx->total[0] >> 29) | (ctx->total[1] << 3));
+ msglen[1] = swapbytes_u4((ctx->total[0] << 3));
+ }
+ else
+ {
+ msglen[0] = (ctx->total[0] << 3);
+ msglen[1] = (ctx->total[0] >> 29) | (ctx->total[1] << 3);
+ }
+
+ last = ctx->total[0] & 0x3F;
+ padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+ algo_sha256_update( ctx, (u1*)sha256_padding, padn );
+ algo_sha256_update( ctx, (u1*)msglen, 8 );
+
+ // little endian processing
+ if (IS_LITTLE_ENDIAN)
+ {
+ for (i = 0; i < (SHA256_HASH_LENGTH / sizeof(u4)); i++) {
+ ctx->digest[i] = swapbytes_u4(ctx->digest[i]);
+ }
+ }
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_sha256.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_sha256.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,40 @@
+/*
+ * 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_algo_sha256_h
+#define _include_algo_sha256_h
+
+#define SHA256_HASH_LENGTH 32
+#define SHA256_BLOCK_LENGTH 64
+
+typedef struct algo_sha256_context
+{
+ u4 total[2];
+ u4 processingBuffer[SHA256_BLOCK_LENGTH];
+ u4* digest;
+ u1* input;
+} algo_sha256_context;
+
+extern void algo_sha256_starts(algo_sha256_context* ctx);
+extern void algo_sha256_update(algo_sha256_context* ctx, u1* input, u4 length);
+extern void algo_sha256_finish(algo_sha256_context* ctx);
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_utils.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,34 @@
+/*
+ * 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 "MarshallerCfg.h"
+#include "algo_utils.h"
+
+u4 swapbytes_u4(u4 val)
+{
+ u4 res;
+ res = val << 24;
+ res |= (val << 8) & 0x00FF0000;
+ res |= (val >> 8) & 0x0000FF00;
+ res |= val >> 24;
+ return (res);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/algo_utils.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/algo_utils.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,27 @@
+/*
+ * 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_algo_utils_h
+#define _include_algo_utils_h
+
+extern u4 swapbytes_u4(u4 val);
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/application.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/application.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,744 @@
+/*
+ * 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_
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/application.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/application.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/application.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/application.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,66 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/attrcert.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,221 @@
+/*
+ * 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.
+
+//#pragma warning(disable : 4251)
+
+#include "stdafx.h"
+#include "platconfig.h"
+//#include "config.h"
+//#include "dbg.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:
+
+ explicit
+ JoinWith(second_argument_type const &rGlue)
+ : m_Glue(rGlue)
+ {}
+
+
+ result_type
+ operator()(string const &rFirst,
+ string const &rSecond) const
+ {
+ return rFirst + m_Glue + rSecond;
+ }
+
+ private:
+
+ second_argument_type const m_Glue;
+ };
+
+ string
+ Combine(vector<string> const &rvsNames)
+ {
+ static string::value_type const cBlank = ' ';
+ static string const sBlank(1, cBlank);
+
+ if(!rvsNames.empty())
+ return accumulate(rvsNames.begin() + 1, rvsNames.end(),
+ *rvsNames.begin(), JoinWith(sBlank));
+ else
+ return string();
+ }
+
+} // namespace
+
+CAttributedCertificate::CAttributedCertificate(BEROctet::Blob const &cert) : m_x509cert(cert)
+{
+}
+
+CAttributedCertificate::CAttributedCertificate(const unsigned char * cert, size_t length)
+ : m_x509cert(cert, static_cast<unsigned long>(length))
+{
+}
+
+CAttributedCertificate::~CAttributedCertificate()
+{
+}
+
+BEROctet::Blob
+CAttributedCertificate::Modulus() const
+{
+ return m_x509cert.Modulus();
+}
+
+BEROctet::Blob
+CAttributedCertificate::PublicExponent() const
+{
+ return m_x509cert.PublicExponent();
+}
+
+BEROctet::Blob
+CAttributedCertificate::Subject() const
+{
+ return m_x509cert.Subject();
+}
+
+BEROctet::Blob
+CAttributedCertificate::Issuer() const
+{
+ return m_x509cert.Issuer();
+}
+
+BEROctet::Blob
+CAttributedCertificate::SerialNumber() const
+{
+ return m_x509cert.SerialNumber();
+}
+
+string
+CAttributedCertificate::DerivedName() const
+{
+ string sDerivedName(Combine(m_x509cert.UTF8SubjectCommonName()));
+ if(sDerivedName.empty())
+ sDerivedName.assign("Smart Card User");
+ return sDerivedName;
+}
+
+string
+CAttributedCertificate::DerivedLabel() const
+{
+ return Combine(m_x509cert.SubjectCommonName());
+}
+
+BEROctet::Blob
+CAttributedCertificate::DerivedId() const
+{
+ return DerivedId(m_x509cert.Modulus());
+}
+
+BEROctet::Blob
+CAttributedCertificate::DerivedId(BEROctet::Blob const & data)
+{
+ return DerivedId(data.c_str(), data.size());
+}
+
+BEROctet::Blob
+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);
+
+ return BEROctet::Blob(hash, 20);
+}
+
+string
+CAttributedCertificate::DerivedUniqueName() const
+{
+ return DerivedUniqueName(m_x509cert.Modulus());
+}
+
+string
+CAttributedCertificate::DerivedUniqueName(BEROctet::Blob const & data)
+{
+ return DerivedUniqueName(data.c_str(), data.size());
+}
+
+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);
+
+ // Format as a GUID
+
+ char name[40];
+
+ u1 *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 string(name);
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/attrcert.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/attrcert.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,84 @@
+/*
+ * 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_attrcert_h
+#define _include_attrcert_h
+
+#include "x509cert.h"
+
+
+class CAttributedCertificate
+{
+
+public:
+ explicit CAttributedCertificate(BEROctet::Blob const &cert);
+ CAttributedCertificate(const unsigned char * cert, size_t length);
+
+ virtual ~CAttributedCertificate();
+
+ BEROctet::Blob
+ Modulus() const;
+
+ BEROctet::Blob
+ PublicExponent() const;
+
+ BEROctet::Blob
+ Subject() const;
+
+ BEROctet::Blob
+ Issuer() const;
+
+ BEROctet::Blob
+ SerialNumber() const;
+
+ std::string
+ DerivedName() const;
+
+ std::string
+ DerivedLabel() const;
+
+ BEROctet::Blob
+ DerivedId() const;
+
+ static BEROctet::Blob
+ DerivedId(BEROctet::Blob const & data);
+
+ static BEROctet::Blob
+ DerivedId(unsigned char const * data, size_t length);
+
+ std::string
+ DerivedUniqueName() const;
+
+ static std::string
+ DerivedUniqueName(BEROctet::Blob const & data);
+
+ static std::string
+ DerivedUniqueName(unsigned char const * data, size_t length);
+
+private:
+ X509Cert m_x509cert;
+
+};
+
+
+#endif // _include_attrcert_h
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/beroctet.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,741 @@
+/*
+ * 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 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.
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "beroctet.h"
+
+using namespace std;
+
+BEROctet::BEROctet() : m_tcClass(tcUniversal),
+ m_fConstructed(fBerPcPrimitive),
+ m_dwTag(dwBerUnivZero),
+ m_fDefinite(true),
+ m_fModified(true)
+{
+}
+
+BEROctet::BEROctet(BEROctet const &oct)
+{
+ *this = oct;
+}
+
+BEROctet::BEROctet(Blob const &blb)
+{
+ Decode(blb);
+}
+
+BEROctet::BEROctet(TagClass tcClass, bool fConstructed, unsigned int dwTag, bool fDefinite) :
+ m_tcClass(tcClass),
+ m_fConstructed(fConstructed),
+ m_dwTag(dwTag),
+ m_fDefinite(fDefinite),
+ m_fModified(true)
+{
+ if(!m_fDefinite && !m_fConstructed)
+ throw runtime_error("BERPrimitiveIndefiniteLength");
+}
+
+BEROctet::~BEROctet(void)
+{
+ for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); 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++)
+ delete m_SubOctetList[i];
+
+ m_SubOctetList.resize(0);
+ m_blbData.resize(0);
+
+ m_fModified = Oct.m_fModified;
+ m_blbOrigOctet = Oct.m_blbOrigOctet;
+
+ m_fConstructed = Oct.m_fConstructed;
+ m_tcClass = Oct.m_tcClass;
+ m_dwTag = Oct.m_dwTag;
+ m_fDefinite = Oct.m_fDefinite;
+
+
+ if(m_fConstructed)
+ {
+ for(std::vector<BEROctet const*>::size_type i=0; i<Oct.m_SubOctetList.size(); i++)
+ m_SubOctetList.push_back(new BEROctet(*Oct.m_SubOctetList[i]));
+ }
+ else
+ m_blbData = Oct.m_blbData;
+
+ return *this;
+}
+
+// Returns a the data part of the octet
+
+BEROctet::Blob BEROctet::Data() const
+{
+
+ if(m_fConstructed)
+ {
+
+ // Traverse the tree
+
+ Blob data;
+
+ for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
+ data += m_SubOctetList[i]->Octet();
+
+ return data;
+ }
+ else
+ return m_blbData;
+
+}
+
+// Sets the data part of the octet
+
+void BEROctet::Data(Blob const &blb)
+{
+
+ if(m_fConstructed)
+ throw runtime_error("BERInconsistentOperation");
+
+ m_blbData = blb;
+ m_fModified = true;
+
+}
+
+// If the octet is a constructed type, this returns list of sub-octets
+
+vector<BEROctet*> BEROctet::SubOctetList() const
+{
+ if(!m_fConstructed)
+ throw runtime_error("BERInconsistentOperation");
+
+ return m_SubOctetList;
+}
+
+// Insert an octet as a sub-octet of a constructed octet
+
+void BEROctet::Insert(BEROctet const &oct)
+{
+ if(!m_fConstructed)
+ throw runtime_error("BERInconsistentOperation");
+
+ BEROctet *pOct = new BEROctet(oct);
+ m_SubOctetList.push_back(pOct);
+ m_fModified = true;
+
+}
+
+// Returns the whole octet
+
+BEROctet::Blob BEROctet::Octet() const
+{
+ if(Modified())
+ {
+
+ Blob blbOct = IdentOctets(m_tcClass, m_fConstructed, m_dwTag);
+ Blob blbData = Data();
+
+ if(m_fDefinite)
+ blbOct += LengthOctets(static_cast<unsigned int>(blbData.size()));
+ else
+ blbOct += 0x80; // Indefinite length octet
+
+ blbOct += blbData;
+
+ if(!m_fDefinite)
+ {
+
+ // Terminate with end-of-contents octet
+
+ BEROctet blbZero;
+ blbOct += blbZero.Octet();
+ }
+
+ return blbOct;
+ }
+ else
+ return m_blbOrigOctet;
+
+}
+
+// Returns the class of the octet
+
+TagClass BEROctet::Class() const
+{
+ return m_tcClass;
+}
+
+// Returns true if the octet is constructet, false otherwise
+
+bool BEROctet::Constructed() const
+{
+ return m_fConstructed;
+}
+
+// Returns the tag of the octet
+
+unsigned int BEROctet::Tag() const
+{
+ return m_dwTag;
+}
+
+// Decode the contents of an OID
+
+string BEROctet::ObjectID() const
+{
+
+ if(m_tcClass!=tcUniversal || m_dwTag!=dwBerUnivObjectIdent)
+ throw runtime_error("BERInconsistentOperation");
+
+ if(!m_blbData.size())
+ throw runtime_error("BEREmptyOctet");
+
+ 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
+ // and the terminating zero.
+
+ char text[40];
+
+ unsigned int subid;
+ const unsigned char *c = m_blbData.data();
+ const unsigned char *Last = c + m_blbData.size();
+ bool First = true;
+
+ while(c<Last)
+ {
+ subid = (*c)&0x7F;
+ while((*c)&0x80)
+ {
+ c++;
+ if(c>=Last)
+ throw runtime_error("BERUnexpectedEndOfOctet");
+ if(subid>0x01FFFFFF)
+ throw runtime_error("BEROIDSubIdentifierOverflow");
+ subid = (subid<<7) | ((*c)&0x7F);
+ }
+ if(First)
+ {
+ unsigned int X,Y;
+ if(subid<40)
+ X=0;
+ else if(subid<80)
+ X=1;
+ else
+ X=2;
+ Y = subid-X*40;
+ sprintf(text,"%d %d",X,Y);
+ OID = text;
+ First = false;
+ }
+ else
+ {
+ sprintf(text," %d",subid);
+ OID += text;
+ }
+ c++;
+ }
+
+ return OID;
+}
+
+// Encode an OID
+
+void BEROctet::ObjectID(string const &str)
+{
+
+ if(m_tcClass!=tcUniversal)
+ throw runtime_error("BERInconsistentOperation");
+
+ if(m_dwTag==dwBerUnivZero)
+ m_dwTag = dwBerUnivObjectIdent;
+
+ if(m_dwTag!=dwBerUnivObjectIdent)
+ throw runtime_error("BERInconsistentOperation");
+
+ char *oid = 0;
+
+ try
+ {
+#if defined(_WIN32)
+ oid = _strdup(str.c_str());
+#else
+ oid = strdup(str.c_str());
+#endif
+ char *s;
+
+ if(0==(s = strtok(oid," ")))
+ throw runtime_error("BERIllegalObjectIdentifier");
+
+ unsigned int X,Y,dwSubOID;
+
+ if(sscanf(s,"%u",&X)!=1)
+ throw runtime_error("BERIllegalObjectIdentifier");
+
+ if(X>2)
+ throw runtime_error("BERIllegalObjectIdentifier");
+
+ if(0==(s = strtok(0," ")))
+ throw runtime_error("BERIllegalObjectIdentifier");
+
+ if(sscanf(s,"%u",&Y)!=1)
+ throw runtime_error("BERIllegalObjectIdentifier");
+
+ if(X<2 && Y>39)
+ throw runtime_error("BERIllegalObjectIdentifier");
+
+ dwSubOID = X*40;
+ if(Y>0xFFFFFFFF-dwSubOID)
+ throw runtime_error("BERDataOverflow");
+
+ dwSubOID += Y;
+
+ Blob blbData;
+
+ while(true)
+ {
+
+ unsigned char buf[2*sizeof(dwSubOID)];
+ int n=0;
+ while(dwSubOID>0x7F)
+ {
+ buf[n] = static_cast<unsigned char>(dwSubOID & 0x7F);
+ dwSubOID >>=7;
+ n++;
+ }
+ buf[n] = static_cast<unsigned char>(dwSubOID & 0x7F);
+ n++;
+
+ for(int i=0; i<n; i++)
+ {
+ unsigned char b = buf[n-i-1];
+ if((i+1)<n) b |= 0x80;
+ blbData += b;
+ }
+
+ if(0==(s = strtok(0," ")))
+ break;
+ if(sscanf(s,"%u",&dwSubOID)!=1)
+ break;
+ }
+
+ Data(blbData);
+
+ }
+ catch(...)
+ {
+ if(oid)
+ free(oid);
+ throw;
+ }
+
+ if(oid)
+ free(oid);
+
+}
+
+// Decode a Time octet. Output format: "YYYYMMDDHHMMSS"
+
+// 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
+{
+
+ static const Blob::size_type UnivUTCTimeSize = 13;
+ static const Blob::size_type UnivGenTimeSize = 15;
+
+ if(m_tcClass!=tcUniversal)
+ throw runtime_error("BERInconsistentOperation");
+
+ if(m_dwTag==dwBerUnivUTCTime)
+ {
+ // UTCTime
+
+ if(m_blbData.size()!=UnivUTCTimeSize)
+ throw runtime_error("BERInconsistentDataLength");
+
+ string strCentury, strYear((char*)m_blbData.data(),2);
+ int iYear;
+ if(sscanf(strYear.c_str(),"%d",&iYear)!=1)
+ throw 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);
+ }
+ else if(m_dwTag==dwBerUnivGenTime)
+ {
+ // GeneralizedTime
+
+ if(m_blbData.size()!=UnivGenTimeSize)
+ throw runtime_error("BERInconsistentDataLength");
+
+ // Return the string as is, stripping off the 'Z'
+
+ return string((char*)m_blbData.data(),UnivGenTimeSize-1);
+ }
+ else
+ throw runtime_error("BERInconsistentOperation");
+
+}
+
+// Encode a Time. Input format: "YYYYMMDDHHMMSS"
+
+// If the Tag is not set to be either UTC Time or Generalized Time,
+// we apply the convention from RFC 2459 where years in the range
+// 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)
+{
+ static const Blob::size_type ExpectedSize = 14;
+
+ if(m_tcClass!=tcUniversal)
+ throw runtime_error("BERInconsistentOperation");
+
+ if(str.size()!=ExpectedSize)
+ throw 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");
+
+ if(m_dwTag==dwBerUnivZero)
+ {
+ if(iYear<1950)
+ throw runtime_error("IllegalParameter");
+ else if(iYear<2050)
+ m_dwTag = dwBerUnivUTCTime;
+ else
+ m_dwTag = dwBerUnivGenTime;
+ }
+
+ Blob blbData;
+
+ if(m_dwTag==dwBerUnivUTCTime)
+ blbData.assign(((unsigned char*)str.data()+2),str.size()-2);
+
+ else if(m_dwTag==dwBerUnivGenTime)
+ blbData.assign((unsigned char*)str.data(),str.size());
+
+ else
+ throw runtime_error("BERInconsistentOperation");
+
+ blbData += 'Z';
+
+ Data(blbData);
+
+}
+
+// SearchOID returns all the constructed octets that contain a particular OID
+
+void BEROctet::SearchOID(string const &OID, vector<BEROctet const*> &result) const
+{
+
+ 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)
+ {
+ if(OID==m_SubOctetList[i]->ObjectID())
+ result.push_back(this);
+ }
+ else if(m_SubOctetList[i]->Constructed())
+ m_SubOctetList[i]->SearchOID(OID,result);
+ }
+
+ return;
+
+}
+
+// SearchOIDNext returns all the octets following a particular OID
+
+void BEROctet::SearchOIDNext(string const &OID, vector<BEROctet const*> &result) const
+{
+ 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)
+ {
+ if(OID==m_SubOctetList[i]->ObjectID())
+ {
+ if((i+1) < m_SubOctetList.size())
+ result.push_back(m_SubOctetList[i+1]);
+ }
+ }
+ else if(m_SubOctetList[i]->Constructed())
+ m_SubOctetList[i]->SearchOIDNext(OID,result);
+ }
+
+ return;
+
+}
+
+// Construct the Identifier octets
+
+BEROctet::Blob BEROctet::IdentOctets(TagClass tcClass, bool fConstructed, unsigned int dwTag)
+{
+
+ unsigned char bLeadingOct;
+ switch(tcClass)
+ {
+
+ case tcUniversal:
+ bLeadingOct = 0x00;
+ break;
+
+ case tcApplication:
+ bLeadingOct = 0x40;
+ break;
+
+ case tcContext:
+ bLeadingOct = 0x80;
+ break;
+
+ case tcPrivate:
+ bLeadingOct = 0xC0;
+ break;
+
+ default:
+ throw runtime_error("BERIllegalClass");
+ }
+
+ if(fConstructed)
+ bLeadingOct |= 0x20;
+
+ int n = 0;
+ unsigned char buf[sizeof(dwTag)];
+
+ if(dwTag<=30)
+ bLeadingOct |= dwTag;
+
+ else
+ {
+ bLeadingOct |= 0x1F;
+ while(dwTag>0)
+ {
+ buf[n] = static_cast<unsigned char>(dwTag & 0x000000FF);
+ dwTag >>= 8;
+ n++;
+ }
+ }
+
+ Blob IdentOcts(&bLeadingOct,1);
+
+ for(int i=0; i<n; i++)
+ IdentOcts +=buf[n-i-1];
+
+ return IdentOcts;
+
+}
+
+// Construct the Length octets
+
+BEROctet::Blob BEROctet::LengthOctets(unsigned int dwLength)
+{
+
+ int n = 0;
+ unsigned char buf[sizeof(dwLength)];
+ unsigned char bLeadingOct;
+
+ if(dwLength<=0x7F)
+ bLeadingOct = static_cast<unsigned char>(dwLength);
+ else
+ {
+ bLeadingOct = 0x80;
+ while(dwLength>0)
+ {
+ buf[n] = static_cast<unsigned char>(dwLength & 0x000000FF);
+ dwLength >>= 8;
+ n++;
+ }
+ bLeadingOct |= n;
+ }
+
+ Blob LengthOcts(&bLeadingOct,1);
+ for(int i=0; i<n; i++)
+ LengthOcts +=buf[n-i-1];
+
+ return LengthOcts;
+
+}
+
+// Decodes recursively a BER octet.
+
+void BEROctet::Decode(Blob const &blb)
+{
+
+ if(!blb.size())
+ throw runtime_error("BEREmptyOctet");
+
+ size_t BufferSize = blb.size();
+
+ m_fConstructed = (blb[0]&0x20) ? true : false;
+
+ switch(blb[0]&0xC0)
+ {
+
+ case 0x00:
+ m_tcClass = tcUniversal;
+ break;
+
+ case 0x40:
+ m_tcClass = tcApplication;
+ break;
+
+ case 0x80:
+ m_tcClass = tcContext;
+ break;
+
+ case 0xC0:
+ m_tcClass = tcPrivate;
+ break;
+
+ default:
+ throw runtime_error("BERIllegalClass");
+ }
+
+ const unsigned char *c = blb.data();
+ const unsigned char *Last = c + blb.size() - 1;
+ m_dwTag = *c & 0x1F;
+
+ if(m_dwTag>30)
+ {
+ m_dwTag = 0;
+
+ c++;
+ if(c>Last)
+ throw runtime_error("BERUnexpectedEndOfOctet");
+
+ while (*c & 0x80)
+ {
+ m_dwTag = (m_dwTag << 7) | ((*c) & 0x7F);
+ c++;
+ if(c>Last)
+ throw runtime_error("BERUnexpectedEndOfOctet");
+ }
+
+ if(m_dwTag > 0x01FFFFFF)
+ throw runtime_error("BERTagValueOverflow");
+
+ m_dwTag = (m_dwTag << 7) | ((*c) & 0x7F);
+
+ }
+
+ c++;
+ if(c>Last)
+ throw runtime_error("BERUnexpectedEndOfOctet");
+
+ size_t DataSize;
+
+ if((*c)&0x80)
+ {
+ int n = (*c) & 0x7F;
+ if(n)
+ {
+ DataSize = 0;
+ for(int i=0; i<n; i++)
+ {
+ c++; if(c>Last)
+ throw runtime_error("BERUnexpectedEndOfOctet");
+ if(DataSize>0x007FFFFF)
+ throw runtime_error("BERDataOverflow");
+ DataSize = (DataSize<<8) | (*c);
+ }
+ }
+ else
+ throw runtime_error("BERUnexpectedIndefiniteLength");
+ }
+ else DataSize = *c;
+
+ c++;
+
+ const unsigned char *bpData = c;
+
+ size_t OctetSize = DataSize + (bpData-blb.data());
+
+ m_blbOrigOctet = blb.substr(0,OctetSize);
+ m_fModified = false;
+
+ if(OctetSize>static_cast<unsigned int>(BufferSize))
+ throw runtime_error("BERInconsistentDataLength");
+
+ for(std::vector<BEROctet const*>::size_type i=0; i<m_SubOctetList.size(); i++)
+ delete m_SubOctetList[i];
+
+ m_SubOctetList.resize(0);
+ m_blbData = Blob();
+
+ if(m_fConstructed)
+ {
+
+ // Constructed type
+
+ while(DataSize)
+ {
+
+ BEROctet *suboct = new BEROctet(Blob(bpData,DataSize));
+
+ m_SubOctetList.push_back(suboct);
+
+ Blob blbSubOct = suboct->Octet();
+
+ bpData += blbSubOct.size();
+ DataSize -= blbSubOct.size();
+ }
+ }
+ else
+ m_blbData = Blob(bpData,DataSize);
+
+}
+
+bool BEROctet::Modified() const
+{
+ 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;
+
+ return false;
+
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/beroctet.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/beroctet.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,221 @@
+/*
+ * 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_beroctet_h
+#define _include_beroctet_h
+
+#include <string>
+#include <vector>
+#include <stdexcept>
+
+enum TagClass {tcAny = -1, tcUniversal = 0, tcApplication = 1, tcContext = 2, tcPrivate = 3};
+
+// Defined tags
+
+const unsigned int dwBerUnivZero = 0;
+const unsigned int dwBerUnivBool = 1;
+const unsigned int dwBerUnivInteger = 2;
+const unsigned int dwBerUnivBitString = 3;
+const unsigned int dwBerUnivOctetString = 4;
+const unsigned int dwBerUnivNull = 5;
+const unsigned int dwBerUnivObjectIdent = 6;
+const unsigned int dwBerUnivObjectDesc = 7;
+const unsigned int dwBerUnivReal = 9;
+const unsigned int dwBerUnivEnum = 10;
+const unsigned int dwBerUnivUTF8String = 12;
+const unsigned int dwBerUnivSequence = 16;
+const unsigned int dwBerUnivSet = 17;
+const unsigned int dwBerUnivPrintString = 19;
+const unsigned int dwBerUnivIA5String = 22;
+const unsigned int dwBerUnivUTCTime = 23;
+const unsigned int dwBerUnivGenTime = 24;
+const unsigned int dwBerGraphicString = 25;
+const unsigned int dwBerISO646String = 26;
+const unsigned int dwBerGeneralString = 27;
+const unsigned int dwBerUniversalString = 28;
+const unsigned int dwBerCharacterString = 29;
+const unsigned int dwBerBMPString = 30;
+const unsigned int dwBerDate = 31;
+const unsigned int dwBerTimeOfDay = 32;
+const unsigned int dwBerDateTime = 33;
+const unsigned int dwBerDuration = 34;
+
+const char OID_pkcs1[] = "1 2 840 113549 1 1";
+const char OID_pkcs1_rsaEncryption[] = "1 2 840 113549 1 1 1";
+const char OID_pkcs1_md2WithRSAEncryption[] = "1 2 840 113549 1 1 2";
+const char OID_pkcs1_md4WithRSAEncryption[] = "1 2 840 113549 1 1 3";
+const char OID_pkcs1_md5WithRSAEncryption[] = "1 2 840 113549 1 1 4";
+const char OID_pkcs1_sha1WithRSAEncryption[] = "1 2 840 113549 1 1 5";
+const char OID_pkcs1_sha256WithRSAEncryption[] = "1 2 840 113549 1 1 11";
+
+const char OID_pkcs7_data[] = "1 2 840 113549 1 7 1";
+const char OID_pkcs7_signedData[] = "1 2 840 113549 1 7 2";
+const char OID_pkcs7_envelopedData[] = "1 2 840 113549 1 7 3";
+const char OID_pkcs7_signedAndEnvelopedData[] = "1 2 840 113549 1 7 4";
+const char OID_pkcs7_digestedData[] = "1 2 840 113549 1 7 5";
+const char OID_pkcs7_encryptedData[] = "1 2 840 113549 1 7 6";
+
+const char OID_pkcs9_emailAddress[] = "1 2 840 113549 1 9 1";
+const char OID_pkcs9_unstructuredName[] = "1 2 840 113549 1 9 2";
+const char OID_pkcs9_contentType[] = "1 2 840 113549 1 9 3";
+const char OID_pkcs9_messageDigest[] = "1 2 840 113549 1 9 4";
+const char OID_pkcs9_signingTime[] = "1 2 840 113549 1 9 5";
+const char OID_pkcs9_countersignature[] = "1 2 840 113549 1 9 6";
+const char OID_pkcs9_challengePassword[] = "1 2 840 113549 1 9 7";
+const char OID_pkcs9_unstructuredAddress[] = "1 2 840 113549 1 9 8";
+const char OID_pkcs9_extendedCertificateAttr[] = "1 2 840 113549 1 9 9";
+const char OID_pkcs9_sMIMECapabilities[] = "1 2 840 113549 1 9 15";
+const char OID_pkcs9_id_smime[] = "1 2 840 113549 1 9 16";
+
+const char OID_digestAlogrithm_md2[] = "1 2 840 113549 2 2";
+const char OID_digestAlogrithm_md4[] = "1 2 840 113549 2 4";
+const char OID_digestAlogrithm_md5[] = "1 2 840 113549 2 5";
+
+const char OID_RC2_CBC[] = "1 2 840 113549 3 2";
+const char OID_dES_EDE3_CBC[] = "1 2 840 113549 3 7";
+
+const char OID_ms_enrollmentAgent[] = "1 3 6 1 4 1 311 20 2 1";
+const char OID_ms_smartCardLogin[] = "1 3 6 1 4 1 311 20 2 2";
+
+const char OID_id_kp_serverAuth[] = "1 3 6 1 5 5 7 3 1";
+const char OID_id_kp_clientAuth[] = "1 3 6 1 5 5 7 3 2";
+const char OID_id_kp_codeSigning[] = "1 3 6 1 5 5 7 3 3";
+const char OID_id_kp_emailProtection[] = "1 3 6 1 5 5 7 3 4";
+const char OID_id_kp_ipsecEndSystem[] = "1 3 6 1 5 5 7 3 5";
+const char OID_id_kp_ipsecTunnel[] = "1 3 6 1 5 5 7 3 6";
+const char OID_id_kp_ipsecUser[] = "1 3 6 1 5 5 7 3 7";
+const char OID_id_kp_timeStamping[] = "1 3 6 1 5 5 7 3 8";
+
+const char OID_md4WithRSA[] = "1 3 14 3 2 2";
+const char OID_md5WithRSA[] = "1 3 14 3 2 3";
+const char OID_md4WithRSAEncryption[] = "1 3 14 3 2 4";
+const char OID_desECB[] = "1 3 14 3 2 6";
+const char OID_desCBC[] = "1 3 14 3 2 7";
+const char OID_desOFB[] = "1 3 14 3 2 8";
+const char OID_desCFB[] = "1 3 14 3 2 9";
+const char OID_desMAC[] = "1 3 14 3 2 10";
+const char OID_rsaSignature[] = "1 3 14 3 2 11";
+const char OID_mdc2WithRSASignature[] = "1 3 14 3 2 14";
+const char OID_shaWithRSASignature[] = "1 3 14 3 2 15";
+const char OID_desEDE[] = "1 3 14 3 2 17";
+const char OID_sha[] = "1 3 14 3 2 18";
+const char OID_rsaKeyTransport[] = "1 3 14 3 2 22";
+const char OID_md2WithRSASignature[] = "1 3 14 3 2 24";
+const char OID_md5WithRSASignature[] = "1 3 14 3 2 25";
+const char OID_sha1[] = "1 3 14 3 2 26";
+const char OID_sha1WithRSASignature[] = "1 3 14 3 2 29";
+
+const char OID_id_at_organizationName[] = "2 5 4 10";
+const char OID_id_at_organizationalUnitName[] = "2 5 4 11";
+const char OID_id_at_commonName[] = "2 5 4 3";
+const char OID_id_at_countryName[] = "2 5 4 6";
+const char OID_id_at_localityName[] = "2 5 4 7";
+const char OID_id_at_stateOrProvinceName[] = "2 5 4 8";
+const char OID_id_ce_subjectDirectoryAttributes[] = "2 5 29 9";
+const char OID_id_ce_subjectKeyIdentifier[] = "2 5 29 14";
+const char OID_id_ce_keyUsage[] = "2 5 29 15";
+const char OID_id_ce_privateKeyUsagePeriod[] = "2 5 29 16";
+const char OID_id_ce_subjectAltName[] = "2 5 29 17";
+const char OID_id_ce_issuerAltName[] = "2 5 29 18";
+const char OID_id_ce_basicConstraints[] = "2 5 29 19";
+const char OID_id_ce_cRLNumber[] = "2 5 29 20";
+const char OID_id_ce_reasonCode[] = "2 5 29 21";
+const char OID_id_ce_instructionCode[] = "2 5 29 23";
+const char OID_id_ce_invalidityDate[] = "2 5 29 24";
+const char OID_id_ce_deltaCRLIndicator[] = "2 5 29 27";
+const char OID_id_ce_issuingDistributionPoint[] = "2 5 29 28";
+const char OID_id_ce_certificateIssuer[] = "2 5 29 29";
+const char OID_id_ce_nameConstraints[] = "2 5 29 30";
+const char OID_id_ce_cRLDistributionPoints[] = "2 5 29 31";
+const char OID_id_ce_certificatePolicies[] = "2 5 29 32";
+const char OID_id_ce_policyMappings[] = "2 5 29 33";
+const char OID_id_ce_policyConstraints[] = "2 5 29 36";
+const char OID_id_ce_authorityKeyIdentifier[] = "2 5 29 35";
+const char OID_id_ce_extKeyUsage[] = "2 5 29 37";
+
+const char OID_sha256[] = "2 16 840 1 101 3 4 2 1";
+const char OID_Netscape_certificate_type[] = "2 16 840 1 113730 1 1";
+//
+////
+
+const bool fBerPcPrimitive = false;
+const bool fBerPcConstructed = true;
+
+class BEROctet
+{
+
+public:
+ typedef std::basic_string<unsigned char> Blob;
+
+ BEROctet();
+ BEROctet(BEROctet const &oct);
+ BEROctet(Blob const &blb);
+ BEROctet(TagClass tcClass, bool fConstructed, unsigned int dwTag, bool fDefinite=true);
+ ~BEROctet();
+
+ BEROctet& operator=(BEROctet const &oct);
+
+ Blob Data() const;
+ void Data(Blob const &data);
+ std::vector<BEROctet*> SubOctetList() const;
+ void Insert(BEROctet const &oct);
+
+ Blob Octet() const;
+
+ TagClass Class() const;
+ bool Constructed() const;
+ unsigned int Tag() const;
+
+ std::string ObjectID() const;
+ void ObjectID(std::string const &str);
+
+ std::string Time() const;
+ void Time(std::string const &str);
+
+ void SearchOID(std::string const &OID, std::vector<BEROctet const*> &result) const;
+ void SearchOIDNext(std::string const &OID, std::vector<BEROctet const*> &result) const;
+
+private:
+ static Blob IdentOctets(TagClass tcClass, bool fConstructed, unsigned int dwTag);
+ static Blob LengthOctets(unsigned int dwLength);
+
+ void Decode(Blob const &blb);
+ bool Modified() const; // =true if octet or sub-octets are modified since decoding
+
+ Blob m_blbOrigOctet; // Original octet that was decoded
+
+ TagClass m_tcClass; // Tag class
+ bool m_fConstructed; // =true if a constructed octed, false if primitive
+ unsigned int m_dwTag; // Tag
+ bool m_fDefinite; // =true for definite form of length octet, false if indefinite
+ bool m_fModified; // =true if octet is modified since decoded, false otherwise
+
+ Blob m_blbData; // Data octets (When primitive)
+ std::vector<BEROctet*> m_SubOctetList; // List of sub-octets (when constructed)
+
+};
+
+
+#endif // _include_beroctet_h
+
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/cardcache.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,312 @@
+/*
+ * 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( );
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/cardcache.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardcache.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/cardmoduleservice.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,350 @@
+// 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;
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/cardmoduleservice.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cardmoduleservice.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,98 @@
+// 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
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/cert_utils.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,879 @@
+/*
+ * 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 "cert_utils.h"
+
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+CCertUtils::CCertUtils(void)
+{
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+CCertUtils::~CCertUtils(void)
+{
+}
+
+// ------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
+bool CCertUtils::IsSequence(BYTE *content)
+{
+ return (content[0] == 0x30);
+}
+
+
+// ------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
+bool CCertUtils::IsInteger(BYTE *content)
+{
+ return (content[0] == 0x02);
+}
+
+
+//------------------------------------------------------------------------------
+// int ExtractContent(ASN1 *pAsn1)
+//
+// Description : Extract contents of a Asn1 block 'pAsn1->Asn1' and place it
+// in 'pAsn1->Content'.
+//
+// Remarks : Field Asn1.pData is allocated by calling function.
+//
+// In : pAsn1->Asn1.pData
+//
+// Out : This fileds are filled (if RV_SUCCESS) :
+// - Tag
+// - Asn1.usLen
+// - Content.usLen
+// - Content.pData
+//
+// Responses : RV_SUCCESS : All is OK.
+// RV_INVALID_DATA : Asn1 block format not supported.
+//
+//------------------------------------------------------------------------------
+int CCertUtils::ExtractContent(ASN1 *pAsn1)
+
+{
+ BYTE
+ *pData;
+ int
+ NbBytes,
+ i;
+
+ pData = pAsn1->Asn1.pData;
+
+ if ((pData[0] & 0x1F) == 0x1F)
+ {
+ // High-tag-number : not supported
+ return(RV_INVALID_DATA);
+ }
+ else
+ {
+ pAsn1->Tag = pData[0];
+ }
+
+ if (pData[1] == 0x80)
+ {
+ // Constructed, indefinite-length method : not supported
+ return(RV_INVALID_DATA);
+ }
+ else if (pData[1] > 0x82)
+ {
+ // Constructed, definite-length method : too long
+ return(RV_INVALID_DATA);
+ }
+ else if (pData[1] < 0x80)
+ {
+ // Primitive, definite-length method
+
+ pAsn1->Content.usLen = pData[1];
+ pAsn1->Content.pData = &pData[2];
+
+ pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2;
+ }
+ else
+ {
+ // Constructed, definite-length method
+
+ NbBytes = pData[1] & 0x7F;
+
+ pAsn1->Content.usLen = 0;
+ for (i = 0; i < NbBytes; i++)
+ {
+ pAsn1->Content.usLen = (pAsn1->Content.usLen << 8) + pData[2+i];
+ }
+ pAsn1->Content.pData = &pData[2+NbBytes];
+
+ pAsn1->Asn1.usLen = pAsn1->Content.usLen + 2 + NbBytes;
+ }
+
+ return(RV_SUCCESS);
+}
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void CCertUtils::MemReverse(BYTE *pbOut, BYTE *pbIn, DWORD dwLen)
+{
+ DWORD i;
+
+ for (i = 0; i < dwLen; i++)
+ {
+ pbOut[i] = pbIn[dwLen - i -1];
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void CCertUtils::ConvAscii (BYTE *pIn,
+ DWORD dwLen,
+ BYTE *pOut
+ )
+{
+#define tohex(x) (((x) >= 0xA) ? ((x) - 0xA + 'A') : ((x) + '0'))
+ register DWORD i;
+
+ for(i=0; i < dwLen; i++)
+ {
+ pOut[i*2] = tohex((pIn[i] >> 4) & 0xF);
+ pOut[i*2+1] = tohex(pIn[i] & 0xF);
+ }
+}
+
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+void CCertUtils::ConvHex (BYTE *pIn,
+ DWORD dwLen,
+ BYTE *pOut
+ )
+{
+#define fromhex(x) (x-((x>='0')&&(x<='9')?'0':((x>='A')&&(x<='F')?'7':'W')))
+ register DWORD i;
+
+ for(i=0; i < dwLen; i+=2)
+ {
+ pOut[i/2] = (fromhex(pIn[i]) << 4) + fromhex(pIn[i+1]);
+ }
+}
+
+
+// ------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
+BYTE* CCertUtils::GetDERLength(BYTE *content, DWORD *len)
+{
+ DWORD NBBytesForLength = 0;
+ unsigned short usLen = 0,i=0;
+
+
+ if(content == NULL){
+ *len = 0;
+ return NULL;
+ }
+ if(content[1] < 0x80){
+ *len = content[1];
+ return &content[2];
+ }
+
+ NBBytesForLength = content[1] & 0x7F;
+
+ usLen = 0;
+ for (i = 0; i < NBBytesForLength; i++)
+ {
+ usLen = (usLen << 8) + content[2+i];
+ }
+
+ *len = usLen;
+ return &content[2+NBBytesForLength];
+
+}
+
+
+//------------------------------------------------------------------------------
+// bool ParseCertificateValue(BYTE *pCert, DWORD dwCertLen,
+// BYTE *pSerialNumber, DWORD *pdwSerialNumberLen,
+// BYTE *pIssuer, DWORD *pdwIssuerLen,
+// BYTE *pSubject, DWORD *pdwSubjectLen
+// )
+//
+// In : pCert : Value of a valid X509 certificate.
+// dwCertLen : Length of value.
+//
+// Out : pSerialNumber : Field 'SerialNumber'
+// pusSerialNumberLen : Serial number length
+// pIssuer : Field 'Issuer'
+// pusIssuerLen : Issuer length
+// pSubject : Field 'Subject'
+// pusSubjectLen : Subject length
+//
+// Responses : true: All is OK.
+// false: Parsing fails.
+//
+//------------------------------------------------------------------------------
+bool CCertUtils::ParseCertificateValue(BYTE *pCert, DWORD /*dwCertLen*/,
+ BYTE *pSerialNumber, DWORD *pdwSerialNumberLen,
+ BYTE *pIssuer, DWORD *pdwIssuerLen,
+ BYTE *pSubject, DWORD *pdwSubjectLen
+ )
+
+{
+ ASN1
+ Value,
+ tbsCert,
+ serialNumberPart,
+ signaturePart,
+ issuerPart,
+ validityPart,
+ subjectPart;
+ bool
+ bValuesToBeReturned;
+ BYTE
+ *pCurrent;
+ int
+ rv;
+ DWORD
+ SerialNumberLen,
+ IssuerLen,
+ SubjectLen;
+
+
+ bValuesToBeReturned = (pSerialNumber != NULL)
+ && (pIssuer != NULL)
+ && (pSubject != NULL);
+
+
+ Value.Asn1.pData = pCert;
+ rv = ExtractContent(&Value);
+ if (rv != RV_SUCCESS) return false;
+
+ tbsCert.Asn1.pData = Value.Content.pData;
+ rv = ExtractContent(&tbsCert);
+ if (rv != RV_SUCCESS) return false;
+
+
+ pCurrent = tbsCert.Content.pData;
+ if (pCurrent[0] == TAG_OPTION_VERSION)
+ {
+ // We have A0 03 02 01 vv where vv is the version
+ pCurrent += 5;
+ }
+
+ serialNumberPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&serialNumberPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = serialNumberPart.Content.pData + serialNumberPart.Content.usLen;
+
+ signaturePart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&signaturePart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = signaturePart.Content.pData + signaturePart.Content.usLen;
+
+ issuerPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&issuerPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = issuerPart.Content.pData + issuerPart.Content.usLen;
+
+ validityPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&validityPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = validityPart.Content.pData + validityPart.Content.usLen;
+
+ subjectPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&subjectPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = subjectPart.Content.pData + subjectPart.Content.usLen;
+
+
+ SerialNumberLen = serialNumberPart.Content.usLen;
+ IssuerLen = issuerPart.Asn1.usLen;
+ SubjectLen = subjectPart.Asn1.usLen;
+
+ if (bValuesToBeReturned)
+ {
+ if ( (*pdwSerialNumberLen < SerialNumberLen)
+ || (*pdwIssuerLen < IssuerLen)
+ || (*pdwSubjectLen < SubjectLen)
+ )
+ {
+ return(false);
+ }
+ memcpy(pSerialNumber, serialNumberPart.Content.pData, SerialNumberLen);
+ memcpy(pIssuer, issuerPart.Asn1.pData, IssuerLen);
+ memcpy(pSubject, subjectPart.Asn1.pData, SubjectLen);
+ *pdwSerialNumberLen = SerialNumberLen;
+ *pdwIssuerLen = IssuerLen;
+ *pdwSubjectLen = SubjectLen;
+ }
+ else
+ {
+ *pdwSerialNumberLen = SerialNumberLen;
+ *pdwIssuerLen = IssuerLen;
+ *pdwSubjectLen = SubjectLen;
+ }
+
+ return(true);
+}
+
+
+// ------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
+bool CCertUtils::MakeCertificateLabel(BYTE *pCert,
+ DWORD /*dwCertLen*/,
+ BYTE *pLabel,
+ DWORD *pdwLabelLen
+ )
+{
+ ASN1
+ AttributeTypePart,
+ AttributeValuePart,
+ AVA,
+ RDN,
+ Value,
+ tbsCert,
+ serialNumberPart,
+ signaturePart,
+ issuerPart,
+ validityPart,
+ subjectPart;
+ BLOC
+ OrganizationName,
+ CommonName;
+ bool
+ bValuesToBeReturned;
+ BYTE
+ *pCurrentRDN,
+ *pCurrent;
+ int
+ rv;
+
+ OrganizationName.pData = NULL;
+ OrganizationName.usLen = 0;
+ CommonName.pData = NULL;
+ CommonName.usLen = 0;
+
+ bValuesToBeReturned = (pLabel != NULL);
+
+ Value.Asn1.pData = pCert;
+ rv = ExtractContent(&Value);
+ if (rv != RV_SUCCESS) return false;
+
+ tbsCert.Asn1.pData = Value.Content.pData;
+ rv = ExtractContent(&tbsCert);
+ if (rv != RV_SUCCESS) return false;
+
+
+ pCurrent = tbsCert.Content.pData;
+ if (pCurrent[0] == TAG_OPTION_VERSION)
+ {
+ /* We have A0 03 02 01 vv where vv is the version */
+ pCurrent += 5;
+ }
+
+ serialNumberPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&serialNumberPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = serialNumberPart.Content.pData + serialNumberPart.Content.usLen;
+
+ signaturePart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&signaturePart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = signaturePart.Content.pData + signaturePart.Content.usLen;
+
+ issuerPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&issuerPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = issuerPart.Content.pData + issuerPart.Content.usLen;
+
+ validityPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&validityPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = validityPart.Content.pData + validityPart.Content.usLen;
+
+ subjectPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&subjectPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = subjectPart.Content.pData + subjectPart.Content.usLen;
+
+
+ // Search field 'OrganizationName' in 'Issuer'
+ pCurrent = issuerPart.Content.pData;
+
+ while (pCurrent < issuerPart.Content.pData + issuerPart.Content.usLen)
+ {
+ RDN.Asn1.pData = pCurrent;
+ rv = ExtractContent(&RDN);
+ if (rv != RV_SUCCESS) return false;
+
+ pCurrentRDN = RDN.Content.pData;
+
+ while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
+ {
+ AVA.Asn1.pData = pCurrentRDN;
+ rv = ExtractContent(&AVA);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeTypePart.Asn1.pData = AVA.Content.pData;
+ rv = ExtractContent(&AttributeTypePart);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
+ + AttributeTypePart.Content.usLen;
+ rv = ExtractContent(&AttributeValuePart);
+ if (rv != RV_SUCCESS) return false;
+
+ // Search 'OrganisationName'
+ if (!memcmp("\x55\x04\x0A",
+ AttributeTypePart.Content.pData,
+ AttributeTypePart.Content.usLen)
+ )
+ {
+ OrganizationName = AttributeValuePart.Content;
+ }
+
+ pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
+ }
+
+ pCurrent = RDN.Content.pData + RDN.Content.usLen;
+ }
+
+ // If no 'OrganizationName' is 'Issuer' search for 'CommonName' in 'Subject'
+ if (OrganizationName.usLen == 0)
+ {
+ pCurrent = issuerPart.Content.pData;
+
+ while (pCurrent < issuerPart.Content.pData + issuerPart.Content.usLen)
+ {
+ RDN.Asn1.pData = pCurrent;
+ rv = ExtractContent(&RDN);
+ if (rv != RV_SUCCESS) return false;
+
+ pCurrentRDN = RDN.Content.pData;
+
+ while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
+ {
+ AVA.Asn1.pData = pCurrentRDN;
+ rv = ExtractContent(&AVA);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeTypePart.Asn1.pData = AVA.Content.pData;
+ rv = ExtractContent(&AttributeTypePart);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
+ + AttributeTypePart.Content.usLen;
+ rv = ExtractContent(&AttributeValuePart);
+ if (rv != RV_SUCCESS) return false;
+
+ // Search 'CommonName'
+ if (!memcmp("\x55\x04\x03",
+ AttributeTypePart.Content.pData,
+ AttributeTypePart.Content.usLen)
+ )
+ {
+ OrganizationName = AttributeValuePart.Content;
+ }
+
+ pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
+ }
+
+ pCurrent = RDN.Content.pData + RDN.Content.usLen;
+ }
+ }
+
+ // Search 'CommonName' in 'Subject'
+ pCurrent = subjectPart.Content.pData;
+
+ while (pCurrent < subjectPart.Content.pData + subjectPart.Content.usLen)
+ {
+ RDN.Asn1.pData = pCurrent;
+ rv = ExtractContent(&RDN);
+ if (rv != RV_SUCCESS) return false;
+
+ pCurrentRDN = RDN.Content.pData;
+
+ while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
+ {
+ AVA.Asn1.pData = pCurrentRDN;
+ rv = ExtractContent(&AVA);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeTypePart.Asn1.pData = AVA.Content.pData;
+ rv = ExtractContent(&AttributeTypePart);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
+ + AttributeTypePart.Content.usLen;
+ rv = ExtractContent(&AttributeValuePart);
+ if (rv != RV_SUCCESS) return false;
+
+ // Search 'CommonName'
+ if (!memcmp("\x55\x04\x03",
+ AttributeTypePart.Content.pData,
+ AttributeTypePart.Content.usLen)
+ )
+ {
+ CommonName = AttributeValuePart.Content;
+ }
+
+ pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
+ }
+
+ pCurrent = RDN.Content.pData + RDN.Content.usLen;
+ }
+
+ if (bValuesToBeReturned)
+ {
+ if ( (*pdwLabelLen < (DWORD)(OrganizationName.usLen + CommonName.usLen))
+ )
+ {
+ return(false);
+ }
+
+ if (CommonName.usLen > 0)
+ {
+ memcpy(pLabel,
+ CommonName.pData,
+ CommonName.usLen
+ );
+ memcpy(&pLabel[CommonName.usLen],
+ "'s ",
+ 3
+ );
+ memcpy(&pLabel[CommonName.usLen+3],
+ OrganizationName.pData,
+ OrganizationName.usLen
+ );
+ memcpy(&pLabel[CommonName.usLen+3+OrganizationName.usLen],
+ " ID",
+ 3
+ );
+
+ *pdwLabelLen = OrganizationName.usLen + CommonName.usLen + 6;
+ }
+ else
+ {
+ memcpy(pLabel,
+ OrganizationName.pData,
+ OrganizationName.usLen
+ );
+ memcpy(&pLabel[OrganizationName.usLen],
+ " ID",
+ 3
+ );
+
+ *pdwLabelLen = OrganizationName.usLen + 3;
+ }
+ }
+ else
+ {
+ if (CommonName.usLen > 0)
+ {
+ *pdwLabelLen = OrganizationName.usLen + CommonName.usLen + 6;
+ }
+ else
+ {
+ *pdwLabelLen = OrganizationName.usLen + 3;
+ }
+ }
+
+ return(true);
+}
+
+
+// ------------------------------------------------------------------------------
+// ------------------------------------------------------------------------------
+bool CCertUtils::MakeCertificateLabelEx(BYTE *pCert,
+ DWORD /*dwCertLen*/,
+ BYTE *pLabel,
+ DWORD *pdwLabelLen
+ )
+{
+ ASN1
+ AttributeTypePart,
+ AttributeValuePart,
+ AVA,
+ RDN,
+ Value,
+ tbsCert,
+ serialNumberPart,
+ signaturePart,
+ issuerPart,
+ validityPart,
+ subjectPart;
+ BLOC
+ OrganizationName,
+ CommonName;
+ bool
+ bValuesToBeReturned;
+ BYTE
+ *pCurrentRDN,
+ *pCurrent,
+ szSerialNumber[256] = "";
+ int
+ rv;
+
+ OrganizationName.pData = NULL;
+ OrganizationName.usLen = 0;
+ CommonName.pData = NULL;
+ CommonName.usLen = 0;
+
+ bValuesToBeReturned = (pLabel != NULL);
+
+ Value.Asn1.pData = pCert;
+ rv = ExtractContent(&Value);
+ if (rv != RV_SUCCESS) return false;
+
+ tbsCert.Asn1.pData = Value.Content.pData;
+ rv = ExtractContent(&tbsCert);
+ if (rv != RV_SUCCESS) return false;
+
+
+ pCurrent = tbsCert.Content.pData;
+ if (pCurrent[0] == TAG_OPTION_VERSION)
+ {
+ /* We have A0 03 02 01 vv where vv is the version */
+ pCurrent += 5;
+ }
+
+ serialNumberPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&serialNumberPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = serialNumberPart.Content.pData + serialNumberPart.Content.usLen;
+
+ memset(szSerialNumber, 0x00, sizeof(szSerialNumber));
+
+ ConvAscii(serialNumberPart.Asn1.pData, serialNumberPart.Asn1.usLen, szSerialNumber);
+
+ signaturePart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&signaturePart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = signaturePart.Content.pData + signaturePart.Content.usLen;
+
+ issuerPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&issuerPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = issuerPart.Content.pData + issuerPart.Content.usLen;
+
+ validityPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&validityPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = validityPart.Content.pData + validityPart.Content.usLen;
+
+ subjectPart.Asn1.pData = pCurrent;
+ rv = ExtractContent(&subjectPart);
+ if (rv != RV_SUCCESS) return false;
+ pCurrent = subjectPart.Content.pData + subjectPart.Content.usLen;
+
+
+ // Search field 'OrganizationName' in 'Issuer'
+ pCurrent = issuerPart.Content.pData;
+
+ while (pCurrent < issuerPart.Content.pData + issuerPart.Content.usLen)
+ {
+ RDN.Asn1.pData = pCurrent;
+ rv = ExtractContent(&RDN);
+ if (rv != RV_SUCCESS) return false;
+
+ pCurrentRDN = RDN.Content.pData;
+
+ while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
+ {
+ AVA.Asn1.pData = pCurrentRDN;
+ rv = ExtractContent(&AVA);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeTypePart.Asn1.pData = AVA.Content.pData;
+ rv = ExtractContent(&AttributeTypePart);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
+ + AttributeTypePart.Content.usLen;
+ rv = ExtractContent(&AttributeValuePart);
+ if (rv != RV_SUCCESS) return false;
+
+ // Search 'OrganisationName'
+ if (!memcmp("\x55\x04\x0A",
+ AttributeTypePart.Content.pData,
+ AttributeTypePart.Content.usLen)
+ )
+ {
+ OrganizationName = AttributeValuePart.Content;
+ }
+
+ pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
+ }
+
+ pCurrent = RDN.Content.pData + RDN.Content.usLen;
+ }
+
+ // If no 'OrganizationName' is 'Issuer' search for 'CommonName' in 'Subject'
+ if (OrganizationName.usLen == 0)
+ {
+ pCurrent = issuerPart.Content.pData;
+
+ while (pCurrent < issuerPart.Content.pData + issuerPart.Content.usLen)
+ {
+ RDN.Asn1.pData = pCurrent;
+ rv = ExtractContent(&RDN);
+ if (rv != RV_SUCCESS) return false;
+
+ pCurrentRDN = RDN.Content.pData;
+
+ while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
+ {
+ AVA.Asn1.pData = pCurrentRDN;
+ rv = ExtractContent(&AVA);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeTypePart.Asn1.pData = AVA.Content.pData;
+ rv = ExtractContent(&AttributeTypePart);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
+ + AttributeTypePart.Content.usLen;
+ rv = ExtractContent(&AttributeValuePart);
+ if (rv != RV_SUCCESS) return false;
+
+ // Search 'CommonName'
+ if (!memcmp("\x55\x04\x03",
+ AttributeTypePart.Content.pData,
+ AttributeTypePart.Content.usLen)
+ )
+ {
+ OrganizationName = AttributeValuePart.Content;
+ }
+
+ pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
+ }
+
+ pCurrent = RDN.Content.pData + RDN.Content.usLen;
+ }
+ }
+
+ // Search 'CommonName' in 'Subject'
+ pCurrent = subjectPart.Content.pData;
+
+ while (pCurrent < subjectPart.Content.pData + subjectPart.Content.usLen)
+ {
+ RDN.Asn1.pData = pCurrent;
+ rv = ExtractContent(&RDN);
+ if (rv != RV_SUCCESS) return false;
+
+ pCurrentRDN = RDN.Content.pData;
+
+ while (pCurrentRDN < RDN.Content.pData + RDN.Content.usLen)
+ {
+ AVA.Asn1.pData = pCurrentRDN;
+ rv = ExtractContent(&AVA);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeTypePart.Asn1.pData = AVA.Content.pData;
+ rv = ExtractContent(&AttributeTypePart);
+ if (rv != RV_SUCCESS) return false;
+
+ AttributeValuePart.Asn1.pData = AttributeTypePart.Content.pData
+ + AttributeTypePart.Content.usLen;
+ rv = ExtractContent(&AttributeValuePart);
+ if (rv != RV_SUCCESS) return false;
+
+ // Search 'CommonName'
+ if (!memcmp("\x55\x04\x03",
+ AttributeTypePart.Content.pData,
+ AttributeTypePart.Content.usLen)
+ )
+ {
+ CommonName = AttributeValuePart.Content;
+ }
+
+ pCurrentRDN = AVA.Content.pData + AVA.Content.usLen;
+ }
+
+ pCurrent = RDN.Content.pData + RDN.Content.usLen;
+ }
+
+ if (bValuesToBeReturned)
+ {
+ if ( (*pdwLabelLen < (DWORD)(OrganizationName.usLen + CommonName.usLen))
+ )
+ {
+ return(false);
+ }
+
+ if (CommonName.usLen > 0)
+ {
+ memcpy(pLabel,
+ CommonName.pData,
+ CommonName.usLen
+ );
+ memcpy(&pLabel[CommonName.usLen],
+ "'s ",
+ 3
+ );
+ memcpy(&pLabel[CommonName.usLen+3],
+ OrganizationName.pData,
+ OrganizationName.usLen
+ );
+ memcpy(&pLabel[CommonName.usLen+3+OrganizationName.usLen],
+ " ID - ",
+ 6
+ );
+ memcpy(&pLabel[CommonName.usLen+3+OrganizationName.usLen+6],
+ szSerialNumber,
+ strlen((char *)szSerialNumber)
+ );
+
+ *pdwLabelLen = OrganizationName.usLen + CommonName.usLen + (DWORD)strlen((char *)szSerialNumber) + 9;
+ }
+ else
+ {
+ memcpy(pLabel,
+ OrganizationName.pData,
+ OrganizationName.usLen
+ );
+ memcpy(&pLabel[OrganizationName.usLen],
+ " ID - ",
+ 6
+ );
+ memcpy(&pLabel[OrganizationName.usLen+6],
+ szSerialNumber,
+ strlen((char *)szSerialNumber)
+ );
+
+ *pdwLabelLen = OrganizationName.usLen + (DWORD)strlen((char *)szSerialNumber) + 6;
+ }
+ }
+ else
+ {
+ if (CommonName.usLen > 0)
+ {
+ *pdwLabelLen = OrganizationName.usLen + CommonName.usLen + (DWORD)strlen((char *)szSerialNumber) + 9;
+ }
+ else
+ {
+ *pdwLabelLen = OrganizationName.usLen + (DWORD)strlen((char *)szSerialNumber) + 6;
+ }
+ }
+
+ return(true);
+}
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/cert_utils.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cert_utils.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,119 @@
+/*
+ * 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
+ *
+ */
+
+#pragma once
+
+#define CERT_TYPE_UNKNOWN (0)
+#define CERT_TYPE_USER (1)
+#define CERT_TYPE_CA_ROOT (2)
+
+#define CERT_USAGE_UNKNOWN (0)
+#define CERT_USAGE_EXCHANGE (AT_KEYEXCHANGE)
+#define CERT_USAGE_SIGNATURE (AT_SIGNATURE)
+
+// Errors code
+#define RV_SUCCESS 0 // Info
+#define RV_COMPRESSION_FAILED 1 // Warning
+#define RV_MALLOC_FAILED 2 // Error
+#define RV_BAD_DICTIONARY 3 // Error
+#define RV_INVALID_DATA 4 // Error
+#define RV_BLOC_TOO_LONG 5 // Warning
+#define RV_FILE_OPEN_FAILED 6 // Error
+#define RV_BUFFER_TOO_SMALL 7 // Error
+
+#define TAG_OPTION_VERSION 0xA0
+
+/*------------------------------------------------------------------------------
+ Types definitions
+------------------------------------------------------------------------------*/
+typedef unsigned char TAG;
+typedef TAG* TAG_PTR;
+typedef BYTE* BYTE_PTR;
+
+typedef struct
+{
+ USHORT usLen;
+ BYTE_PTR pData;
+} BLOC, * BLOC_PTR;
+
+typedef struct
+{
+ BLOC Asn1;
+ BLOC Content;
+ TAG Tag;
+} ASN1, * ASN1_PTR;
+
+
+class CCertUtils
+{
+public:
+ CCertUtils(void);
+ ~CCertUtils(void);
+
+void MemReverse (BYTE *pbOut,
+ BYTE *pbIn,
+ DWORD dwLen
+ );
+
+void ConvAscii (BYTE *pIn,
+ DWORD dwLen,
+ BYTE *pOut
+ );
+
+void ConvHex (BYTE *pIn,
+ DWORD dwLen,
+ BYTE *pOut
+ );
+
+BYTE *GetDERLength (BYTE *content,
+ DWORD *len
+ );
+
+bool ParseCertificateValue (BYTE *pCert,
+ DWORD dwCertLen,
+ BYTE *pSerialNumber,
+ DWORD *pdwSerialNumberLen,
+ BYTE *pIssuer,
+ DWORD *pdwIssuerLen,
+ BYTE *pSubject,
+ DWORD *pdwSubjectLen
+ );
+
+bool MakeCertificateLabel (BYTE *pCert,
+ DWORD dwCertLen,
+ BYTE *pLabel,
+ DWORD *pdwLabelLen
+ );
+
+bool MakeCertificateLabelEx (BYTE *pCert,
+ DWORD dwCertLen,
+ BYTE *pLabel,
+ DWORD *pdwLabelLen
+ );
+
+
+private:
+int ExtractContent (ASN1 *pAsn1);
+
+bool IsSequence (BYTE *content);
+
+bool IsInteger (BYTE *content);
+};
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/certificateobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,258 @@
+/*
+ * 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);
+
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/certificateobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/certificateobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,57 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/config.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/config.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/config.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/config.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,26 @@
+/*
+ * 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_config_h
+#define _include_config_h
+
+#define CONFIG_MAX_SLOT 16
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_digit.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,132 @@
+/*
+ * 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 "cr_global.h"
+#include "cr_nn.h"
+#include "cr_digit.h"
+
+/**
+ * Computes a = b * c, where b and c are digits.
+ *
+ * Lengths: a[2].
+ */
+void NN_DigitMult (NN_DIGIT a[2], NN_DIGIT b, NN_DIGIT c)
+{
+ NN_DIGIT t, u;
+ NN_HALF_DIGIT bHigh, bLow, cHigh, cLow;
+
+ bHigh = (NN_HALF_DIGIT)HIGH_HALF (b);
+ bLow = (NN_HALF_DIGIT)LOW_HALF (b);
+ cHigh = (NN_HALF_DIGIT)HIGH_HALF (c);
+ cLow = (NN_HALF_DIGIT)LOW_HALF (c);
+
+ a[0] = (NN_DIGIT)bLow * (NN_DIGIT)cLow;
+ t = (NN_DIGIT)bLow * (NN_DIGIT)cHigh;
+ u = (NN_DIGIT)bHigh * (NN_DIGIT)cLow;
+ a[1] = (NN_DIGIT)bHigh * (NN_DIGIT)cHigh;
+
+ if ((t += u) < u)
+ a[1] += TO_HIGH_HALF (1);
+ u = TO_HIGH_HALF (t);
+
+ if ((a[0] += u) < u)
+ a[1]++;
+ a[1] += HIGH_HALF (t);
+
+ return ;
+}
+
+/**
+ * Sets a = b / c, where a and c are digits.
+ *
+ * Lengths: b[2].
+ * Assumes b[1] < c and HIGH_HALF (c) > 0. For efficiency, c should be
+ * normalized.
+ */
+void NN_DigitDiv (NN_DIGIT *a, NN_DIGIT b[2], NN_DIGIT c)
+{
+ NN_DIGIT t[2], u, v;
+ NN_HALF_DIGIT aHigh, aLow, cHigh, cLow;
+
+ cHigh = (NN_HALF_DIGIT)HIGH_HALF (c);
+ cLow = (NN_HALF_DIGIT)LOW_HALF (c);
+
+ t[0] = b[0];
+ t[1] = b[1];
+
+ /**
+ * Underestimate high half of quotient and subtract.
+ */
+ if (cHigh == MAX_NN_HALF_DIGIT)
+ aHigh = (NN_HALF_DIGIT)HIGH_HALF (t[1]);
+ else
+ aHigh = (NN_HALF_DIGIT)(t[1] / (cHigh + 1));
+
+ u = (NN_DIGIT)aHigh * (NN_DIGIT)cLow;
+ v = (NN_DIGIT)aHigh * (NN_DIGIT)cHigh;
+ if ((t[0] -= TO_HIGH_HALF (u)) > (MAX_NN_DIGIT - TO_HIGH_HALF (u)))
+ t[1]--;
+ t[1] -= HIGH_HALF (u);
+ t[1] -= v;
+
+ /**
+ * Correct estimate.
+ */
+ while ((t[1] > cHigh) ||
+ ((t[1] == cHigh) && (t[0] >= TO_HIGH_HALF (cLow))))
+ {
+ if ((t[0] -= TO_HIGH_HALF (cLow)) > MAX_NN_DIGIT - TO_HIGH_HALF (cLow))
+ t[1]--;
+ t[1] -= cHigh;
+ aHigh++;
+ }
+
+ /**
+ * Underestimate low half of quotient and subtract.
+ */
+ if (cHigh == MAX_NN_HALF_DIGIT)
+ aLow = (NN_HALF_DIGIT)LOW_HALF (t[1]);
+ else
+ aLow = (NN_HALF_DIGIT)((TO_HIGH_HALF (t[1]) + HIGH_HALF (t[0])) / (cHigh + 1));
+
+ u = (NN_DIGIT)aLow * (NN_DIGIT)cLow;
+ v = (NN_DIGIT)aLow * (NN_DIGIT)cHigh;
+ if ((t[0] -= u) > (MAX_NN_DIGIT - u))
+ t[1]--;
+ if ((t[0] -= TO_HIGH_HALF (v)) > (MAX_NN_DIGIT - TO_HIGH_HALF (v)))
+ t[1]--;
+ t[1] -= HIGH_HALF (v);
+
+ /**
+ * Correct estimate.
+ */
+ while ((t[1] > 0) || ((t[1] == 0) && t[0] >= c))
+ {
+ if ((t[0] -= c) > (MAX_NN_DIGIT - c))
+ t[1]--;
+ aLow++;
+ }
+
+ *a = TO_HIGH_HALF (aHigh) + aLow;
+
+ return ;
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_digit.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_digit.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,28 @@
+/*
+ * 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 _CR_DIGIT_H_
+#define _CR_DIGIT_H_
+
+void NN_DigitMult(NN_DIGIT [2], NN_DIGIT, NN_DIGIT) ;
+void NN_DigitDiv(NN_DIGIT *, NN_DIGIT [2], NN_DIGIT) ;
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_global.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_global.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_global.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_global.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,55 @@
+/*
+ * 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 _CR_GLOBAL_H_
+#define _CR_GLOBAL_H_
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+/* UINT4 defines a four byte word */
+typedef unsigned long int UINT4;
+
+/* Error codes.
+ */
+#define RE_CONTENT_ENCODING 0x0400
+#define RE_DATA 0x0401
+#define RE_DIGEST_ALGORITHM 0x0402
+#define RE_ENCODING 0x0403
+#define RE_KEY 0x0404
+#define RE_KEY_ENCODING 0x0405
+#define RE_LEN 0x0406
+#define RE_MODULUS_LEN 0x0407
+#define RE_NEED_RANDOM 0x0408
+#define RE_PRIVATE_KEY 0x0409
+#define RE_PUBLIC_KEY 0x040a
+#define RE_SIGNATURE 0x040b
+#define RE_SIGNATURE_ENCODING 0x040c
+#define RE_ENCRYPTION_ALGORITHM 0x040d
+
+#define R_memset(x, y, z) memset(x, y, z)
+#define R_memcpy(x, y, z) memcpy(x, y, z)
+#define R_memcmp(x, y, z) memcmp(x, y, z)
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_nn.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,695 @@
+/*
+ * 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 "cr_rsa.h"
+#include "cr_global.h"
+#include "cr_nn.h"
+#include "cr_digit.h"
+
+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);
+
+static unsigned int NN_DigitBits(NN_DIGIT);
+
+/**
+ * Decodes character string b into a, where character string is ordered
+ * from most to least significant.
+ *
+ * Lengths: a[digits], b[len].
+ * Assumes b[i] = 0 for i < len - digits * NN_DIGIT_LEN. (Otherwise most
+ * significant bytes are truncated.)
+ */
+void NN_Decode (NN_DIGIT *a,
+ unsigned int digits,
+ const unsigned char *b,
+ unsigned int len)
+{
+ NN_DIGIT t;
+ int j;
+ unsigned int i, u;
+
+ for (i = 0, j = len - 1; i < digits && j >= 0; i++)
+ {
+ t = 0;
+ for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
+ t |= ((NN_DIGIT)b[j]) << u;
+ a[i] = t;
+ }
+
+ for (; i < digits; i++)
+ a[i] = 0;
+
+ return ;
+}
+
+/**
+ * Encodes b into character string a, where character string is ordered
+ * from most to least significant.
+ *
+ * Lengths: a[len], b[digits].
+ * Assumes NN_Bits (b, digits) <= 8 * len. (Otherwise most significant
+ * digits are truncated.)
+ */
+void NN_Encode (unsigned char *a,
+ unsigned int len,
+ NN_DIGIT *b,
+ unsigned int digits)
+{
+ NN_DIGIT t;
+ int j;
+ unsigned int i, u;
+
+ for (i = 0, j = len - 1; i < digits && j >= 0; i++)
+ {
+ t = b[i];
+ for (u = 0; j >= 0 && u < NN_DIGIT_BITS; j--, u += 8)
+ a[j] = (unsigned char)(t >> u);
+ }
+
+ for (; j >= 0; j--)
+ a[j] = 0;
+
+ return ;
+}
+
+/**
+ * Assigns a = b.
+ *
+ * Lengths: a[digits], b[digits].
+ */
+void NN_Assign (NN_DIGIT *a, NN_DIGIT *b, unsigned int digits)
+{
+ unsigned int i;
+
+ for (i = 0; i < digits; i++)
+ a[i] = b[i];
+
+ return ;
+}
+
+/**
+ * Assigns a = 0.
+ *
+ * Lengths: a[digits].
+ */
+void NN_AssignZero (NN_DIGIT *a, unsigned int digits)
+{
+ unsigned int i;
+
+ for (i = 0; i < digits; i++)
+ a[i] = 0;
+
+ return ;
+}
+
+/**
+ * Assigns a = 2^b.
+ *
+ * Lengths: a[digits].
+ * Requires b < digits * NN_DIGIT_BITS.
+ */
+void NN_Assign2Exp (NN_DIGIT *a, unsigned int b, unsigned int digits)
+{
+ NN_AssignZero (a, digits);
+
+ if (b >= digits * NN_DIGIT_BITS)
+ return;
+
+ a[b / NN_DIGIT_BITS] = (NN_DIGIT)1 << (b % NN_DIGIT_BITS);
+
+ return ;
+}
+
+/**
+ * Computes a = b + c. Returns carry.
+ *
+ * Lengths: a[digits], b[digits], c[digits].
+ */
+NN_DIGIT NN_Add (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
+{
+ NN_DIGIT ai, carry;
+ unsigned int i;
+
+ carry = 0;
+
+ for (i = 0; i < digits; i++)
+ {
+ if ((ai = b[i] + carry) < carry)
+ ai = c[i];
+ else if ((ai += c[i]) < c[i])
+ carry = 1;
+ else
+ carry = 0;
+ a[i] = ai;
+ }
+
+ return (carry);
+}
+
+/**
+ * Computes a = b - c. Returns borrow.
+ *
+ * Lengths: a[digits], b[digits], c[digits].
+ */
+NN_DIGIT NN_Sub (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
+{
+ NN_DIGIT ai, borrow;
+ unsigned int i;
+
+ borrow = 0;
+
+ for (i = 0; i < digits; i++)
+ {
+ if ((ai = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
+ ai = MAX_NN_DIGIT - c[i];
+ else if ((ai -= c[i]) > (MAX_NN_DIGIT - c[i]))
+ borrow = 1;
+ else
+ borrow = 0;
+
+ a[i] = ai;
+ }
+
+ return (borrow);
+}
+
+/**
+ * Computes a = b * c.
+ *
+ * Lengths: a[2*digits], b[digits], c[digits].
+ * Assumes digits < MAX_NN_DIGITS.
+ */
+void NN_Mult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
+{
+ NN_DIGIT t[2*MAX_NN_DIGITS];
+ unsigned int bDigits, cDigits, i;
+
+ NN_AssignZero (t, 2 * digits);
+
+ bDigits = NN_Digits (b, digits);
+ cDigits = NN_Digits (c, digits);
+
+ for (i = 0; i < bDigits; i++)
+ t[i+cDigits] += NN_AddDigitMult (&t[i], &t[i], b[i], c, cDigits);
+
+ NN_Assign (a, t, 2 * digits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)t, 0, sizeof (t));
+
+ return ;
+}
+
+/**
+ * Computes a = b * 2^c (i.e., shifts left c bits), returning carry.
+ *
+ * Lengths: a[digits], b[digits].
+ * Requires c < NN_DIGIT_BITS.
+ */
+NN_DIGIT NN_LShift (NN_DIGIT *a, NN_DIGIT *b, unsigned int c, unsigned int digits)
+{
+ NN_DIGIT bi, carry;
+ unsigned int i, t;
+
+ if (c >= NN_DIGIT_BITS)
+ return (0);
+
+ t = NN_DIGIT_BITS - c;
+
+ carry = 0;
+
+ for (i = 0; i < digits; i++)
+ {
+ bi = b[i];
+ a[i] = (bi << c) | carry;
+ carry = c ? (bi >> t) : 0;
+ }
+
+ return (carry);
+}
+
+/**
+ * Computes a = c div 2^c (i.e., shifts right c bits), returning carry.
+ *
+ * Lengths: a[digits], b[digits].
+ * Requires: c < NN_DIGIT_BITS.
+ */
+NN_DIGIT NN_RShift (NN_DIGIT *a, NN_DIGIT *b, unsigned int c, unsigned int digits)
+{
+ NN_DIGIT bi, carry;
+ int i;
+ unsigned int t;
+
+ if (c >= NN_DIGIT_BITS)
+ return (0);
+
+ t = NN_DIGIT_BITS - c;
+
+ carry = 0;
+
+ for (i = digits - 1; i >= 0; i--)
+ {
+ bi = b[i];
+ a[i] = (bi >> c) | carry;
+ carry = c ? (bi << t) : 0;
+ }
+
+ return (carry);
+}
+
+/**
+ * Computes a = c div d and b = c mod d.
+ *
+ * Lengths: a[cDigits], b[dDigits], c[cDigits], d[dDigits].
+ * Assumes d > 0, cDigits < 2 * MAX_NN_DIGITS,
+ * dDigits < MAX_NN_DIGITS.
+ */
+void NN_Div (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c,
+ unsigned int cDigits, NN_DIGIT *d, unsigned int dDigits)
+{
+ NN_DIGIT ai, cc[2*MAX_NN_DIGITS+1], dd[MAX_NN_DIGITS], t;
+ int i;
+ unsigned int ddDigits, shift;
+
+ ddDigits = NN_Digits (d, dDigits);
+ if (ddDigits == 0)
+ return;
+
+ /**
+ * Normalize operands.
+ */
+ shift = NN_DIGIT_BITS - NN_DigitBits (d[ddDigits-1]);
+ NN_AssignZero (cc, ddDigits);
+ cc[cDigits] = NN_LShift (cc, c, shift, cDigits);
+ NN_LShift (dd, d, shift, ddDigits);
+ t = dd[ddDigits-1];
+
+ NN_AssignZero (a, cDigits);
+
+ for (i = cDigits-ddDigits; i >= 0; i--)
+ {
+ /**
+ * Underestimate quotient digit and subtract.
+ */
+ if (t == MAX_NN_DIGIT)
+ ai = cc[i+ddDigits];
+ else
+ NN_DigitDiv (&ai, &cc[i+ddDigits-1], t + 1);
+
+ cc[i+ddDigits] -= NN_SubDigitMult (&cc[i], &cc[i], ai, dd, ddDigits);
+
+ /**
+ * Correct estimate.
+ */
+ while (cc[i+ddDigits] || (NN_Cmp (&cc[i], dd, ddDigits) >= 0))
+ {
+ ai++;
+ cc[i+ddDigits] -= NN_Sub (&cc[i], &cc[i], dd, ddDigits);
+ }
+
+ a[i] = ai;
+ }
+
+ /**
+ * Restore result.
+ */
+ NN_AssignZero (b, dDigits);
+ NN_RShift (b, cc, shift, ddDigits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)cc, 0, sizeof (cc));
+ R_memset ((POINTER)dd, 0, sizeof (dd));
+
+ return ;
+}
+
+/**
+ * Computes a = b mod c.
+ *
+ * Lengths: a[cDigits], b[bDigits], c[cDigits].
+ * Assumes c > 0, bDigits < 2 * MAX_NN_DIGITS, cDigits < MAX_NN_DIGITS.
+ */
+void NN_Mod (NN_DIGIT *a, NN_DIGIT *b, unsigned int bDigits,
+ NN_DIGIT *c, unsigned int cDigits)
+{
+ NN_DIGIT t[2 * MAX_NN_DIGITS];
+
+ NN_Div (t, a, b, bDigits, c, cDigits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)t, 0, sizeof (t));
+
+ return ;
+}
+
+/**
+ * Computes a = b * c mod d.
+ *
+ * Lengths: a[digits], b[digits], c[digits], d[digits].
+ * Assumes d > 0, digits < MAX_NN_DIGITS.
+ */
+void NN_ModMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, NN_DIGIT *d,
+ unsigned int digits)
+{
+ NN_DIGIT t[2*MAX_NN_DIGITS];
+
+ NN_Mult (t, b, c, digits);
+ NN_Mod (a, t, 2 * digits, d, digits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)t, 0, sizeof (t));
+
+ return ;
+}
+
+/**
+ * Computes a = b^c mod d.
+ *
+ * Lengths: a[dDigits], b[dDigits], c[cDigits], d[dDigits].
+ * Assumes d > 0, cDigits > 0, dDigits < MAX_NN_DIGITS.
+ *
+ * NOTE:
+ * PGP 2.5's mpilib contains a faster modular exponentiation routine, mp_modexp.
+ * If USEMPILIB is defined, NN_ModExp is replaced in the PGP 2.5 sources with a
+ * stub call to mp_modexp. If USEMPILIB is not defined, we'll get a pure (albeit
+ * slower) RSAREF implementation.
+ *
+ * The RSAREF 2.0 license, clause 1(c), permits "...modify[ing] the Program in any
+ * manner for porting or performance improvement purposes..."
+ */
+
+#ifndef USEMPILIB
+void NN_ModExp (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c,
+ unsigned int cDigits, NN_DIGIT *d,
+ unsigned int dDigits)
+{
+ NN_DIGIT bPower[3][MAX_NN_DIGITS], ci, t[MAX_NN_DIGITS];
+ int i;
+ unsigned int ciBits, j, s;
+
+ /**
+ * Store b, b^2 mod d, and b^3 mod d.
+ */
+ NN_Assign (bPower[0], b, dDigits);
+ NN_ModMult (bPower[1], bPower[0], b, d, dDigits);
+ NN_ModMult (bPower[2], bPower[1], b, d, dDigits);
+
+ NN_ASSIGN_DIGIT (t, 1, dDigits);
+
+ cDigits = NN_Digits (c, cDigits);
+ for (i = cDigits - 1; i >= 0; i--)
+ {
+ ci = c[i];
+ ciBits = NN_DIGIT_BITS;
+
+ /**
+ * Scan past leading zero bits of most significant digit.
+ */
+ if (i == (int)(cDigits - 1))
+ {
+ while (! DIGIT_2MSB (ci))
+ {
+ ci <<= 2;
+ ciBits -= 2;
+ }
+ }
+
+ for (j = 0; j < ciBits; j += 2, ci <<= 2)
+ {
+ /**
+ * Compute t = t^4 * b^s mod d, where s = two MSB's of ci.
+ */
+ NN_ModMult (t, t, t, d, dDigits);
+ NN_ModMult (t, t, t, d, dDigits);
+
+ if ((s = DIGIT_2MSB (ci)) != 0)
+ NN_ModMult (t, t, bPower[s-1], d, dDigits);
+ }
+ }
+
+ NN_Assign (a, t, dDigits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)bPower, 0, sizeof (bPower));
+ R_memset ((POINTER)t, 0, sizeof (t));
+
+ return ;
+}
+#endif
+
+/**
+ * Compute a = 1/b mod c, assuming inverse exists.
+ *
+ * Lengths: a[digits], b[digits], c[digits].
+ * Assumes gcd (b, c) = 1, digits < MAX_NN_DIGITS.
+ */
+void NN_ModInv (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
+{
+ NN_DIGIT q[MAX_NN_DIGITS], t1[MAX_NN_DIGITS], t3[MAX_NN_DIGITS],
+ u1[MAX_NN_DIGITS], u3[MAX_NN_DIGITS], v1[MAX_NN_DIGITS],
+ v3[MAX_NN_DIGITS], w[2*MAX_NN_DIGITS];
+ int u1Sign;
+
+ /**
+ * Apply extended Euclidean algorithm, modified to avoid negative
+ * numbers.
+ */
+ NN_ASSIGN_DIGIT (u1, 1, digits);
+ NN_AssignZero (v1, digits);
+ NN_Assign (u3, b, digits);
+ NN_Assign (v3, c, digits);
+ u1Sign = 1;
+
+ while (! NN_Zero (v3, digits))
+ {
+ NN_Div (q, t3, u3, digits, v3, digits);
+ NN_Mult (w, q, v1, digits);
+ NN_Add (t1, u1, w, digits);
+ NN_Assign (u1, v1, digits);
+ NN_Assign (v1, t1, digits);
+ NN_Assign (u3, v3, digits);
+ NN_Assign (v3, t3, digits);
+ u1Sign = -u1Sign;
+ }
+
+ /**
+ * Negate result if sign is negative.
+ */
+ if (u1Sign < 0)
+ NN_Sub (a, c, u1, digits);
+ else
+ NN_Assign (a, u1, digits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)q, 0, sizeof (q));
+ R_memset ((POINTER)t1, 0, sizeof (t1));
+ R_memset ((POINTER)t3, 0, sizeof (t3));
+ R_memset ((POINTER)u1, 0, sizeof (u1));
+ R_memset ((POINTER)u3, 0, sizeof (u3));
+ R_memset ((POINTER)v1, 0, sizeof (v1));
+ R_memset ((POINTER)v3, 0, sizeof (v3));
+ R_memset ((POINTER)w, 0, sizeof (w));
+
+ return ;
+}
+
+/**
+ * Computes a = gcd(b, c).
+ *
+ * Lengths: a[digits], b[digits], c[digits].
+ * Assumes b > c, digits < MAX_NN_DIGITS.
+ */
+void NN_Gcd (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT *c, unsigned int digits)
+{
+ NN_DIGIT t[MAX_NN_DIGITS], u[MAX_NN_DIGITS], v[MAX_NN_DIGITS];
+
+ NN_Assign (u, b, digits);
+ NN_Assign (v, c, digits);
+
+ while (! NN_Zero (v, digits))
+ {
+ NN_Mod (t, u, digits, v, digits);
+ NN_Assign (u, v, digits);
+ NN_Assign (v, t, digits);
+ }
+
+ NN_Assign (a, u, digits);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)t, 0, sizeof (t));
+ R_memset ((POINTER)u, 0, sizeof (u));
+ R_memset ((POINTER)v, 0, sizeof (v));
+}
+
+/**
+ * Returns sign of a - b.
+ *
+ * Lengths: a[digits], b[digits].
+ */
+int NN_Cmp (NN_DIGIT *a, NN_DIGIT *b, unsigned int digits)
+{
+ int i;
+
+ for (i = digits - 1; i >= 0; i--)
+ {
+ if (a[i] > b[i])
+ return (1);
+ if (a[i] < b[i])
+ return (-1);
+ }
+
+ return (0);
+}
+
+/**
+ * Returns nonzero iff a is zero.
+ *
+ * Lengths: a[digits].
+ */
+int NN_Zero (NN_DIGIT *a, unsigned int digits)
+{
+ unsigned int i;
+
+ for (i = 0; i < digits; i++)
+ if (a[i])
+ return (0);
+
+ return (1);
+}
+
+/**
+ * Returns the significant length of a in bits.
+ *
+ * Lengths: a[digits].
+ */
+unsigned int NN_Bits (NN_DIGIT *a, unsigned int digits)
+{
+ if ((digits = NN_Digits (a, digits)) == 0)
+ return (0);
+
+ return ((digits - 1) * NN_DIGIT_BITS + NN_DigitBits (a[digits-1]));
+}
+
+/**
+ * Returns the significant length of a in digits.
+ *
+ * Lengths: a[digits].
+ */
+unsigned int NN_Digits (NN_DIGIT *a, unsigned int digits)
+{
+ int i;
+
+ for (i = digits - 1; i >= 0; i--)
+ if (a[i])
+ break;
+
+ return (i + 1);
+}
+
+/**
+ * Computes a = b + c*d, where c is a digit. Returns carry.
+ *
+ * Lengths: a[digits], b[digits], d[digits].
+ */
+static NN_DIGIT NN_AddDigitMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT c,
+ NN_DIGIT *d, unsigned int digits)
+{
+ NN_DIGIT carry, t[2];
+ unsigned int i;
+
+ if (c == 0)
+ return (0);
+
+ carry = 0;
+ for (i = 0; i < digits; i++)
+ {
+ NN_DigitMult (t, c, d[i]);
+ if ((a[i] = b[i] + carry) < carry)
+ carry = 1;
+ else
+ carry = 0;
+ if ((a[i] += t[0]) < t[0])
+ carry++;
+ carry += t[1];
+ }
+
+ return (carry);
+}
+
+/**
+ * Computes a = b - c*d, where c is a digit. Returns borrow.
+ *
+ * Lengths: a[digits], b[digits], d[digits].
+ */
+static NN_DIGIT NN_SubDigitMult (NN_DIGIT *a, NN_DIGIT *b, NN_DIGIT c,
+ NN_DIGIT *d, unsigned int digits)
+{
+ NN_DIGIT borrow, t[2];
+ unsigned int i;
+
+ if (c == 0)
+ return (0);
+
+ borrow = 0;
+ for (i = 0; i < digits; i++)
+ {
+ NN_DigitMult (t, c, d[i]);
+ if ((a[i] = b[i] - borrow) > (MAX_NN_DIGIT - borrow))
+ borrow = 1;
+ else
+ borrow = 0;
+ if ((a[i] -= t[0]) > (MAX_NN_DIGIT - t[0]))
+ borrow++;
+ borrow += t[1];
+ }
+
+ return (borrow);
+}
+
+/**
+ * Returns the significant length of a in bits, where a is a digit.
+ */
+static unsigned int NN_DigitBits (NN_DIGIT a)
+{
+ unsigned int i;
+
+ for (i = 0; i < NN_DIGIT_BITS; i++, a >>= 1)
+ if (a == 0)
+ break;
+
+ return (i);
+}
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_nn.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_nn.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,147 @@
+/*
+ * 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 _CR_NN_H_
+#define _CR_NN_H_
+
+
+/**
+ * Type definitions.
+ */
+typedef UINT4 NN_DIGIT;
+typedef UINT2 NN_HALF_DIGIT;
+
+/**
+ * Constants:
+ *
+ * Note: MAX_NN_DIGITS is long enough to hold any RSA modulus, plus
+ * one more digit as required by R_GeneratePEMKeys (for n and phiN,
+ * whose lengths must be even). All natural numbers have at most
+ * MAX_NN_DIGITS digits, except for double-length intermediate values
+ * in NN_Mult (t), NN_ModMult (t), NN_ModInv (w), and NN_Div (c).
+ */
+
+/**
+ * Length of digit in bits
+ */
+#define NN_DIGIT_BITS 32
+#define NN_HALF_DIGIT_BITS 16
+
+/**
+ * Length of digit in bytes
+ */
+#define NN_DIGIT_LEN (NN_DIGIT_BITS / 8)
+
+/**
+ * Maximum length in digits
+ */
+#define MAX_NN_DIGITS \
+ ((MAX_RSA_MODULUS_LEN + NN_DIGIT_LEN - 1) / NN_DIGIT_LEN + 1)
+
+/**
+ * Maximum digits
+ */
+#define MAX_NN_DIGIT 0xffffffff
+#define MAX_NN_HALF_DIGIT 0xffff
+
+/**
+ * Some macros:
+ */
+#define LOW_HALF(x) ((x) & MAX_NN_HALF_DIGIT)
+#define HIGH_HALF(x) (((x) >> NN_HALF_DIGIT_BITS) & MAX_NN_HALF_DIGIT)
+#define TO_HIGH_HALF(x) (((NN_DIGIT)(x)) << NN_HALF_DIGIT_BITS)
+#define DIGIT_MSB(x) (unsigned int)(((x) >> (NN_DIGIT_BITS - 1)) & 1)
+#define DIGIT_2MSB(x) (unsigned int)(((x) >> (NN_DIGIT_BITS - 2)) & 3)
+
+#define NN_ASSIGN_DIGIT(a, b, digits) {NN_AssignZero (a, digits); a[0] = b;}
+#define NN_EQUAL(a, b, digits) (! NN_Cmp (a, b, digits))
+#define NN_EVEN(a, digits) (((digits) == 0) || ! (a[0] & 1))
+
+
+/**
+ * Declaration of conversion functions:
+ *
+ NN_Decode (a, digits, b, len) Decodes character string b into a.
+ NN_Encode (a, len, b, digits) Encodes a into character string b.
+
+ ASSIGNMENTS
+ NN_Assign (a, b, digits) Assigns a = b.
+ NN_ASSIGN_DIGIT (a, b, digits) Assigns a = b, where b is a digit.
+ NN_AssignZero (a, b, digits) Assigns a = 0.
+ NN_Assign2Exp (a, b, digits) Assigns a = 2^b.
+
+ ARITHMETIC OPERATIONS
+ NN_Add (a, b, c, digits) Computes a = b + c.
+ NN_Sub (a, b, c, digits) Computes a = b - c.
+ NN_Mult (a, b, c, digits) Computes a = b * c.
+ NN_LShift (a, b, c, digits) Computes a = b * 2^c.
+ NN_RShift (a, b, c, digits) Computes a = b / 2^c.
+ NN_Div (a, b, c, cDigits, d, dDigits) Computes a = c div d and b = c mod d.
+
+ NUMBER THEORY
+ NN_Mod (a, b, bDigits, c, cDigits) Computes a = b mod c.
+ NN_ModMult (a, b, c, d, digits) Computes a = b * c mod d.
+ NN_ModExp (a, b, c, cDigits, d, dDigits) Computes a = b^c mod d.
+ NN_ModInv (a, b, c, digits) Computes a = 1/b mod c.
+ NN_Gcd (a, b, c, digits) Computes a = gcd (b, c).
+
+ OTHER OPERATIONS
+ NN_EVEN (a, digits) Returns 1 iff a is even.
+ NN_Cmp (a, b, digits) Returns sign of a - b.
+ NN_EQUAL (a, digits) Returns 1 iff a = b.
+ NN_Zero (a, digits) Returns 1 iff a = 0.
+ NN_Digits (a, digits) Returns significant length of a in digits.
+ NN_Bits (a, digits) Returns significant length of a in bits.
+ *
+ */
+
+/**
+ * The third parameter changed from 'unsigned char *'
+ */
+void NN_Decode(NN_DIGIT *, unsigned int, const unsigned char *, unsigned int);
+
+void NN_Encode(unsigned char *, unsigned int, NN_DIGIT *, unsigned int);
+
+void NN_Assign(NN_DIGIT *, NN_DIGIT *, unsigned int);
+void NN_AssignZero(NN_DIGIT *, unsigned int);
+void NN_Assign2Exp(NN_DIGIT *, unsigned int, unsigned int);
+
+NN_DIGIT NN_Add(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int);
+NN_DIGIT NN_Sub(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int);
+void NN_Mult(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int);
+void NN_Div(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int);
+NN_DIGIT NN_LShift(NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int);
+NN_DIGIT NN_RShift(NN_DIGIT *, NN_DIGIT *, unsigned int, unsigned int);
+
+void NN_Mod(NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int);
+void NN_ModMult(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int);
+void NN_ModExp(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int, NN_DIGIT *, unsigned int);
+void NN_ModInv(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int);
+void NN_Gcd(NN_DIGIT *, NN_DIGIT *, NN_DIGIT *, unsigned int);
+
+int NN_Cmp(NN_DIGIT *, NN_DIGIT *, unsigned int);
+int NN_Zero(NN_DIGIT *, unsigned int);
+unsigned int NN_Bits(NN_DIGIT *, unsigned int);
+unsigned int NN_Digits(NN_DIGIT *, unsigned int);
+
+
+#endif /* _CR_NN_H_ */
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_random.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,170 @@
+/*
+ * 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 "ha_config.h"
+#include "cr_random.h"
+#include "cr_global.h"
+#include "platconfig.h"
+#include "digest.h"
+#include "md5.h"
+
+#include "cr_rsa.h"
+
+#define RANDOM_BYTES_NEEDED 256
+
+int R_GenerateBytes(
+ unsigned char *block, /* block */
+ unsigned int blockLen, /* length of block */
+ R_RANDOM_STRUCT *randomStruct) /* random structure */
+{
+ unsigned int available, i;
+
+ if (randomStruct->bytesNeeded)
+ {
+ return (RE_NEED_RANDOM);
+ }
+
+ available = randomStruct->outputAvailable;
+
+ while (blockLen > available)
+ {
+ R_memcpy( (POINTER)block,
+ (POINTER)&randomStruct->output[16-available],
+ available) ;
+ block += available;
+ blockLen -= available;
+
+ // Generate new output
+ CMD5* md4Ctx = new CMD5();
+ md4Ctx->HashCore(randomStruct->state,0,16);
+ md4Ctx->HashFinal(randomStruct->output);
+ delete md4Ctx;
+
+ available = 16;
+
+ /**
+ * increment state
+ */
+ for (i = 0; i < 16; i++)
+ {
+ if (randomStruct->state[15-i]++)
+ break;
+ }
+ }
+
+ R_memcpy((POINTER)block, (POINTER)&randomStruct->output[16-available], blockLen);
+ randomStruct->outputAvailable = available - blockLen;
+
+ return (0);
+}
+
+
+int R_RandomInit(R_RANDOM_STRUCT *randomStruct)
+{
+ randomStruct->bytesNeeded = RANDOM_BYTES_NEEDED;
+ R_memset ((POINTER)randomStruct->state, 0, sizeof (randomStruct->state));
+ randomStruct->outputAvailable = 0;
+
+ return (0);
+}
+
+
+int R_RandomUpdate(
+ R_RANDOM_STRUCT *randomStruct, /* random structure */
+ unsigned char *block, /* block of values to mix in */
+ unsigned int blockLen) /* length of block */
+{
+ unsigned char digest[16];
+ unsigned int i, x;
+
+ CMD5* md5Ctx = new CMD5();
+ md5Ctx->HashCore(block,0,blockLen);
+ md5Ctx->HashFinal(digest);
+ delete md5Ctx;
+
+ /* add digest to state */
+ x = 0;
+ for (i = 0; i < 16; i++)
+ {
+ x += randomStruct->state[15-i] + digest[15-i];
+ randomStruct->state[15-i] = (unsigned char)x;
+ x >>= 8;
+ }
+
+ if (randomStruct->bytesNeeded < blockLen)
+ randomStruct->bytesNeeded = 0;
+ else
+ randomStruct->bytesNeeded -= blockLen;
+
+ /**
+ * Zeroize sensitive information.
+ */
+ R_memset ((POINTER)digest, 0, sizeof (digest));
+ x = 0;
+
+ return (0);
+}
+
+
+int R_GetRandomBytesNeeded(
+ unsigned int *bytesNeeded, /* number of mix-in bytes needed */
+ R_RANDOM_STRUCT *randomStruct) /* random structure */
+{
+ *bytesNeeded = randomStruct->bytesNeeded;
+ return (0);
+}
+
+
+void R_RandomFinal(R_RANDOM_STRUCT *randomStruct)
+{
+ R_memset((POINTER)randomStruct, 0, sizeof (*randomStruct)) ;
+}
+
+
+/**
+ * Initialize the random structure with all zero seed bytes.
+ *
+ * NOTE: that this will cause the output of the "random" process
+ * to be the same every time. To produce random bytes, the random
+ * struct needs random seeds.
+ */
+void InitRandomStruct(R_RANDOM_STRUCT *randomStruct)
+{
+ static unsigned char seedByte = 0;
+ unsigned int bytesNeeded;
+
+ R_RandomInit (randomStruct);
+
+ /**
+ * Initialize with all zero seed bytes, which will not yield
+ * an actual random number output.
+ */
+ int iCondition = 1;
+ while( iCondition )
+ {
+ R_GetRandomBytesNeeded (&bytesNeeded, randomStruct);
+ if (bytesNeeded == 0)
+ break;
+
+ R_RandomUpdate (randomStruct, &seedByte, 1);
+ }
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_random.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_random.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _CR_RANDOM_H_
+#define _CR_RANDOM_H_
+
+
+/**
+ * RSA Random structure.
+ */
+typedef struct {
+ unsigned int bytesNeeded;
+ unsigned char state[16];
+ unsigned int outputAvailable;
+ unsigned char output[16];
+} R_RANDOM_STRUCT;
+
+
+int R_GenerateBytes(unsigned char *, unsigned int, R_RANDOM_STRUCT *);
+
+int R_RandomInit(R_RANDOM_STRUCT *randomStruct) ;
+void InitRandomStruct(R_RANDOM_STRUCT *randomStruct) ;
+int R_GetRandomBytesNeeded(unsigned int *bytesNeeded, R_RANDOM_STRUCT *randomStruct) ;
+int R_RandomUpdate(R_RANDOM_STRUCT *randomStruct, unsigned char *block, unsigned int blockLen) ;
+void R_RandomFinal(R_RANDOM_STRUCT *randomStruct) ;
+
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_rsa.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,375 @@
+/*
+ * 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 "cr_rsa.h"
+#include "cr_global.h"
+#include "cr_nn.h"
+#include "cr_random.h"
+
+#include "ha_config.h"
+
+/**
+ * RSA private-key decryption, according to PKCS #1.
+ */
+int RSAPrivateDecrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PRIVATE_KEY *privateKey) /* RSA private key */
+{
+ int status;
+ unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
+ unsigned int i, modulusLen, pkcsBlockLen;
+
+ modulusLen = (privateKey->bits + 7) / 8;
+ if (inputLen > modulusLen)
+ return (RE_LEN);
+
+ //if (status = RSAPrivateBlock(pkcsBlock, &pkcsBlockLen, input, inputLen, privateKey))
+ status = RSAPrivateBlock(pkcsBlock, &pkcsBlockLen, input, inputLen, privateKey);
+ if ( status )
+ return (status);
+
+ if (pkcsBlockLen != modulusLen)
+ return (RE_LEN);
+
+ /* Require block type 2.
+ */
+ if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 2))
+ return (RE_DATA);
+
+ for (i = 2; i < modulusLen-1; i++)
+ {
+ if (pkcsBlock[i] == 0)
+ break;
+ }
+
+ i++;
+ if (i >= modulusLen)
+ return (RE_DATA);
+
+ *outputLen = modulusLen - i;
+
+ if (*outputLen + 11 > modulusLen)
+ return (RE_DATA);
+
+ R_memcpy ((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen);
+
+ /**
+ * Zeroize sensitive information.
+ */
+ R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
+
+ return (0);
+}
+
+
+/**
+ * Raw RSA private-key operation. Output has same length as modulus.
+ *
+ * Assumes inputLen < length of modulus.
+ * Requires input < modulus.
+ */
+int RSAPrivateBlock (
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PRIVATE_KEY *privateKey) /* RSA private key */
+{
+ NN_DIGIT c[MAX_NN_DIGITS], cP[MAX_NN_DIGITS], cQ[MAX_NN_DIGITS],
+ dP[MAX_NN_DIGITS], dQ[MAX_NN_DIGITS], mP[MAX_NN_DIGITS],
+ mQ[MAX_NN_DIGITS], n[MAX_NN_DIGITS], p[MAX_NN_DIGITS],
+ q[MAX_NN_DIGITS], qInv[MAX_NN_DIGITS], t[MAX_NN_DIGITS] ;
+
+ unsigned int cDigits, nDigits, pDigits;
+ unsigned int len_Mod, len_Prime ;
+
+ len_Mod = (privateKey->bits + 7) / 8 ;
+ len_Prime = (((privateKey->bits + 1) / 2) + 7) / 8 ;
+
+ NN_Decode (c, MAX_NN_DIGITS, input, inputLen);
+ NN_Decode (n, MAX_NN_DIGITS, privateKey->modulus, len_Mod);
+ NN_Decode (p, MAX_NN_DIGITS, privateKey->prime[0], len_Prime);
+ NN_Decode (q, MAX_NN_DIGITS, privateKey->prime[1], len_Prime);
+ NN_Decode (dP, MAX_NN_DIGITS, privateKey->primeExponent[0], len_Prime);
+ NN_Decode (dQ, MAX_NN_DIGITS, privateKey->primeExponent[1], len_Prime);
+ NN_Decode (qInv, MAX_NN_DIGITS, privateKey->coefficient, len_Prime);
+
+ cDigits = NN_Digits (c, MAX_NN_DIGITS);
+ nDigits = NN_Digits (n, MAX_NN_DIGITS);
+ pDigits = NN_Digits (p, MAX_NN_DIGITS);
+
+ if (NN_Cmp (c, n, nDigits) >= 0)
+ return (RE_DATA);
+
+ /**
+ * Compute mP = cP^dP mod p and mQ = cQ^dQ mod q. (Assumes q has
+ * length at most pDigits, i.e., p > q.)
+ */
+ NN_Mod (cP, c, cDigits, p, pDigits);
+ NN_Mod (cQ, c, cDigits, q, pDigits);
+ NN_ModExp (mP, cP, dP, pDigits, p, pDigits);
+ NN_AssignZero (mQ, nDigits);
+ NN_ModExp (mQ, cQ, dQ, pDigits, q, pDigits);
+
+ /**
+ * Chinese Remainder Theorem:
+ * m = ((((mP - mQ) mod p) * qInv) mod p) * q + mQ.
+ */
+ if (NN_Cmp (mP, mQ, pDigits) >= 0)
+ {
+ NN_Sub (t, mP, mQ, pDigits);
+ }
+ else
+ {
+ NN_Sub (t, mQ, mP, pDigits);
+ NN_Sub (t, p, t, pDigits);
+ }
+ NN_ModMult (t, t, qInv, p, pDigits);
+ NN_Mult (t, t, q, pDigits);
+ NN_Add (t, t, mQ, nDigits);
+
+ *outputLen = (privateKey->bits + 7) / 8;
+ NN_Encode (output, *outputLen, t, nDigits);
+
+ /**
+ * Zeroize sensitive information.
+ */
+ R_memset ((POINTER)c, 0, sizeof (c));
+ R_memset ((POINTER)cP, 0, sizeof (cP));
+ R_memset ((POINTER)cQ, 0, sizeof (cQ));
+ R_memset ((POINTER)dP, 0, sizeof (dP));
+ R_memset ((POINTER)dQ, 0, sizeof (dQ));
+ R_memset ((POINTER)mP, 0, sizeof (mP));
+ R_memset ((POINTER)mQ, 0, sizeof (mQ));
+ R_memset ((POINTER)p, 0, sizeof (p));
+ R_memset ((POINTER)q, 0, sizeof (q));
+ R_memset ((POINTER)qInv, 0, sizeof (qInv));
+ R_memset ((POINTER)t, 0, sizeof (t));
+
+ return (0);
+}
+
+
+/**
+ * RSA public-key encryption, according to PKCS #1.
+ */
+int RSAPublicEncrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PUBLIC_KEY *publicKey, /* RSA public key */
+ R_RANDOM_STRUCT *randomStruct) /* random structure */
+{
+ int status;
+ unsigned char byte, pkcsBlock[MAX_RSA_MODULUS_LEN];
+ unsigned int i, modulusLen;
+
+ modulusLen = (publicKey->bits + 7) / 8;
+ if (inputLen + 11 > modulusLen)
+ {
+ return (RE_LEN);
+ }
+
+ /**
+ * block type 2
+ */
+ pkcsBlock[0] = 0;
+ pkcsBlock[1] = 2;
+
+ for (i = 2; i < modulusLen - inputLen - 1; i++)
+ {
+ /**
+ * Find nonzero random byte.
+ */
+ do {
+ R_GenerateBytes (&byte, 1, randomStruct);
+ } while (byte == 0);
+
+ pkcsBlock[i] = byte;
+ }
+
+ /**
+ * separator
+ */
+ pkcsBlock[i++] = 0;
+ R_memcpy ((POINTER)&pkcsBlock[i], (POINTER)input, inputLen);
+ status = RSAPublicBlock(output, outputLen, pkcsBlock, modulusLen, publicKey);
+
+ /**
+ * Zeroize sensitive information.
+ */
+ byte = 0;
+ R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
+
+ return (status);
+}
+
+
+/**
+ * Raw RSA public-key operation. Output has same length as modulus.
+ *
+ * Assumes inputLen < length of modulus.
+ * Requires input < modulus.
+ */
+int RSAPublicBlock(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PUBLIC_KEY *publicKey) /* RSA public key */
+{
+ unsigned int eDigits, nDigits;
+ NN_DIGIT c[MAX_NN_DIGITS],
+ e[MAX_NN_DIGITS],
+ m[MAX_NN_DIGITS],
+ n[MAX_NN_DIGITS] ;
+
+ unsigned int len_Mod ;
+
+ len_Mod = (publicKey->bits + 7) / 8 ;
+
+ NN_Decode (m, MAX_NN_DIGITS, input, inputLen);
+ NN_Decode (n, MAX_NN_DIGITS, publicKey->modulus, len_Mod);
+ NN_Decode (e, MAX_NN_DIGITS, publicKey->exponent, len_Mod);
+ nDigits = NN_Digits (n, MAX_NN_DIGITS);
+ eDigits = NN_Digits (e, MAX_NN_DIGITS);
+
+ if (NN_Cmp (m, n, nDigits) >= 0)
+ {
+ return (RE_DATA);
+ }
+
+ /**
+ * Compute c = m^e mod n.
+ */
+ NN_ModExp (c, m, e, eDigits, n, nDigits);
+
+ *outputLen = (publicKey->bits + 7) / 8;
+ NN_Encode (output, *outputLen, c, nDigits);
+
+ /**
+ * Zeroize sensitive information.
+ */
+ R_memset ((POINTER)c, 0, sizeof (c));
+ R_memset ((POINTER)m, 0, sizeof (m));
+
+ return (0);
+}
+
+
+/**
+ * RSA public-key decryption, according to PKCS #1.
+ */
+int RSAPublicDecrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PUBLIC_KEY *publicKey) /* RSA public key */
+{
+ int status;
+ unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
+ unsigned int i, modulusLen, pkcsBlockLen;
+
+ modulusLen = (publicKey->bits + 7) / 8;
+ if (inputLen > modulusLen)
+ return (RE_LEN);
+
+ status = RSAPublicBlock(pkcsBlock, &pkcsBlockLen, input, inputLen, publicKey) ;
+ if (status)
+ return (status);
+
+ if (pkcsBlockLen != modulusLen)
+ return (RE_LEN);
+
+ /**
+ * Require block type 1.
+ */
+ if ((pkcsBlock[0] != 0) || (pkcsBlock[1] != 1))
+ return (RE_DATA);
+
+ for (i = 2; i < modulusLen-1; i++)
+ {
+ if (pkcsBlock[i] != 0xff)
+ break;
+ }
+
+ /* separator */
+ if (pkcsBlock[i++] != 0)
+ return (RE_DATA);
+
+ *outputLen = modulusLen - i;
+
+ if (*outputLen + 11 > modulusLen)
+ return (RE_DATA);
+
+ R_memcpy((POINTER)output, (POINTER)&pkcsBlock[i], *outputLen);
+
+ /**
+ * Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
+
+ return (0);
+}
+
+/* RSA private-key encryption, according to PKCS #1.
+ */
+int RSAPrivateEncrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PRIVATE_KEY *privateKey) /* RSA private key */
+{
+ int status;
+ unsigned char pkcsBlock[MAX_RSA_MODULUS_LEN];
+ unsigned int i, modulusLen;
+
+ modulusLen = (privateKey->bits + 7) / 8;
+ if (inputLen + 11 > modulusLen)
+ return (RE_LEN);
+
+ pkcsBlock[0] = 0;
+ /* block type 1 */
+ pkcsBlock[1] = 1;
+
+ for (i = 2; i < modulusLen - inputLen - 1; i++)
+ pkcsBlock[i] = 0xff;
+
+ /* separator */
+ pkcsBlock[i++] = 0;
+
+ R_memcpy ((POINTER)&pkcsBlock[i], (POINTER)input, inputLen);
+
+ status = RSAPrivateBlock(output, outputLen, pkcsBlock, modulusLen, privateKey);
+
+ /* Zeroize potentially sensitive information.
+ */
+ R_memset ((POINTER)pkcsBlock, 0, sizeof (pkcsBlock));
+
+ return (status);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/cr_rsa.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/cr_rsa.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,157 @@
+/*
+ * 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 _CR_RSA_H_
+#define _CR_RSA_H_
+
+#include "cr_random.h"
+
+/**
+ * RSA key lengths.
+ */
+#define MIN_RSA_MODULUS_BITS 512
+#define MAX_RSA_MODULUS_BITS 2048
+#define MAX_RSA_MODULUS_LEN ((MAX_RSA_MODULUS_BITS + 7) / 8)
+#define MAX_RSA_PRIME_BITS ((MAX_RSA_MODULUS_BITS + 1) / 2)
+#define MAX_RSA_PRIME_LEN ((MAX_RSA_PRIME_BITS + 7) / 8)
+
+
+/**
+ * RSA public key struct.
+ */
+typedef struct {
+ unsigned int bits; /* length in bits of modulus */
+ unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */
+ unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* public exponent */
+} R_RSA_PUBLIC_KEY;
+
+
+/**
+ * RSA private key struct.
+ *
+ * The size of arrays for key should be:
+ *
+ * modulus [MAX_RSA_MODULUS_LEN]
+ * publicExponent [MAX_RSA_MODULUS_LEN]
+ * exponent [MAX_RSA_MODULUS_LEN]
+ * prime[2] [MAX_RSA_PRIME_LEN]
+ * primeExponent[2] [MAX_RSA_PRIME_LEN]
+ * coefficient [MAX_RSA_PRIME_LEN]
+ */
+typedef struct {
+ unsigned int bits; /* length in bits of modulus */
+ unsigned char modulus[MAX_RSA_MODULUS_LEN]; /* modulus */
+ unsigned char publicExponent[MAX_RSA_MODULUS_LEN]; /* public exponent */
+ unsigned char exponent[MAX_RSA_MODULUS_LEN]; /* private exponent */
+ unsigned char prime[2][MAX_RSA_PRIME_LEN]; /* prime factors */
+ unsigned char primeExponent[2][MAX_RSA_PRIME_LEN]; /* exponents for CRT */
+ unsigned char coefficient[MAX_RSA_PRIME_LEN]; /* CRT coefficient */
+} R_RSA_PRIVATE_KEY;
+
+
+/**
+ * RSA prototype key.
+ */
+typedef struct {
+ unsigned int bits; /* length in bits of modulus */
+ int useFermat4; /* public exponent (1 = F4, 0 = 3) */
+} R_RSA_PROTO_KEY;
+
+
+ /**
+ * ------------------------------------------------------------------------
+ * RSA Interfaces
+ * ------------------------------------------------------------------------
+ */
+
+typedef struct
+{
+ DWORD modulusLength; /* length (bits) of modulus */
+ BYTE* modulus; /* modulus */
+ DWORD publicExponentLength; /* length (bits) of public exponent */
+ BYTE* publicExponent; /* public exponent */
+} rsaPublicKey_t ;
+
+typedef struct
+{
+ DWORD modulusLength; /* length (bits) of modulus */
+ BYTE* modulus; /* modulus */
+ DWORD publicExponentLength; /* length (bits) of public exponent */
+ BYTE* publicExponent; /* public exponent */
+ BYTE* privateExponent; /* private exponent */
+ BYTE* prime[2]; /* prime factors */
+ BYTE* primeExponent[2]; /* exponents for CRT */
+ BYTE* coefficient; /* CRT coefficient */
+} rsaPrivateKey_t ;
+
+
+/**
+ * RSA function declaration for private/public key operation
+ */
+
+int RSAPrivateDecrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PRIVATE_KEY *privateKey); /* RSA private key */
+
+int RSAPrivateEncrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PRIVATE_KEY *privateKey) ; /* RSA private key */
+
+int RSAPrivateBlock(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PRIVATE_KEY *privateKey) ; /* RSA private key */
+
+
+int RSAPublicEncrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PUBLIC_KEY *publicKey, /* RSA public key */
+ R_RANDOM_STRUCT *randomStruct) ; /* random structure */
+
+
+int RSAPublicBlock(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PUBLIC_KEY *publicKey) ; /* RSA public key */
+
+
+int RSAPublicDecrypt(
+ unsigned char *output, /* output block */
+ unsigned int *outputLen, /* length of output block */
+ unsigned char *input, /* input block */
+ unsigned int inputLen, /* length of input block */
+ R_RSA_PUBLIC_KEY *publicKey) ; /* RSA public key */
+
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/critsect.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,112 @@
+/*
+ * 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
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/critsect.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/critsect.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,95 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/dataobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,175 @@
+/*
+ * 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);
+}
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/dataobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/dataobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,51 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/des.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/des.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,54 @@
+/*
+ * 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 "symmalgo.h"
+#include "des.h"
+
+CDES::CDES(){
+ this->_blockSize = 8;
+}
+
+CDES::~CDES(){
+}
+
+void CDES::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];
+ }
+ }
+
+ algo_DES_DESProcess(key,&input[input_offset],&output[output_offset],(u1)encryptMode);
+
+ if(iv != NULL_PTR && this->_encryptMode == DECRYPT){
+ for(CK_LONG i=0;i<8;i++){
+ output[output_offset+i] ^= iv[i];
+ }
+ }
+
+
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/des.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/des.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/des.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/des.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,42 @@
+/*
+ * 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_des_h
+#define _include_des_h
+
+#include "MarshallerCfg.h"
+#include "algo_des.h"
+
+class CDES : public CSymmAlgo
+{
+
+public:
+ CDES();
+ ~CDES();
+
+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);
+
+};
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/digest.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/digest.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -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
+ *
+ */
+
+#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;
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/digest.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/digest.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,49 @@
+/*
+ * 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_digest_h
+#define _include_digest_h
+
+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;
+
+ 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;
+
+public:
+ CDigest();
+ virtual ~CDigest();
+
+ void HashCore(CK_BYTE_PTR data,CK_LONG offset,CK_LONG count);
+ void HashFinal(CK_BYTE_PTR hash);
+ CK_LONG HashLength(void);
+};
+
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/error.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/error.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,340 @@
+/*
+ * 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;
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/error.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/error.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/error.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/error.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/event.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/event.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,141 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/event.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/event.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/event.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/event.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,57 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/ha_config.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsa/ha_config.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/ha_config.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/ha_config.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,42 @@
+/*
+ * 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 _HA_CONFIG_H_
+#define _HA_CONFIG_H_
+
+/**
+ * Global typedefs for use in various Host Agent components.
+ * TODO: Choose a single set and use it consistently.
+ */
+
+typedef signed char s8_t;
+typedef signed short s16_t;
+typedef signed long s32_t;
+
+typedef unsigned char u8_t ;
+typedef unsigned short u16_t ;
+typedef unsigned long u32_t ;
+
+typedef unsigned char u1 ;
+typedef unsigned short u2 ;
+typedef unsigned int u4 ;
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/keyobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,258 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/keyobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/keyobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,52 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/log.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/log.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,2207 @@
+
+/* ---------------- 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
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/log.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/log.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/log.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/log.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,96 @@
+/*
+ * 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
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/md5.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/md5.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -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
+ *
+ */
+
+#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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/md5.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/md5.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,39 @@
+/*
+ * 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_md5_h
+#define _include_md5_h
+
+#include "MarshallerCfg.h"
+#include "algo_md5.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);
+
+public:
+ CMD5();
+ ~CMD5();
+};
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/mutex.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,144 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/mutex.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/mutex.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,54 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/pkcs11.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,2741 @@
+/*
+ * 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"
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/pkcs11.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,300 @@
+/* pkcs11.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.
+ */
+
+#ifndef _PKCS11_H_
+#define _PKCS11_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Before including this file (pkcs11.h) (or pkcs11t.h by
+ * itself), 6 platform-specific macros must be defined. These
+ * macros are described below, and typical definitions for them
+ * are also given. Be advised that these definitions can depend
+ * on both the platform and the compiler used (and possibly also
+ * on whether a Cryptoki library is linked statically or
+ * dynamically).
+ *
+ * In addition to defining these 6 macros, the packing convention
+ * for Cryptoki structures should be set. The Cryptoki
+ * convention on packing is that structures should be 1-byte
+ * aligned.
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, this might be done by using the following
+ * preprocessor directive before including pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(push, cryptoki, 1)
+ *
+ * and using the following preprocessor directive after including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(pop, cryptoki)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, this might be done by using
+ * the following preprocessor directive before including
+ * pkcs11.h or pkcs11t.h:
+ *
+ * #pragma pack(1)
+ *
+ * In a UNIX environment, you're on your own for this. You might
+ * not need to do (or be able to do!) anything.
+ *
+ *
+ * Now for the macros:
+ *
+ *
+ * 1. CK_PTR: The indirection string for making a pointer to an
+ * object. It can be used like this:
+ *
+ * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to produce
+ * Win32 stuff, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to produce Win16 stuff, it might be defined by:
+ *
+ * #define CK_PTR far *
+ *
+ * In a typical UNIX environment, it might be defined by:
+ *
+ * #define CK_PTR *
+ *
+ *
+ * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
+ * an exportable Cryptoki library function definition out of a
+ * return type and a function name. It should be used in the
+ * following fashion to define the exposed Cryptoki functions in
+ * a Cryptoki library:
+ *
+ * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * )
+ * {
+ * ...
+ * }
+ *
+ * If you're using Microsoft Developer Studio 5.0 to define a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllexport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to define a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DEFINE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
+ * an importable Cryptoki library function declaration out of a
+ * return type and a function name. It should be used in the
+ * following fashion:
+ *
+ * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
+ * CK_VOID_PTR pReserved
+ * );
+ *
+ * If you're using Microsoft Developer Studio 5.0 to declare a
+ * function in a Win32 Cryptoki .dll, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __declspec(dllimport) name
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to declare a function in a Win16 Cryptoki .dll, it
+ * might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType __export _far _pascal name
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION(returnType, name) \
+ * returnType name
+ *
+ *
+ * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
+ * which makes a Cryptoki API function pointer declaration or
+ * function pointer type declaration out of a return type and a
+ * function name. It should be used in the following fashion:
+ *
+ * // Define funcPtr to be a pointer to a Cryptoki API function
+ * // taking arguments args and returning CK_RV.
+ * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
+ *
+ * or
+ *
+ * // Define funcPtrType to be the type of a pointer to a
+ * // Cryptoki API function taking arguments args and returning
+ * // CK_RV, and then define funcPtr to be a variable of type
+ * // funcPtrType.
+ * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
+ * funcPtrType funcPtr;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to access
+ * functions in a Win32 Cryptoki .dll, in might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __declspec(dllimport) (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to access functions in a Win16 Cryptoki .dll, it might
+ * be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType __export _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
+ * a function pointer type for an application callback out of
+ * a return type for the callback and a name for the callback.
+ * It should be used in the following fashion:
+ *
+ * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
+ *
+ * to declare a function pointer, myCallback, to a callback
+ * which takes arguments args and returns a CK_RV. It can also
+ * be used like this:
+ *
+ * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
+ * myCallbackType myCallback;
+ *
+ * If you're using Microsoft Developer Studio 5.0 to do Win32
+ * Cryptoki development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ * If you're using an earlier version of Microsoft Developer
+ * Studio to do Win16 development, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType _far _pascal (* name)
+ *
+ * In a UNIX environment, it might be defined by:
+ *
+ * #define CK_CALLBACK_FUNCTION(returnType, name) \
+ * returnType (* name)
+ *
+ *
+ * 6. NULL_PTR: This macro is the value of a NULL pointer.
+ *
+ * In any ANSI/ISO C environment (and in many others as well),
+ * this should best be defined by
+ *
+ * #ifndef NULL_PTR
+ * #define NULL_PTR 0
+ * #endif
+ */
+
+
+/* All the various Cryptoki types and #define'd values are in the
+ * file pkcs11t.h. */
+#include "pkcs11t.h"
+
+#define __PASTE(x,y) x##y
+
+
+/* ==============================================================
+ * Define the "extern" form of all the entry points.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ extern CK_DECLARE_FUNCTION(CK_RV, name)
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define the typedef form of all the entry points. That is, for
+ * each Cryptoki function C_XXX, define a type CK_C_XXX which is
+ * a pointer to that kind of function.
+ * ==============================================================
+ */
+
+#define CK_NEED_ARG_LIST 1
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
+
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+#undef CK_NEED_ARG_LIST
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+/* ==============================================================
+ * Define structed vector of entry points. A CK_FUNCTION_LIST
+ * contains a CK_VERSION indicating a library's Cryptoki version
+ * and then a whole slew of function pointers to the routines in
+ * the library. This type was declared, but not defined, in
+ * pkcs11t.h.
+ * ==============================================================
+ */
+
+#define CK_PKCS11_FUNCTION_INFO(name) \
+ __PASTE(CK_,name) name;
+
+struct CK_FUNCTION_LIST {
+
+ CK_VERSION version; /* Cryptoki version */
+
+/* Pile all the function pointers into the CK_FUNCTION_LIST. */
+/* pkcs11f.h has all the information about the Cryptoki
+ * function prototypes. */
+#include "pkcs11f.h"
+
+};
+
+#undef CK_PKCS11_FUNCTION_INFO
+
+
+#undef __PASTE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/pkcs11f.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11f.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,903 @@
+/* pkcs11f.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 header file contains pretty much everything about all the */
+/* Cryptoki function prototypes. Because this information is */
+/* used for more than just declaring function prototypes, the */
+/* order of the functions appearing herein is important, and */
+/* should not be altered. */
+
+/* General-purpose */
+
+/* C_Initialize initializes the Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Initialize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pInitArgs /* if this is not NULL_PTR, it gets
+ * cast to CK_C_INITIALIZE_ARGS_PTR
+ * and dereferenced */
+);
+#endif
+
+
+/* C_Finalize indicates that an application is done with the
+ * Cryptoki library. */
+CK_PKCS11_FUNCTION_INFO(C_Finalize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_VOID_PTR pReserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
+
+/* C_GetInfo returns general information about Cryptoki. */
+CK_PKCS11_FUNCTION_INFO(C_GetInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_INFO_PTR pInfo /* location that receives information */
+);
+#endif
+
+/* C_GetFunctionList returns the function list. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FUNCTION_LIST_PTR_PTR ppFunctionList /* receives pointer to
+ * function list */
+);
+#endif
+
+/* Slot and token management */
+
+/* C_GetSlotList obtains a list of slots in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_BBOOL tokenPresent, /* only slots with tokens? */
+ CK_SLOT_ID_PTR pSlotList, /* receives array of slot IDs */
+ CK_ULONG_PTR pulCount /* receives number of slots */
+);
+#endif
+
+/* C_GetSlotInfo obtains information about a particular slot in
+ * the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the ID of the slot */
+ CK_SLOT_INFO_PTR pInfo /* receives the slot information */
+);
+#endif
+
+
+
+/* C_GetTokenInfo obtains information about a particular token
+ * in the system. */
+CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_TOKEN_INFO_PTR pInfo /* receives the token information */
+);
+#endif
+
+/* C_GetMechanismList obtains a list of mechanism types
+ * supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of token's slot */
+ CK_MECHANISM_TYPE_PTR pMechanismList, /* gets mech. array */
+ CK_ULONG_PTR pulCount /* gets # of mechs. */
+);
+#endif
+
+/* C_GetMechanismInfo obtains information about a particular
+ * mechanism possibly supported by a token. */
+CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_MECHANISM_TYPE type, /* type of mechanism */
+ CK_MECHANISM_INFO_PTR pInfo /* receives mechanism info */
+);
+#endif
+
+
+/* C_InitToken initializes a token. */
+CK_PKCS11_FUNCTION_INFO(C_InitToken)
+#ifdef CK_NEED_ARG_LIST
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+(
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_UTF8CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+);
+#endif
+
+
+/* C_InitPIN initializes the normal user's PIN. */
+CK_PKCS11_FUNCTION_INFO(C_InitPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pPin, /* the normal user's PIN */
+ CK_ULONG ulPinLen /* length in bytes of the PIN */
+);
+#endif
+
+
+/* C_SetPIN modifies the PIN of the user who is logged in. */
+CK_PKCS11_FUNCTION_INFO(C_SetPIN)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_UTF8CHAR_PTR pOldPin, /* the old PIN */
+ CK_ULONG ulOldLen, /* length of the old PIN */
+ CK_UTF8CHAR_PTR pNewPin, /* the new PIN */
+ CK_ULONG ulNewLen /* length of the new PIN */
+);
+#endif
+
+
+
+/* Session management */
+
+/* C_OpenSession opens a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_OpenSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID, /* the slot's ID */
+ CK_FLAGS flags, /* from CK_SESSION_INFO */
+ CK_VOID_PTR pApplication, /* passed to callback */
+ CK_NOTIFY Notify, /* callback function */
+ CK_SESSION_HANDLE_PTR phSession /* gets session handle */
+);
+#endif
+
+
+/* C_CloseSession closes a session between an application and a
+ * token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseSession)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CloseAllSessions closes all sessions with a token. */
+CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SLOT_ID slotID /* the token's slot */
+);
+#endif
+
+
+/* C_GetSessionInfo obtains information about the session. */
+CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_SESSION_INFO_PTR pInfo /* receives session info */
+);
+#endif
+
+
+/* C_GetOperationState obtains the state of the cryptographic operation
+ * in a session. */
+CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* gets state */
+ CK_ULONG_PTR pulOperationStateLen /* gets state length */
+);
+#endif
+
+
+/* C_SetOperationState restores the state of the cryptographic
+ * operation in a session. */
+CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pOperationState, /* holds state */
+ CK_ULONG ulOperationStateLen, /* holds state length */
+ CK_OBJECT_HANDLE hEncryptionKey, /* en/decryption key */
+ CK_OBJECT_HANDLE hAuthenticationKey /* sign/verify key */
+);
+#endif
+
+
+/* C_Login logs a user into a token. */
+CK_PKCS11_FUNCTION_INFO(C_Login)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_USER_TYPE userType, /* the user type */
+ CK_UTF8CHAR_PTR pPin, /* the user's PIN */
+ CK_ULONG ulPinLen /* the length of the PIN */
+);
+#endif
+
+
+/* C_Logout logs a user out from a token. */
+CK_PKCS11_FUNCTION_INFO(C_Logout)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+/* Object management */
+
+/* C_CreateObject creates a new object. */
+CK_PKCS11_FUNCTION_INFO(C_CreateObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* the object's template */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phObject /* gets new object's handle. */
+);
+#endif
+
+
+/* C_CopyObject copies an object, creating a new object for the
+ * copy. */
+CK_PKCS11_FUNCTION_INFO(C_CopyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new object */
+ CK_ULONG ulCount, /* attributes in template */
+ CK_OBJECT_HANDLE_PTR phNewObject /* receives handle of copy */
+);
+#endif
+
+
+/* C_DestroyObject destroys an object. */
+CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject /* the object's handle */
+);
+#endif
+
+
+/* C_GetObjectSize gets the size of an object in bytes. */
+CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ULONG_PTR pulSize /* receives size of object */
+);
+#endif
+
+
+/* C_GetAttributeValue obtains the value of one or more object
+ * attributes. */
+CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs; gets vals */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_SetAttributeValue modifies the value of one or more object
+ * attributes */
+CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hObject, /* the object's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* specifies attrs and values */
+ CK_ULONG ulCount /* attributes in template */
+);
+#endif
+
+
+/* C_FindObjectsInit initializes a search for token and session
+ * objects that match a template. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_ATTRIBUTE_PTR pTemplate, /* attribute values to match */
+ CK_ULONG ulCount /* attrs in search template */
+);
+#endif
+
+
+/* C_FindObjects continues a search for token and session
+ * objects that match a template, obtaining additional object
+ * handles. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjects)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_OBJECT_HANDLE_PTR phObject, /* gets obj. handles */
+ CK_ULONG ulMaxObjectCount, /* max handles to get */
+ CK_ULONG_PTR pulObjectCount /* actual # returned */
+);
+#endif
+
+
+/* C_FindObjectsFinal finishes a search for token and session
+ * objects. */
+CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* Encryption and decryption */
+
+/* C_EncryptInit initializes an encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the encryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of encryption key */
+);
+#endif
+
+
+/* C_Encrypt encrypts single-part data. */
+CK_PKCS11_FUNCTION_INFO(C_Encrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pData, /* the plaintext data */
+ CK_ULONG ulDataLen, /* bytes of plaintext */
+ CK_BYTE_PTR pEncryptedData, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedDataLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptUpdate continues a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext data len */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text size */
+);
+#endif
+
+
+/* C_EncryptFinal finishes a multiple-part encryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session handle */
+ CK_BYTE_PTR pLastEncryptedPart, /* last c-text */
+ CK_ULONG_PTR pulLastEncryptedPartLen /* gets last size */
+);
+#endif
+
+
+/* C_DecryptInit initializes a decryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the decryption mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of decryption key */
+);
+#endif
+
+
+/* C_Decrypt decrypts encrypted data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Decrypt)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedData, /* ciphertext */
+ CK_ULONG ulEncryptedDataLen, /* ciphertext length */
+ CK_BYTE_PTR pData, /* gets plaintext */
+ CK_ULONG_PTR pulDataLen /* gets p-text size */
+);
+#endif
+
+
+/* C_DecryptUpdate continues a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* encrypted data */
+ CK_ULONG ulEncryptedPartLen, /* input length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* p-text size */
+);
+#endif
+
+
+/* C_DecryptFinal finishes a multiple-part decryption
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pLastPart, /* gets plaintext */
+ CK_ULONG_PTR pulLastPartLen /* p-text size */
+);
+#endif
+
+
+
+/* Message digesting */
+
+/* C_DigestInit initializes a message-digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism /* the digesting mechanism */
+);
+#endif
+
+
+/* C_Digest digests data in a single part. */
+CK_PKCS11_FUNCTION_INFO(C_Digest)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* data to be digested */
+ CK_ULONG ulDataLen, /* bytes of data to digest */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets digest length */
+);
+#endif
+
+
+/* C_DigestUpdate continues a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* data to be digested */
+ CK_ULONG ulPartLen /* bytes of data to be digested */
+);
+#endif
+
+
+/* C_DigestKey continues a multi-part message-digesting
+ * operation, by digesting the value of a secret key as part of
+ * the data already digested. */
+CK_PKCS11_FUNCTION_INFO(C_DigestKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_OBJECT_HANDLE hKey /* secret key to digest */
+);
+#endif
+
+
+/* C_DigestFinal finishes a multiple-part message-digesting
+ * operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pDigest, /* gets the message digest */
+ CK_ULONG_PTR pulDigestLen /* gets byte count of digest */
+);
+#endif
+
+
+
+/* Signing and MACing */
+
+/* C_SignInit initializes a signature (private key encryption)
+ * operation, where the signature is (will be) an appendix to
+ * the data, and plaintext cannot be recovered from the
+ *signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of signature key */
+);
+#endif
+
+
+/* C_Sign signs (encrypts with private key) data in a single
+ * part, where the signature is (will be) an appendix to the
+ * data, and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Sign)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignUpdate continues a multiple-part signature operation,
+ * where the signature is (will be) an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* the data to sign */
+ CK_ULONG ulPartLen /* count of bytes to sign */
+);
+#endif
+
+
+/* C_SignFinal finishes a multiple-part signature operation,
+ * returning the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+/* C_SignRecoverInit initializes a signature operation, where
+ * the data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the signature mechanism */
+ CK_OBJECT_HANDLE hKey /* handle of the signature key */
+);
+#endif
+
+
+/* C_SignRecover signs data in a single operation, where the
+ * data can be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_SignRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* the data to sign */
+ CK_ULONG ulDataLen, /* count of bytes to sign */
+ CK_BYTE_PTR pSignature, /* gets the signature */
+ CK_ULONG_PTR pulSignatureLen /* gets signature length */
+);
+#endif
+
+
+
+/* Verifying signatures and MACs */
+
+/* C_VerifyInit initializes a verification operation, where the
+ * signature is an appendix to the data, and plaintext cannot
+ * cannot be recovered from the signature (e.g. DSA). */
+CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_Verify verifies a signature in a single-part operation,
+ * where the signature is an appendix to the data, and plaintext
+ * cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_Verify)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pData, /* signed data */
+ CK_ULONG ulDataLen, /* length of signed data */
+ CK_BYTE_PTR pSignature, /* signature */
+ CK_ULONG ulSignatureLen /* signature length*/
+);
+#endif
+
+
+/* C_VerifyUpdate continues a multiple-part verification
+ * operation, where the signature is an appendix to the data,
+ * and plaintext cannot be recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pPart, /* signed data */
+ CK_ULONG ulPartLen /* length of signed data */
+);
+#endif
+
+
+/* C_VerifyFinal finishes a multiple-part verification
+ * operation, checking the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen /* signature length */
+);
+#endif
+
+
+/* C_VerifyRecoverInit initializes a signature verification
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the verification mechanism */
+ CK_OBJECT_HANDLE hKey /* verification key */
+);
+#endif
+
+
+/* C_VerifyRecover verifies a signature in a single-part
+ * operation, where the data is recovered from the signature. */
+CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSignature, /* signature to verify */
+ CK_ULONG ulSignatureLen, /* signature length */
+ CK_BYTE_PTR pData, /* gets signed data */
+ CK_ULONG_PTR pulDataLen /* gets signed data len */
+);
+#endif
+
+
+
+/* Dual-function cryptographic operations */
+
+/* C_DigestEncryptUpdate continues a multiple-part digesting
+ * and encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptDigestUpdate continues a multiple-part decryption and
+ * digesting operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets plaintext len */
+);
+#endif
+
+
+/* C_SignEncryptUpdate continues a multiple-part signing and
+ * encryption operation. */
+CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pPart, /* the plaintext data */
+ CK_ULONG ulPartLen, /* plaintext length */
+ CK_BYTE_PTR pEncryptedPart, /* gets ciphertext */
+ CK_ULONG_PTR pulEncryptedPartLen /* gets c-text length */
+);
+#endif
+
+
+/* C_DecryptVerifyUpdate continues a multiple-part decryption and
+ * verify operation. */
+CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_BYTE_PTR pEncryptedPart, /* ciphertext */
+ CK_ULONG ulEncryptedPartLen, /* ciphertext length */
+ CK_BYTE_PTR pPart, /* gets plaintext */
+ CK_ULONG_PTR pulPartLen /* gets p-text length */
+);
+#endif
+
+
+
+/* Key management */
+
+/* C_GenerateKey generates a secret key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key generation mech. */
+ CK_ATTRIBUTE_PTR pTemplate, /* template for new key */
+ CK_ULONG ulCount, /* # of attrs in template */
+ CK_OBJECT_HANDLE_PTR phKey /* gets handle of new key */
+);
+#endif
+
+
+/* C_GenerateKeyPair generates a public-key/private-key pair,
+ * creating new key objects. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session
+ * handle */
+ CK_MECHANISM_PTR pMechanism, /* key-gen
+ * mech. */
+ CK_ATTRIBUTE_PTR pPublicKeyTemplate, /* template
+ * for pub.
+ * key */
+ CK_ULONG ulPublicKeyAttributeCount, /* # pub.
+ * attrs. */
+ CK_ATTRIBUTE_PTR pPrivateKeyTemplate, /* template
+ * for priv.
+ * key */
+ CK_ULONG ulPrivateKeyAttributeCount, /* # priv.
+ * attrs. */
+ CK_OBJECT_HANDLE_PTR phPublicKey, /* gets pub.
+ * key
+ * handle */
+ CK_OBJECT_HANDLE_PTR phPrivateKey /* gets
+ * priv. key
+ * handle */
+);
+#endif
+
+
+/* C_WrapKey wraps (i.e., encrypts) a key. */
+CK_PKCS11_FUNCTION_INFO(C_WrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_MECHANISM_PTR pMechanism, /* the wrapping mechanism */
+ CK_OBJECT_HANDLE hWrappingKey, /* wrapping key */
+ CK_OBJECT_HANDLE hKey, /* key to be wrapped */
+ CK_BYTE_PTR pWrappedKey, /* gets wrapped key */
+ CK_ULONG_PTR pulWrappedKeyLen /* gets wrapped key size */
+);
+#endif
+
+
+/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
+ * key object. */
+CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* unwrapping mech. */
+ CK_OBJECT_HANDLE hUnwrappingKey, /* unwrapping key */
+ CK_BYTE_PTR pWrappedKey, /* the wrapped key */
+ CK_ULONG ulWrappedKeyLen, /* wrapped key len */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+/* C_DeriveKey derives a key from a base key, creating a new key
+ * object. */
+CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* session's handle */
+ CK_MECHANISM_PTR pMechanism, /* key deriv. mech. */
+ CK_OBJECT_HANDLE hBaseKey, /* base key */
+ CK_ATTRIBUTE_PTR pTemplate, /* new key template */
+ CK_ULONG ulAttributeCount, /* template length */
+ CK_OBJECT_HANDLE_PTR phKey /* gets new handle */
+);
+#endif
+
+
+
+/* Random number generation */
+
+/* C_SeedRandom mixes additional seed material into the token's
+ * random number generator. */
+CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR pSeed, /* the seed material */
+ CK_ULONG ulSeedLen /* length of seed material */
+);
+#endif
+
+
+/* C_GenerateRandom generates random data. */
+CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_BYTE_PTR RandomData, /* receives the random data */
+ CK_ULONG ulRandomLen /* # of bytes to generate */
+);
+#endif
+
+
+
+/* Parallel function management */
+
+/* C_GetFunctionStatus is a legacy function; it obtains an
+ * updated status of a function running in parallel with an
+ * application. */
+CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+
+/* C_CancelFunction is a legacy function; it cancels a function
+ * running in parallel. */
+CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_SESSION_HANDLE hSession /* the session's handle */
+);
+#endif
+
+/* Functions added in for Cryptoki Version 2.01 or later */
+
+/* C_WaitForSlotEvent waits for a slot event (token insertion,
+ * removal, etc.) to occur. */
+CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
+#ifdef CK_NEED_ARG_LIST
+(
+ CK_FLAGS flags, /* blocking/nonblocking flag */
+ CK_SLOT_ID_PTR pSlot, /* location that receives the slot ID */
+ CK_VOID_PTR pRserved /* reserved. Should be NULL_PTR */
+);
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/pkcs11t.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/pkcs11t.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,1701 @@
+/* pkcs11t.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.
+ */
+
+/* See top of pkcs11.h for information about the macros that
+ * must be defined and the structure-packing conventions that
+ * must be set before including this file. */
+
+#ifndef _PKCS11T_H_
+#define _PKCS11T_H_ 1
+
+#define CK_TRUE 1
+#define CK_FALSE 0
+
+#ifndef CK_DISABLE_TRUE_FALSE
+#ifndef FALSE
+#define FALSE CK_FALSE
+#endif
+
+#ifndef TRUE
+#define TRUE CK_TRUE
+#endif
+#endif
+
+typedef unsigned short CK_USHORT;
+
+/* an unsigned 8-bit value */
+typedef unsigned char CK_BYTE;
+
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_CHAR;
+
+/* an 8-bit UTF-8 character */
+typedef CK_BYTE CK_UTF8CHAR;
+
+/* a BYTE-sized Boolean flag */
+typedef CK_BYTE CK_BBOOL;
+
+/* an unsigned value, at least 32 bits long */
+typedef unsigned long int CK_ULONG;
+
+/* a signed value, the same size as a CK_ULONG */
+/* CK_LONG is new for v2.0 */
+typedef long int CK_LONG;
+
+/* at least 32 bits; each bit is a Boolean flag */
+typedef CK_ULONG CK_FLAGS;
+
+
+/* some special values for certain CK_ULONG variables */
+#define CK_UNAVAILABLE_INFORMATION (~0UL)
+#define CK_EFFECTIVELY_INFINITE 0
+
+
+typedef CK_BYTE CK_PTR CK_BYTE_PTR;
+typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
+typedef CK_ULONG CK_PTR CK_ULONG_PTR;
+typedef void CK_PTR CK_VOID_PTR;
+
+/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
+typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
+
+
+/* The following value is always invalid if used as a session */
+/* handle or object handle */
+#define CK_INVALID_HANDLE 0
+
+
+typedef struct CK_VERSION {
+ CK_BYTE major; /* integer portion of version number */
+ CK_BYTE minor; /* 1/100ths portion of version number */
+} CK_VERSION;
+
+typedef CK_VERSION CK_PTR CK_VERSION_PTR;
+
+
+typedef struct CK_INFO {
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_VERSION cryptokiVersion; /* Cryptoki interface ver */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags; /* must be zero */
+
+ /* libraryDescription and libraryVersion are new for v2.0 */
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
+ CK_VERSION libraryVersion; /* version of library */
+} CK_INFO;
+
+typedef CK_INFO CK_PTR CK_INFO_PTR;
+
+
+/* CK_NOTIFICATION enumerates the types of notifications that
+ * Cryptoki provides to an application */
+/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_NOTIFICATION;
+#define CKN_SURRENDER 0
+
+
+typedef CK_ULONG CK_SLOT_ID;
+
+typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
+
+
+/* CK_SLOT_INFO provides information about a slot */
+typedef struct CK_SLOT_INFO {
+ /* slotDescription and manufacturerID have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_FLAGS flags;
+
+ /* hardwareVersion and firmwareVersion are new for v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+} CK_SLOT_INFO;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_TOKEN_PRESENT 0x00000001 /* a token is there */
+#define CKF_REMOVABLE_DEVICE 0x00000002 /* removable devices*/
+#define CKF_HW_SLOT 0x00000004 /* hardware slot */
+
+typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
+
+
+/* CK_TOKEN_INFO provides information about a token */
+typedef struct CK_TOKEN_INFO {
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR label[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR model[16]; /* blank padded */
+ CK_CHAR serialNumber[16]; /* blank padded */
+ CK_FLAGS flags; /* see below */
+
+ /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
+ * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
+ * changed from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulMaxSessionCount; /* max open sessions */
+ CK_ULONG ulSessionCount; /* sess. now open */
+ CK_ULONG ulMaxRwSessionCount; /* max R/W sessions */
+ CK_ULONG ulRwSessionCount; /* R/W sess. now open */
+ CK_ULONG ulMaxPinLen; /* in bytes */
+ CK_ULONG ulMinPinLen; /* in bytes */
+ CK_ULONG ulTotalPublicMemory; /* in bytes */
+ CK_ULONG ulFreePublicMemory; /* in bytes */
+ CK_ULONG ulTotalPrivateMemory; /* in bytes */
+ CK_ULONG ulFreePrivateMemory; /* in bytes */
+
+ /* hardwareVersion, firmwareVersion, and time are new for
+ * v2.0 */
+ CK_VERSION hardwareVersion; /* version of hardware */
+ CK_VERSION firmwareVersion; /* version of firmware */
+ CK_CHAR utcTime[16]; /* time */
+} CK_TOKEN_INFO;
+
+/* The flags parameter is defined as follows:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RNG 0x00000001 /* has random #
+ * generator */
+#define CKF_WRITE_PROTECTED 0x00000002 /* token is
+ * write-
+ * protected */
+#define CKF_LOGIN_REQUIRED 0x00000004 /* user must
+ * login */
+#define CKF_USER_PIN_INITIALIZED 0x00000008 /* normal user's
+ * PIN is set */
+
+/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0. If it is set,
+ * that means that *every* time the state of cryptographic
+ * operations of a session is successfully saved, all keys
+ * needed to continue those operations are stored in the state */
+#define CKF_RESTORE_KEY_NOT_NEEDED 0x00000020
+
+/* CKF_CLOCK_ON_TOKEN is new for v2.0. If it is set, that means
+ * that the token has some sort of clock. The time on that
+ * clock is returned in the token info structure */
+#define CKF_CLOCK_ON_TOKEN 0x00000040
+
+/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0. If it is
+ * set, that means that there is some way for the user to login
+ * without sending a PIN through the Cryptoki library itself */
+#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
+
+/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0. If it is true,
+ * that means that a single session with the token can perform
+ * dual simultaneous cryptographic operations (digest and
+ * encrypt; decrypt and digest; sign and encrypt; and decrypt
+ * and sign) */
+#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED 0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. This flag is deprecated in v2.11 and
+ onwards. */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED 0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing, or the PIN has been
+ * expired by the card. */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
+
+typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
+
+
+/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
+ * identifies a session */
+typedef CK_ULONG CK_SESSION_HANDLE;
+
+typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
+
+
+/* CK_USER_TYPE enumerates the types of Cryptoki users */
+/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_USER_TYPE;
+/* Security Officer */
+#define CKU_SO 0
+/* Normal user */
+#define CKU_USER 1
+/* 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 */
+typedef CK_ULONG CK_STATE;
+#define CKS_RO_PUBLIC_SESSION 0
+#define CKS_RO_USER_FUNCTIONS 1
+#define CKS_RW_PUBLIC_SESSION 2
+#define CKS_RW_USER_FUNCTIONS 3
+#define CKS_RW_SO_FUNCTIONS 4
+
+
+/* CK_SESSION_INFO provides information about a session */
+typedef struct CK_SESSION_INFO {
+ CK_SLOT_ID slotID;
+ CK_STATE state;
+ CK_FLAGS flags; /* see below */
+
+ /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulDeviceError; /* device-dependent error code */
+} CK_SESSION_INFO;
+
+/* The flags are defined in the following table:
+ * Bit Flag Mask Meaning
+ */
+#define CKF_RW_SESSION 0x00000002 /* session is r/w */
+#define CKF_SERIAL_SESSION 0x00000004 /* no parallel */
+
+typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
+
+
+/* CK_OBJECT_HANDLE is a token-specific identifier for an
+ * object */
+typedef CK_ULONG CK_OBJECT_HANDLE;
+
+typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
+
+
+/* CK_OBJECT_CLASS is a value that identifies the classes (or
+ * types) of objects that Cryptoki recognizes. It is defined
+ * as follows: */
+/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_OBJECT_CLASS;
+
+/* The following classes of objects are defined: */
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+/* CKO_MECHANISM is new for v2.20 */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+#define CKO_HW_FEATURE 0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_MECHANISM 0x00000007
+#define CKO_VENDOR_DEFINED 0x80000000
+
+typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+/* CKH_USER_INTERFACE is new for v2.20 */
+#define CKH_MONOTONIC_COUNTER 0x00000001
+#define CKH_CLOCK 0x00000002
+#define CKH_USER_INTERFACE 0x00000003
+#define CKH_VENDOR_DEFINED 0x80000000
+
+/* CK_KEY_TYPE is a value that identifies a key type */
+/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_KEY_TYPE;
+
+/* the following key types are defined: */
+#define CKK_RSA 0x00000000
+#define CKK_DSA 0x00000001
+#define CKK_DH 0x00000002
+
+/* CKK_ECDSA and CKK_KEA are new for v2.0 */
+/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
+#define CKK_ECDSA 0x00000003
+#define CKK_EC 0x00000003
+#define CKK_X9_42_DH 0x00000004
+#define CKK_KEA 0x00000005
+
+#define CKK_GENERIC_SECRET 0x00000010
+#define CKK_RC2 0x00000011
+#define CKK_RC4 0x00000012
+#define CKK_DES 0x00000013
+#define CKK_DES2 0x00000014
+#define CKK_DES3 0x00000015
+
+/* all these key types are new for v2.0 */
+#define CKK_CAST 0x00000016
+#define CKK_CAST3 0x00000017
+/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
+#define CKK_CAST5 0x00000018
+#define CKK_CAST128 0x00000018
+#define CKK_RC5 0x00000019
+#define CKK_IDEA 0x0000001A
+#define CKK_SKIPJACK 0x0000001B
+#define CKK_BATON 0x0000001C
+#define CKK_JUNIPER 0x0000001D
+#define CKK_CDMF 0x0000001E
+#define CKK_AES 0x0000001F
+
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKK_BLOWFISH 0x00000020
+#define CKK_TWOFISH 0x00000021
+
+#define CKK_VENDOR_DEFINED 0x80000000
+
+
+/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
+ * type */
+/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
+ * for v2.0 */
+typedef CK_ULONG CK_CERTIFICATE_TYPE;
+
+/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
+/* CKC_WTLS is new for v2.20 */
+#define CKC_X_509 0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
+#define CKC_WTLS 0x00000002
+#define CKC_VENDOR_DEFINED 0x80000000
+
+
+/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
+ * type */
+/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_ATTRIBUTE_TYPE;
+
+/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
+ consists of an array of values. */
+#define CKF_ARRAY_ATTRIBUTE 0x40000000
+
+/* The following attribute types are defined: */
+#define CKA_CLASS 0x00000000
+#define CKA_TOKEN 0x00000001
+#define CKA_PRIVATE 0x00000002
+#define CKA_LABEL 0x00000003
+#define CKA_APPLICATION 0x00000010
+#define CKA_VALUE 0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID 0x00000012
+
+#define CKA_CERTIFICATE_TYPE 0x00000080
+#define CKA_ISSUER 0x00000081
+#define CKA_SERIAL_NUMBER 0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+ * for v2.10 */
+#define CKA_AC_ISSUER 0x00000083
+#define CKA_OWNER 0x00000084
+#define CKA_ATTR_TYPES 0x00000085
+
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED 0x00000086
+
+/* CKA_CERTIFICATE_CATEGORY ...
+ * CKA_CHECK_VALUE are new for v2.20 */
+#define CKA_CERTIFICATE_CATEGORY 0x00000087
+#define CKA_JAVA_MIDP_SECURITY_DOMAIN 0x00000088
+#define CKA_URL 0x00000089
+#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY 0x0000008A
+#define CKA_HASH_OF_ISSUER_PUBLIC_KEY 0x0000008B
+#define CKA_CHECK_VALUE 0x00000090
+
+#define CKA_KEY_TYPE 0x00000100
+#define CKA_SUBJECT 0x00000101
+#define CKA_ID 0x00000102
+#define CKA_SENSITIVE 0x00000103
+#define CKA_ENCRYPT 0x00000104
+#define CKA_DECRYPT 0x00000105
+#define CKA_WRAP 0x00000106
+#define CKA_UNWRAP 0x00000107
+#define CKA_SIGN 0x00000108
+#define CKA_SIGN_RECOVER 0x00000109
+#define CKA_VERIFY 0x0000010A
+#define CKA_VERIFY_RECOVER 0x0000010B
+#define CKA_DERIVE 0x0000010C
+#define CKA_START_DATE 0x00000110
+#define CKA_END_DATE 0x00000111
+#define CKA_MODULUS 0x00000120
+#define CKA_MODULUS_BITS 0x00000121
+#define CKA_PUBLIC_EXPONENT 0x00000122
+#define CKA_PRIVATE_EXPONENT 0x00000123
+#define CKA_PRIME_1 0x00000124
+#define CKA_PRIME_2 0x00000125
+#define CKA_EXPONENT_1 0x00000126
+#define CKA_EXPONENT_2 0x00000127
+#define CKA_COEFFICIENT 0x00000128
+#define CKA_PRIME 0x00000130
+#define CKA_SUBPRIME 0x00000131
+#define CKA_BASE 0x00000132
+
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS 0x00000133
+#define CKA_SUBPRIME_BITS 0x00000134
+#define CKA_SUB_PRIME_BITS CKA_SUBPRIME_BITS
+/* (To retain backwards-compatibility) */
+
+#define CKA_VALUE_BITS 0x00000160
+#define CKA_VALUE_LEN 0x00000161
+
+/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
+#define CKA_EXTRACTABLE 0x00000162
+#define CKA_LOCAL 0x00000163
+#define CKA_NEVER_EXTRACTABLE 0x00000164
+#define CKA_ALWAYS_SENSITIVE 0x00000165
+
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM 0x00000166
+
+#define CKA_MODIFIABLE 0x00000170
+
+/* CKA_ECDSA_PARAMS is deprecated in v2.11,
+ * CKA_EC_PARAMS is preferred. */
+#define CKA_ECDSA_PARAMS 0x00000180
+#define CKA_EC_PARAMS 0x00000180
+
+#define CKA_EC_POINT 0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * are new for v2.10. Deprecated in v2.11 and onwards. */
+#define CKA_SECONDARY_AUTH 0x00000200
+#define CKA_AUTH_PIN_FLAGS 0x00000201
+
+/* CKA_ALWAYS_AUTHENTICATE ...
+ * CKA_UNWRAP_TEMPLATE are new for v2.20 */
+#define CKA_ALWAYS_AUTHENTICATE 0x00000202
+
+#define CKA_WRAP_WITH_TRUSTED 0x00000210
+#define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000211)
+#define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE|0x00000212)
+
+/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_HW_FEATURE_TYPE 0x00000300
+#define CKA_RESET_ON_INIT 0x00000301
+#define CKA_HAS_RESET 0x00000302
+
+/* The following attributes are new for v2.20 */
+#define CKA_PIXEL_X 0x00000400
+#define CKA_PIXEL_Y 0x00000401
+#define CKA_RESOLUTION 0x00000402
+#define CKA_CHAR_ROWS 0x00000403
+#define CKA_CHAR_COLUMNS 0x00000404
+#define CKA_COLOR 0x00000405
+#define CKA_BITS_PER_PIXEL 0x00000406
+#define CKA_CHAR_SETS 0x00000480
+#define CKA_ENCODING_METHODS 0x00000481
+#define CKA_MIME_TYPES 0x00000482
+#define CKA_MECHANISM_TYPE 0x00000500
+#define CKA_REQUIRED_CMS_ATTRIBUTES 0x00000501
+#define CKA_DEFAULT_CMS_ATTRIBUTES 0x00000502
+#define CKA_SUPPORTED_CMS_ATTRIBUTES 0x00000503
+#define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE|0x00000600)
+
+#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 */
+typedef struct CK_ATTRIBUTE {
+ CK_ATTRIBUTE_TYPE type;
+ CK_VOID_PTR pValue;
+
+ /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
+ CK_ULONG ulValueLen; /* in bytes */
+} CK_ATTRIBUTE;
+
+typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
+
+
+/* CK_DATE is a structure that defines a date */
+typedef struct CK_DATE{
+ CK_CHAR year[4]; /* the year ("1900" - "9999") */
+ CK_CHAR month[2]; /* the month ("01" - "12") */
+ CK_CHAR day[2]; /* the day ("01" - "31") */
+} CK_DATE;
+
+
+/* CK_MECHANISM_TYPE is a value that identifies a mechanism
+ * type */
+/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+typedef CK_ULONG CK_MECHANISM_TYPE;
+
+/* the following mechanism types are defined: */
+#define CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
+#define CKM_RSA_PKCS 0x00000001
+#define CKM_RSA_9796 0x00000002
+#define CKM_RSA_X_509 0x00000003
+
+/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
+ * are new for v2.0. They are mechanisms which hash and sign */
+#define CKM_MD2_RSA_PKCS 0x00000004
+#define CKM_MD5_RSA_PKCS 0x00000005
+#define CKM_SHA1_RSA_PKCS 0x00000006
+
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
+ * CKM_RSA_PKCS_OAEP are new for v2.10 */
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
+#define CKM_RSA_PKCS_OAEP 0x00000009
+
+/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
+ * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
+#define CKM_RSA_X9_31 0x0000000B
+#define CKM_SHA1_RSA_X9_31 0x0000000C
+#define CKM_RSA_PKCS_PSS 0x0000000D
+#define CKM_SHA1_RSA_PKCS_PSS 0x0000000E
+
+#define CKM_DSA_KEY_PAIR_GEN 0x00000010
+#define CKM_DSA 0x00000011
+#define CKM_DSA_SHA1 0x00000012
+#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
+#define CKM_DH_PKCS_DERIVE 0x00000021
+
+/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
+ * v2.11 */
+#define CKM_X9_42_DH_KEY_PAIR_GEN 0x00000030
+#define CKM_X9_42_DH_DERIVE 0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
+#define CKM_X9_42_MQV_DERIVE 0x00000033
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_RSA_PKCS 0x00000040
+#define CKM_SHA384_RSA_PKCS 0x00000041
+#define CKM_SHA512_RSA_PKCS 0x00000042
+#define CKM_SHA256_RSA_PKCS_PSS 0x00000043
+#define CKM_SHA384_RSA_PKCS_PSS 0x00000044
+#define CKM_SHA512_RSA_PKCS_PSS 0x00000045
+
+#define CKM_RC2_KEY_GEN 0x00000100
+#define CKM_RC2_ECB 0x00000101
+#define CKM_RC2_CBC 0x00000102
+#define CKM_RC2_MAC 0x00000103
+
+/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
+#define CKM_RC2_MAC_GENERAL 0x00000104
+#define CKM_RC2_CBC_PAD 0x00000105
+
+#define CKM_RC4_KEY_GEN 0x00000110
+#define CKM_RC4 0x00000111
+#define CKM_DES_KEY_GEN 0x00000120
+#define CKM_DES_ECB 0x00000121
+#define CKM_DES_CBC 0x00000122
+#define CKM_DES_MAC 0x00000123
+
+/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
+#define CKM_DES_MAC_GENERAL 0x00000124
+#define CKM_DES_CBC_PAD 0x00000125
+
+#define CKM_DES2_KEY_GEN 0x00000130
+#define CKM_DES3_KEY_GEN 0x00000131
+#define CKM_DES3_ECB 0x00000132
+#define CKM_DES3_CBC 0x00000133
+#define CKM_DES3_MAC 0x00000134
+
+/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
+ * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
+ * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
+#define CKM_DES3_MAC_GENERAL 0x00000135
+#define CKM_DES3_CBC_PAD 0x00000136
+#define CKM_CDMF_KEY_GEN 0x00000140
+#define CKM_CDMF_ECB 0x00000141
+#define CKM_CDMF_CBC 0x00000142
+#define CKM_CDMF_MAC 0x00000143
+#define CKM_CDMF_MAC_GENERAL 0x00000144
+#define CKM_CDMF_CBC_PAD 0x00000145
+
+/* the following four DES mechanisms are new for v2.20 */
+#define CKM_DES_OFB64 0x00000150
+#define CKM_DES_OFB8 0x00000151
+#define CKM_DES_CFB64 0x00000152
+#define CKM_DES_CFB8 0x00000153
+
+#define CKM_MD2 0x00000200
+
+/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD2_HMAC 0x00000201
+#define CKM_MD2_HMAC_GENERAL 0x00000202
+
+#define CKM_MD5 0x00000210
+
+/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
+#define CKM_MD5_HMAC 0x00000211
+#define CKM_MD5_HMAC_GENERAL 0x00000212
+
+#define CKM_SHA_1 0x00000220
+
+/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
+#define CKM_SHA_1_HMAC 0x00000221
+#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128 0x00000230
+#define CKM_RIPEMD128_HMAC 0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
+#define CKM_RIPEMD160 0x00000240
+#define CKM_RIPEMD160_HMAC 0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256 0x00000250
+#define CKM_SHA256_HMAC 0x00000251
+#define CKM_SHA256_HMAC_GENERAL 0x00000252
+#define CKM_SHA384 0x00000260
+#define CKM_SHA384_HMAC 0x00000261
+#define CKM_SHA384_HMAC_GENERAL 0x00000262
+#define CKM_SHA512 0x00000270
+#define CKM_SHA512_HMAC 0x00000271
+#define CKM_SHA512_HMAC_GENERAL 0x00000272
+
+/* All of the following mechanisms are new for v2.0 */
+/* Note that CAST128 and CAST5 are the same algorithm */
+#define CKM_CAST_KEY_GEN 0x00000300
+#define CKM_CAST_ECB 0x00000301
+#define CKM_CAST_CBC 0x00000302
+#define CKM_CAST_MAC 0x00000303
+#define CKM_CAST_MAC_GENERAL 0x00000304
+#define CKM_CAST_CBC_PAD 0x00000305
+#define CKM_CAST3_KEY_GEN 0x00000310
+#define CKM_CAST3_ECB 0x00000311
+#define CKM_CAST3_CBC 0x00000312
+#define CKM_CAST3_MAC 0x00000313
+#define CKM_CAST3_MAC_GENERAL 0x00000314
+#define CKM_CAST3_CBC_PAD 0x00000315
+#define CKM_CAST5_KEY_GEN 0x00000320
+#define CKM_CAST128_KEY_GEN 0x00000320
+#define CKM_CAST5_ECB 0x00000321
+#define CKM_CAST128_ECB 0x00000321
+#define CKM_CAST5_CBC 0x00000322
+#define CKM_CAST128_CBC 0x00000322
+#define CKM_CAST5_MAC 0x00000323
+#define CKM_CAST128_MAC 0x00000323
+#define CKM_CAST5_MAC_GENERAL 0x00000324
+#define CKM_CAST128_MAC_GENERAL 0x00000324
+#define CKM_CAST5_CBC_PAD 0x00000325
+#define CKM_CAST128_CBC_PAD 0x00000325
+#define CKM_RC5_KEY_GEN 0x00000330
+#define CKM_RC5_ECB 0x00000331
+#define CKM_RC5_CBC 0x00000332
+#define CKM_RC5_MAC 0x00000333
+#define CKM_RC5_MAC_GENERAL 0x00000334
+#define CKM_RC5_CBC_PAD 0x00000335
+#define CKM_IDEA_KEY_GEN 0x00000340
+#define CKM_IDEA_ECB 0x00000341
+#define CKM_IDEA_CBC 0x00000342
+#define CKM_IDEA_MAC 0x00000343
+#define CKM_IDEA_MAC_GENERAL 0x00000344
+#define CKM_IDEA_CBC_PAD 0x00000345
+#define CKM_GENERIC_SECRET_KEY_GEN 0x00000350
+#define CKM_CONCATENATE_BASE_AND_KEY 0x00000360
+#define CKM_CONCATENATE_BASE_AND_DATA 0x00000362
+#define CKM_CONCATENATE_DATA_AND_BASE 0x00000363
+#define CKM_XOR_BASE_AND_DATA 0x00000364
+#define CKM_EXTRACT_KEY_FROM_KEY 0x00000365
+#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
+#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
+#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
+ * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+
+/* CKM_TLS_PRF is new for v2.20 */
+#define CKM_TLS_PRF 0x00000378
+
+#define CKM_SSL3_MD5_MAC 0x00000380
+#define CKM_SSL3_SHA1_MAC 0x00000381
+#define CKM_MD5_KEY_DERIVATION 0x00000390
+#define CKM_MD2_KEY_DERIVATION 0x00000391
+#define CKM_SHA1_KEY_DERIVATION 0x00000392
+
+/* CKM_SHA256/384/512 are new for v2.20 */
+#define CKM_SHA256_KEY_DERIVATION 0x00000393
+#define CKM_SHA384_KEY_DERIVATION 0x00000394
+#define CKM_SHA512_KEY_DERIVATION 0x00000395
+
+#define CKM_PBE_MD2_DES_CBC 0x000003A0
+#define CKM_PBE_MD5_DES_CBC 0x000003A1
+#define CKM_PBE_MD5_CAST_CBC 0x000003A2
+#define CKM_PBE_MD5_CAST3_CBC 0x000003A3
+#define CKM_PBE_MD5_CAST5_CBC 0x000003A4
+#define CKM_PBE_MD5_CAST128_CBC 0x000003A4
+#define CKM_PBE_SHA1_CAST5_CBC 0x000003A5
+#define CKM_PBE_SHA1_CAST128_CBC 0x000003A5
+#define CKM_PBE_SHA1_RC4_128 0x000003A6
+#define CKM_PBE_SHA1_RC4_40 0x000003A7
+#define CKM_PBE_SHA1_DES3_EDE_CBC 0x000003A8
+#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
+#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
+#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2 0x000003B0
+
+#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
+
+/* WTLS mechanisms are new for v2.20 */
+#define CKM_WTLS_PRE_MASTER_KEY_GEN 0x000003D0
+#define CKM_WTLS_MASTER_KEY_DERIVE 0x000003D1
+#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC 0x000003D2
+#define CKM_WTLS_PRF 0x000003D3
+#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE 0x000003D4
+#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE 0x000003D5
+
+#define CKM_KEY_WRAP_LYNKS 0x00000400
+#define CKM_KEY_WRAP_SET_OAEP 0x00000401
+
+/* CKM_CMS_SIG is new for v2.20 */
+#define CKM_CMS_SIG 0x00000500
+
+/* Fortezza mechanisms */
+#define CKM_SKIPJACK_KEY_GEN 0x00001000
+#define CKM_SKIPJACK_ECB64 0x00001001
+#define CKM_SKIPJACK_CBC64 0x00001002
+#define CKM_SKIPJACK_OFB64 0x00001003
+#define CKM_SKIPJACK_CFB64 0x00001004
+#define CKM_SKIPJACK_CFB32 0x00001005
+#define CKM_SKIPJACK_CFB16 0x00001006
+#define CKM_SKIPJACK_CFB8 0x00001007
+#define CKM_SKIPJACK_WRAP 0x00001008
+#define CKM_SKIPJACK_PRIVATE_WRAP 0x00001009
+#define CKM_SKIPJACK_RELAYX 0x0000100a
+#define CKM_KEA_KEY_PAIR_GEN 0x00001010
+#define CKM_KEA_KEY_DERIVE 0x00001011
+#define CKM_FORTEZZA_TIMESTAMP 0x00001020
+#define CKM_BATON_KEY_GEN 0x00001030
+#define CKM_BATON_ECB128 0x00001031
+#define CKM_BATON_ECB96 0x00001032
+#define CKM_BATON_CBC128 0x00001033
+#define CKM_BATON_COUNTER 0x00001034
+#define CKM_BATON_SHUFFLE 0x00001035
+#define CKM_BATON_WRAP 0x00001036
+
+/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
+ * CKM_EC_KEY_PAIR_GEN is preferred */
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
+
+#define CKM_ECDSA 0x00001041
+#define CKM_ECDSA_SHA1 0x00001042
+
+/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
+ * are new for v2.11 */
+#define CKM_ECDH1_DERIVE 0x00001050
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001051
+#define CKM_ECMQV_DERIVE 0x00001052
+
+#define CKM_JUNIPER_KEY_GEN 0x00001060
+#define CKM_JUNIPER_ECB128 0x00001061
+#define CKM_JUNIPER_CBC128 0x00001062
+#define CKM_JUNIPER_COUNTER 0x00001063
+#define CKM_JUNIPER_SHUFFLE 0x00001064
+#define CKM_JUNIPER_WRAP 0x00001065
+#define CKM_FASTHASH 0x00001070
+
+/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
+ * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
+ * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
+ * new for v2.11 */
+#define CKM_AES_KEY_GEN 0x00001080
+#define CKM_AES_ECB 0x00001081
+#define CKM_AES_CBC 0x00001082
+#define CKM_AES_MAC 0x00001083
+#define CKM_AES_MAC_GENERAL 0x00001084
+#define CKM_AES_CBC_PAD 0x00001085
+
+/* BlowFish and TwoFish are new for v2.20 */
+#define CKM_BLOWFISH_KEY_GEN 0x00001090
+#define CKM_BLOWFISH_CBC 0x00001091
+#define CKM_TWOFISH_KEY_GEN 0x00001092
+#define CKM_TWOFISH_CBC 0x00001093
+
+
+/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
+#define CKM_DES_ECB_ENCRYPT_DATA 0x00001100
+#define CKM_DES_CBC_ENCRYPT_DATA 0x00001101
+#define CKM_DES3_ECB_ENCRYPT_DATA 0x00001102
+#define CKM_DES3_CBC_ENCRYPT_DATA 0x00001103
+#define CKM_AES_ECB_ENCRYPT_DATA 0x00001104
+#define CKM_AES_CBC_ENCRYPT_DATA 0x00001105
+
+#define CKM_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_X9_42_DH_PARAMETER_GEN 0x00002002
+
+#define CKM_VENDOR_DEFINED 0x80000000
+
+typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
+
+
+/* CK_MECHANISM is a structure that specifies a particular
+ * mechanism */
+typedef struct CK_MECHANISM {
+ CK_MECHANISM_TYPE mechanism;
+ CK_VOID_PTR pParameter;
+
+ /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulParameterLen; /* in bytes */
+} CK_MECHANISM;
+
+typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
+
+
+/* CK_MECHANISM_INFO provides information about a particular
+ * mechanism */
+typedef struct CK_MECHANISM_INFO {
+ CK_ULONG ulMinKeySize;
+ CK_ULONG ulMaxKeySize;
+ CK_FLAGS flags;
+} CK_MECHANISM_INFO;
+
+/* The flags are defined as follows:
+ * Bit Flag Mask Meaning */
+#define CKF_HW 0x00000001 /* performed by HW */
+
+// 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,
+ * and CKF_DERIVE are new for v2.0. They specify whether or not
+ * a mechanism can be used for a particular task */
+#define CKF_ENCRYPT 0x00000100
+#define CKF_DECRYPT 0x00000200
+#define CKF_DIGEST 0x00000400
+#define CKF_SIGN 0x00000800
+#define CKF_SIGN_RECOVER 0x00001000
+#define CKF_VERIFY 0x00002000
+#define CKF_VERIFY_RECOVER 0x00004000
+#define CKF_GENERATE 0x00008000
+#define CKF_GENERATE_KEY_PAIR 0x00010000
+#define CKF_WRAP 0x00020000
+#define CKF_UNWRAP 0x00040000
+#define CKF_DERIVE 0x00080000
+
+/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
+ * describe a token's EC capabilities not available in mechanism
+ * information. */
+#define CKF_EC_F_P 0x00100000
+#define CKF_EC_F_2M 0x00200000
+#define CKF_EC_ECPARAMETERS 0x00400000
+#define CKF_EC_NAMEDCURVE 0x00800000
+#define CKF_EC_UNCOMPRESS 0x01000000
+#define CKF_EC_COMPRESS 0x02000000
+
+#define CKF_EXTENSION 0x80000000 /* FALSE for this version */
+
+typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
+
+
+/* CK_RV is a value that identifies the return value of a
+ * Cryptoki function */
+/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
+typedef CK_ULONG CK_RV;
+
+#define CKR_OK 0x00000000
+#define CKR_CANCEL 0x00000001
+#define CKR_HOST_MEMORY 0x00000002
+#define CKR_SLOT_ID_INVALID 0x00000003
+
+/* CKR_FLAGS_INVALID was removed for v2.0 */
+
+/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
+#define CKR_GENERAL_ERROR 0x00000005
+#define CKR_FUNCTION_FAILED 0x00000006
+
+/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
+ * and CKR_CANT_LOCK are new for v2.01 */
+#define CKR_ARGUMENTS_BAD 0x00000007
+#define CKR_NO_EVENT 0x00000008
+#define CKR_NEED_TO_CREATE_THREADS 0x00000009
+#define CKR_CANT_LOCK 0x0000000A
+
+#define CKR_ATTRIBUTE_READ_ONLY 0x00000010
+#define CKR_ATTRIBUTE_SENSITIVE 0x00000011
+#define CKR_ATTRIBUTE_TYPE_INVALID 0x00000012
+#define CKR_ATTRIBUTE_VALUE_INVALID 0x00000013
+#define CKR_DATA_INVALID 0x00000020
+#define CKR_DATA_LEN_RANGE 0x00000021
+#define CKR_DEVICE_ERROR 0x00000030
+#define CKR_DEVICE_MEMORY 0x00000031
+#define CKR_DEVICE_REMOVED 0x00000032
+#define CKR_ENCRYPTED_DATA_INVALID 0x00000040
+#define CKR_ENCRYPTED_DATA_LEN_RANGE 0x00000041
+#define CKR_FUNCTION_CANCELED 0x00000050
+#define CKR_FUNCTION_NOT_PARALLEL 0x00000051
+
+/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
+#define CKR_FUNCTION_NOT_SUPPORTED 0x00000054
+
+#define CKR_KEY_HANDLE_INVALID 0x00000060
+
+/* CKR_KEY_SENSITIVE was removed for v2.0 */
+
+#define CKR_KEY_SIZE_RANGE 0x00000062
+#define CKR_KEY_TYPE_INCONSISTENT 0x00000063
+
+/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
+ * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
+ * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
+ * v2.0 */
+#define CKR_KEY_NOT_NEEDED 0x00000064
+#define CKR_KEY_CHANGED 0x00000065
+#define CKR_KEY_NEEDED 0x00000066
+#define CKR_KEY_INDIGESTIBLE 0x00000067
+#define CKR_KEY_FUNCTION_NOT_PERMITTED 0x00000068
+#define CKR_KEY_NOT_WRAPPABLE 0x00000069
+#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+
+#define CKR_MECHANISM_INVALID 0x00000070
+#define CKR_MECHANISM_PARAM_INVALID 0x00000071
+
+/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
+ * were removed for v2.0 */
+#define CKR_OBJECT_HANDLE_INVALID 0x00000082
+#define CKR_OPERATION_ACTIVE 0x00000090
+#define CKR_OPERATION_NOT_INITIALIZED 0x00000091
+#define CKR_PIN_INCORRECT 0x000000A0
+#define CKR_PIN_INVALID 0x000000A1
+#define CKR_PIN_LEN_RANGE 0x000000A2
+
+/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
+#define CKR_PIN_EXPIRED 0x000000A3
+#define CKR_PIN_LOCKED 0x000000A4
+
+#define CKR_SESSION_CLOSED 0x000000B0
+#define CKR_SESSION_COUNT 0x000000B1
+#define CKR_SESSION_HANDLE_INVALID 0x000000B3
+#define CKR_SESSION_PARALLEL_NOT_SUPPORTED 0x000000B4
+#define CKR_SESSION_READ_ONLY 0x000000B5
+#define CKR_SESSION_EXISTS 0x000000B6
+
+/* CKR_SESSION_READ_ONLY_EXISTS and
+ * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
+#define CKR_SESSION_READ_ONLY_EXISTS 0x000000B7
+#define CKR_SESSION_READ_WRITE_SO_EXISTS 0x000000B8
+
+#define CKR_SIGNATURE_INVALID 0x000000C0
+#define CKR_SIGNATURE_LEN_RANGE 0x000000C1
+#define CKR_TEMPLATE_INCOMPLETE 0x000000D0
+#define CKR_TEMPLATE_INCONSISTENT 0x000000D1
+#define CKR_TOKEN_NOT_PRESENT 0x000000E0
+#define CKR_TOKEN_NOT_RECOGNIZED 0x000000E1
+#define CKR_TOKEN_WRITE_PROTECTED 0x000000E2
+#define CKR_UNWRAPPING_KEY_HANDLE_INVALID 0x000000F0
+#define CKR_UNWRAPPING_KEY_SIZE_RANGE 0x000000F1
+#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT 0x000000F2
+#define CKR_USER_ALREADY_LOGGED_IN 0x00000100
+#define CKR_USER_NOT_LOGGED_IN 0x00000101
+#define CKR_USER_PIN_NOT_INITIALIZED 0x00000102
+#define CKR_USER_TYPE_INVALID 0x00000103
+
+/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
+ * are new to v2.01 */
+#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN 0x00000104
+#define CKR_USER_TOO_MANY_TYPES 0x00000105
+
+#define CKR_WRAPPED_KEY_INVALID 0x00000110
+#define CKR_WRAPPED_KEY_LEN_RANGE 0x00000112
+#define CKR_WRAPPING_KEY_HANDLE_INVALID 0x00000113
+#define CKR_WRAPPING_KEY_SIZE_RANGE 0x00000114
+#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
+#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
+
+/* These are new to v2.0 */
+#define CKR_RANDOM_NO_RNG 0x00000121
+
+/* These are new to v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+
+/* These are new to v2.0 */
+#define CKR_BUFFER_TOO_SMALL 0x00000150
+#define CKR_SAVED_STATE_INVALID 0x00000160
+#define CKR_INFORMATION_SENSITIVE 0x00000170
+#define CKR_STATE_UNSAVEABLE 0x00000180
+
+/* These are new to v2.01 */
+#define CKR_CRYPTOKI_NOT_INITIALIZED 0x00000190
+#define CKR_CRYPTOKI_ALREADY_INITIALIZED 0x00000191
+#define CKR_MUTEX_BAD 0x000001A0
+#define CKR_MUTEX_NOT_LOCKED 0x000001A1
+
+/* This is new to v2.20 */
+#define CKR_FUNCTION_REJECTED 0x00000200
+
+#define CKR_VENDOR_DEFINED 0x80000000
+
+
+/* CK_NOTIFY is an application callback that processes events */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
+ CK_SESSION_HANDLE hSession, /* the session's handle */
+ CK_NOTIFICATION event,
+ CK_VOID_PTR pApplication /* passed to C_OpenSession */
+);
+
+
+/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
+ * version and pointers of appropriate types to all the
+ * Cryptoki functions */
+/* CK_FUNCTION_LIST is new for v2.0 */
+typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
+
+typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
+
+typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
+
+
+/* CK_CREATEMUTEX is an application callback for creating a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
+ CK_VOID_PTR_PTR ppMutex /* location to receive ptr to mutex */
+);
+
+
+/* CK_DESTROYMUTEX is an application callback for destroying a
+ * mutex object */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_LOCKMUTEX is an application callback for locking a mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_UNLOCKMUTEX is an application callback for unlocking a
+ * mutex */
+typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
+ CK_VOID_PTR pMutex /* pointer to mutex */
+);
+
+
+/* CK_C_INITIALIZE_ARGS provides the optional arguments to
+ * C_Initialize */
+typedef struct CK_C_INITIALIZE_ARGS {
+ CK_CREATEMUTEX CreateMutex;
+ CK_DESTROYMUTEX DestroyMutex;
+ CK_LOCKMUTEX LockMutex;
+ CK_UNLOCKMUTEX UnlockMutex;
+ CK_FLAGS flags;
+ CK_VOID_PTR pReserved;
+} CK_C_INITIALIZE_ARGS;
+
+/* flags: bit flags that provide capabilities of the slot
+ * Bit Flag Mask Meaning
+ */
+#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
+#define CKF_OS_LOCKING_OK 0x00000002
+
+typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
+
+
+/* additional flags for parameters to functions */
+
+/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
+#define CKF_DONT_BLOCK 1
+
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
+
+typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
+ * are new for v2.20 */
+#define CKG_MGF1_SHA1 0x00000001
+#define CKG_MGF1_SHA256 0x00000002
+#define CKG_MGF1_SHA384 0x00000003
+#define CKG_MGF1_SHA512 0x00000004
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
+
+/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
+ * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_PSS mechanism(s). */
+typedef struct CK_RSA_PKCS_PSS_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_MGF_TYPE mgf;
+ CK_ULONG sLen;
+} CK_RSA_PKCS_PSS_PARAMS;
+
+typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
+
+/* CK_EC_KDF_TYPE is new for v2.11. */
+typedef CK_ULONG CK_EC_KDF_TYPE;
+
+/* The following EC Key Derivation Functions are defined */
+#define CKD_NULL 0x00000001
+#define CKD_SHA1_KDF 0x00000002
+
+/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
+ * where each party contributes one key pair.
+ */
+typedef struct CK_ECDH1_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_ECDH1_DERIVE_PARAMS;
+
+typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
+
+
+/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
+ * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
+typedef struct CK_ECDH2_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_ECDH2_DERIVE_PARAMS;
+
+typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_ECMQV_DERIVE_PARAMS {
+ CK_EC_KDF_TYPE kdf;
+ CK_ULONG ulSharedDataLen;
+ CK_BYTE_PTR pSharedData;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_ECMQV_DERIVE_PARAMS;
+
+typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
+
+/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
+ * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
+typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
+typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
+
+/* The following X9.42 DH key derivation functions are defined
+ (besides CKD_NULL already defined : */
+#define CKD_SHA1_KDF_ASN1 0x00000003
+#define CKD_SHA1_KDF_CONCATENATE 0x00000004
+
+/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
+ * contributes one key pair */
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_X9_42_DH1_DERIVE_PARAMS;
+
+typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
+
+/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
+ * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
+ * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
+ * mechanisms, where each party contributes two key pairs */
+typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+} CK_X9_42_DH2_DERIVE_PARAMS;
+
+typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
+
+typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
+ CK_X9_42_DH_KDF_TYPE kdf;
+ CK_ULONG ulOtherInfoLen;
+ CK_BYTE_PTR pOtherInfo;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPrivateDataLen;
+ CK_OBJECT_HANDLE hPrivateData;
+ CK_ULONG ulPublicDataLen2;
+ CK_BYTE_PTR pPublicData2;
+ CK_OBJECT_HANDLE publicKey;
+} CK_X9_42_MQV_DERIVE_PARAMS;
+
+typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
+
+/* CK_KEA_DERIVE_PARAMS provides the parameters to the
+ * CKM_KEA_DERIVE mechanism */
+/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
+typedef struct CK_KEA_DERIVE_PARAMS {
+ CK_BBOOL isSender;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pRandomB;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+} CK_KEA_DERIVE_PARAMS;
+
+typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
+
+
+/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
+ * CKM_RC2_MAC mechanisms. An instance of CK_RC2_PARAMS just
+ * holds the effective keysize */
+typedef CK_ULONG CK_RC2_PARAMS;
+
+typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
+
+
+/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
+ * mechanism */
+typedef struct CK_RC2_CBC_PARAMS {
+ /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
+ * v2.0 */
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+
+ CK_BYTE iv[8]; /* IV for CBC mode */
+} CK_RC2_CBC_PARAMS;
+
+typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
+
+
+/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC2_MAC_GENERAL mechanism */
+/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC2_MAC_GENERAL_PARAMS {
+ CK_ULONG ulEffectiveBits; /* effective bits (1-1024) */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC2_MAC_GENERAL_PARAMS;
+
+typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC2_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
+ * CKM_RC5_MAC mechanisms */
+/* CK_RC5_PARAMS is new for v2.0 */
+typedef struct CK_RC5_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+} CK_RC5_PARAMS;
+
+typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
+
+
+/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
+ * mechanism */
+/* CK_RC5_CBC_PARAMS is new for v2.0 */
+typedef struct CK_RC5_CBC_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_BYTE_PTR pIv; /* pointer to IV */
+ CK_ULONG ulIvLen; /* length of IV in bytes */
+} CK_RC5_CBC_PARAMS;
+
+typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
+
+
+/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
+ * CKM_RC5_MAC_GENERAL mechanism */
+/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef struct CK_RC5_MAC_GENERAL_PARAMS {
+ CK_ULONG ulWordsize; /* wordsize in bits */
+ CK_ULONG ulRounds; /* number of rounds */
+ CK_ULONG ulMacLength; /* Length of MAC in bytes */
+} CK_RC5_MAC_GENERAL_PARAMS;
+
+typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
+ CK_RC5_MAC_GENERAL_PARAMS_PTR;
+
+
+/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
+ * ciphers' MAC_GENERAL mechanisms. Its value is the length of
+ * the MAC */
+/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_MAC_GENERAL_PARAMS;
+
+typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
+
+/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
+typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[8];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
+ CK_BYTE iv[16];
+ CK_BYTE_PTR pData;
+ CK_ULONG length;
+} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
+
+typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
+
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
+/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pPassword;
+ CK_ULONG ulPublicDataLen;
+ CK_BYTE_PTR pPublicData;
+ CK_ULONG ulPAndGLen;
+ CK_ULONG ulQLen;
+ CK_ULONG ulRandomLen;
+ CK_BYTE_PTR pRandomA;
+ CK_BYTE_PTR pPrimeP;
+ CK_BYTE_PTR pBaseG;
+ CK_BYTE_PTR pSubprimeQ;
+} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
+
+typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
+ CK_SKIPJACK_PRIVATE_WRAP_PTR;
+
+
+/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
+ * CKM_SKIPJACK_RELAYX mechanism */
+/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
+typedef struct CK_SKIPJACK_RELAYX_PARAMS {
+ CK_ULONG ulOldWrappedXLen;
+ CK_BYTE_PTR pOldWrappedX;
+ CK_ULONG ulOldPasswordLen;
+ CK_BYTE_PTR pOldPassword;
+ CK_ULONG ulOldPublicDataLen;
+ CK_BYTE_PTR pOldPublicData;
+ CK_ULONG ulOldRandomLen;
+ CK_BYTE_PTR pOldRandomA;
+ CK_ULONG ulNewPasswordLen;
+ CK_BYTE_PTR pNewPassword;
+ CK_ULONG ulNewPublicDataLen;
+ CK_BYTE_PTR pNewPublicData;
+ CK_ULONG ulNewRandomLen;
+ CK_BYTE_PTR pNewRandomA;
+} CK_SKIPJACK_RELAYX_PARAMS;
+
+typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
+ CK_SKIPJACK_RELAYX_PARAMS_PTR;
+
+
+typedef struct CK_PBE_PARAMS {
+ CK_BYTE_PTR pInitVector;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG ulPasswordLen;
+ CK_BYTE_PTR pSalt;
+ CK_ULONG ulSaltLen;
+ CK_ULONG ulIteration;
+} CK_PBE_PARAMS;
+
+typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
+
+
+/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
+ * CKM_KEY_WRAP_SET_OAEP mechanism */
+/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
+typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
+ CK_BYTE bBC; /* block contents byte */
+ CK_BYTE_PTR pX; /* extra data */
+ CK_ULONG ulXLen; /* length of extra data in bytes */
+} CK_KEY_WRAP_SET_OAEP_PARAMS;
+
+typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
+ CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_SSL3_RANDOM_DATA;
+
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_VERSION_PTR pVersion;
+} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
+
+typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hClientMacSecret;
+ CK_OBJECT_HANDLE hServerMacSecret;
+ CK_OBJECT_HANDLE hClientKey;
+ CK_OBJECT_HANDLE hServerKey;
+ CK_BYTE_PTR pIVClient;
+ CK_BYTE_PTR pIVServer;
+} CK_SSL3_KEY_MAT_OUT;
+
+typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
+
+
+typedef struct CK_SSL3_KEY_MAT_PARAMS {
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_BBOOL bIsExport;
+ CK_SSL3_RANDOM_DATA RandomInfo;
+ CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_SSL3_KEY_MAT_PARAMS;
+
+typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
+
+/* CK_TLS_PRF_PARAMS is new for version 2.20 */
+typedef struct CK_TLS_PRF_PARAMS {
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_TLS_PRF_PARAMS;
+
+typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
+
+/* WTLS is new for version 2.20 */
+typedef struct CK_WTLS_RANDOM_DATA {
+ CK_BYTE_PTR pClientRandom;
+ CK_ULONG ulClientRandomLen;
+ CK_BYTE_PTR pServerRandom;
+ CK_ULONG ulServerRandomLen;
+} CK_WTLS_RANDOM_DATA;
+
+typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
+
+typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_BYTE_PTR pVersion;
+} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
+
+typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
+ CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
+
+typedef struct CK_WTLS_PRF_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_BYTE_PTR pSeed;
+ CK_ULONG ulSeedLen;
+ CK_BYTE_PTR pLabel;
+ CK_ULONG ulLabelLen;
+ CK_BYTE_PTR pOutput;
+ CK_ULONG_PTR pulOutputLen;
+} CK_WTLS_PRF_PARAMS;
+
+typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_OUT {
+ CK_OBJECT_HANDLE hMacSecret;
+ CK_OBJECT_HANDLE hKey;
+ CK_BYTE_PTR pIV;
+} CK_WTLS_KEY_MAT_OUT;
+
+typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
+
+typedef struct CK_WTLS_KEY_MAT_PARAMS {
+ CK_MECHANISM_TYPE DigestMechanism;
+ CK_ULONG ulMacSizeInBits;
+ CK_ULONG ulKeySizeInBits;
+ CK_ULONG ulIVSizeInBits;
+ CK_ULONG ulSequenceNumber;
+ CK_BBOOL bIsExport;
+ CK_WTLS_RANDOM_DATA RandomInfo;
+ CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
+} CK_WTLS_KEY_MAT_PARAMS;
+
+typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
+
+/* CMS is new for version 2.20 */
+typedef struct CK_CMS_SIG_PARAMS {
+ CK_OBJECT_HANDLE certificateHandle;
+ CK_MECHANISM_PTR pSigningMechanism;
+ CK_MECHANISM_PTR pDigestMechanism;
+ CK_UTF8CHAR_PTR pContentType;
+ CK_BYTE_PTR pRequestedAttributes;
+ CK_ULONG ulRequestedAttributesLen;
+ CK_BYTE_PTR pRequiredAttributes;
+ CK_ULONG ulRequiredAttributesLen;
+} CK_CMS_SIG_PARAMS;
+
+typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
+
+typedef struct CK_KEY_DERIVATION_STRING_DATA {
+ CK_BYTE_PTR pData;
+ CK_ULONG ulLen;
+} CK_KEY_DERIVATION_STRING_DATA;
+
+typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
+ CK_KEY_DERIVATION_STRING_DATA_PTR;
+
+
+/* The CK_EXTRACT_PARAMS is used for the
+ * CKM_EXTRACT_KEY_FROM_KEY mechanism. It specifies which bit
+ * of the base key should be used as the first bit of the
+ * derived key */
+/* CK_EXTRACT_PARAMS is new for v2.0 */
+typedef CK_ULONG CK_EXTRACT_PARAMS;
+
+typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
+
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+ CK_UTF8CHAR_PTR pPassword;
+ CK_ULONG_PTR ulPasswordLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/platconfig.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/platconfig.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,97 @@
+/* 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/privatekeyobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,372 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/privatekeyobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/privatekeyobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/publickeyobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,205 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/publickeyobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/publickeyobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,56 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/resource.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/resource.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,15 @@
+//{{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
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsaprivatekeyobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,282 @@
+/*
+ * 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);
+}
+
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsaprivatekeyobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsaprivatekeyobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsapublickeyobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,152 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/rsapublickeyobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/rsapublickeyobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,49 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/sctoken.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,4813 @@
+
+
+#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;
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/sctoken.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sctoken.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,258 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/secretkeyobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,308 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/secretkeyobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/secretkeyobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,61 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/session.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/session.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,604 @@
+/*
+ * 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);
+
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/session.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/session.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/session.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/session.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,144 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/sha1.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,73 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/sha1.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha1.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,39 @@
+/*
+ * 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_sha1_h
+#define _include_sha1_h
+
+#include "MarshallerCfg.h"
+#include "algo_sha1.h"
+
+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);
+
+public:
+ CSHA1();
+ ~CSHA1();
+};
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/sha256.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 "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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/sha256.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/sha256.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,39 @@
+/*
+ * 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_sha256_h
+#define _include_sha256_h
+
+#include "MarshallerCfg.h"
+#include "algo_sha256.h"
+
+class CSHA256 : 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);
+
+public:
+ CSHA256();
+ ~CSHA256();
+};
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/slot.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/slot.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,2949 @@
+/*
+ * 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;
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/slot.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/slot.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,413 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/stdafx.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,41 @@
+/*
+ * 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;
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/stdafx.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/stdafx.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,52 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/storageobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,373 @@
+/*
+ * 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);
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/storageobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/storageobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/symmalgo.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,224 @@
+/*
+ * 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 "symmalgo.h"
+
+CSymmAlgo::CSymmAlgo(){
+ this->_cipherMode = CIPHER_MODE_CBC;
+ this->_paddingMode = PADDING_MODE_PKCS7;
+ this->_iv = NULL_PTR;
+ this->_key = NULL_PTR;
+}
+
+CSymmAlgo::~CSymmAlgo(){
+ if(this->_key != NULL_PTR)
+ free(this->_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::SetIV(CK_BYTE_PTR iv){
+ this->_iv = iv;
+}
+
+void CSymmAlgo::SetEncryptMode(CK_LONG mode){
+ this->_encryptMode = mode;
+}
+
+void CSymmAlgo::SetCipherMode(CK_LONG cmode){
+ this->_cipherMode = cmode;
+}
+
+void CSymmAlgo::SetPaddingMode(CK_LONG pmode){
+ this->_paddingMode = pmode;
+}
+
+CK_LONG CSymmAlgo::GetOutputLength(CK_LONG input_count){
+
+ CK_LONG outputLen;
+
+ if(this->_encryptMode == ENCRYPT){
+ outputLen = input_count & -this->_blockSize;
+
+ switch(this->_paddingMode){
+
+ case PADDING_MODE_ISO9797M2:
+ case PADDING_MODE_PKCS7:
+ // atleast 1 padding byte will be needed
+ if(input_count >= outputLen){
+ outputLen += this->_blockSize;
+ }
+ break;
+
+ case PADDING_MODE_ZEROS:
+ if(input_count > outputLen){
+ outputLen += this->_blockSize;
+ }
+ break;
+
+ case PADDING_MODE_NONE:
+ outputLen = input_count;
+ break;
+ }
+ }else{
+ outputLen = input_count;
+ }
+
+ 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)
+{
+ CK_LONG res = 0;
+ while (res != input_count)
+ {
+ TransformBlockInternal(_iv,_key,_encryptMode,input,input_offset,output,output_offset);
+
+ if (_cipherMode == CIPHER_MODE_CBC)
+ {
+ if (_encryptMode == ENCRYPT){
+ // last block of output becomes icv for next round.
+ memcpy(_iv,&output[output_offset],_blockSize);
+ }
+ else {
+ // last block of input becomes icv for next round.
+ memcpy(_iv,&input[input_offset],_blockSize);
+ }
+ }
+
+ // adjust offsets
+ input_offset += _blockSize;
+ res += _blockSize;
+ output_offset += _blockSize;
+ }
+
+ 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)
+{
+ CK_LONG workingLength;
+
+ if (((this->_paddingMode == PADDING_MODE_NONE) ||
+ (this->_encryptMode == DECRYPT)) &&
+ (input_count % _blockSize != 0))
+ {
+ PKCS11_ASSERT(CK_FALSE);
+ }
+
+ // prepare outbuffer in case of encryption
+ if (this->_encryptMode == ENCRYPT)
+ {
+ // ~ round_down(inputCount, _blockSizeByte)
+ workingLength = input_count & -_blockSize;
+ }
+ else
+ {
+ // we're in Decrypt mode, hence workingLength is % _blockSizeByte
+ workingLength = input_count;
+ }
+
+ if (workingLength > 0)
+ {
+ // compute the workingLength length part (% _blockSizeByte)
+ TransformBlock(input,input_offset, workingLength,output,output_offset);
+
+ input_offset += workingLength;
+ output_offset += workingLength;
+ input_count -= workingLength;
+ }
+
+ if (this->_encryptMode == DECRYPT)
+ {
+ switch (this->_paddingMode)
+ {
+ case PADDING_MODE_PKCS7:
+ // check the padding value make sense
+ if (output[output_offset - 1] > _blockSize){
+ PKCS11_ASSERT(CK_FALSE);
+ }
+ workingLength -= output[output_offset - 1];
+ break;
+
+ case PADDING_MODE_ISO9797M2:
+ // remove trailing zeros
+ while (output[output_offset - 1] == 0x00){
+ workingLength--;
+ output_offset--;
+ }
+ // check initial byte is 0x80
+ if (output[output_offset - 1] != 0x80){
+ PKCS11_ASSERT(CK_FALSE);
+ }
+ workingLength--;
+ break;
+
+ // note when PaddingMode.Zeros is used, we do not remove the 0s (no way to differentiate from the actual data)
+ }
+ }
+ else
+ {
+ if ((this->_paddingMode == PADDING_MODE_PKCS7)
+ || (this->_paddingMode == PADDING_MODE_ISO9797M2)
+ || ((this->_paddingMode == PADDING_MODE_ZEROS) && (input_count > 0)))
+ {
+ CK_BYTE_PTR paddedIntput = (CK_BYTE_PTR)malloc(_blockSize);
+ memset(paddedIntput,0,_blockSize);
+
+ memcpy(paddedIntput,&input[input_offset],input_count);
+
+ // add padding information in buffer if relevant
+ switch (this->_paddingMode)
+ {
+ // set first bit to 1, all other bits already set to 0
+ case PADDING_MODE_ISO9797M2:
+ paddedIntput[input_count] = 0x80;
+ break;
+
+ case PADDING_MODE_PKCS7:
+ CK_BYTE paddingValue = (CK_BYTE)(_blockSize - input_count);
+ for (CK_LONG i = input_count; i < _blockSize; i++){
+ paddedIntput[i] = paddingValue;
+ }
+ break;
+ }
+
+ // compute last block
+ TransformBlock(paddedIntput, 0, _blockSize, output, output_offset);
+
+ workingLength += _blockSize;
+
+ free(paddedIntput);
+ }
+ }
+
+ // over, let's return.
+ return workingLength;
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/symmalgo.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/symmalgo.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,72 @@
+/*
+ * 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_symmalgo_h
+#define _include_symmalgo_h
+
+#define PADDING_MODE_ISO9797M2 1
+#define PADDING_MODE_NONE 2
+#define PADDING_MODE_PKCS7 3
+#define PADDING_MODE_ZEROS 4
+
+#define ENCRYPT 1
+#define DECRYPT 2
+
+#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;
+
+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;
+
+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);
+
+ CK_LONG GetOutputLength(CK_LONG input_count);
+
+ CK_LONG TransformBlock(CK_BYTE_PTR input,CK_LONG input_offset,CK_LONG input_count,
+ CK_BYTE_PTR output,CK_LONG output_offset);
+
+ CK_LONG TransformFinalBlock(CK_BYTE_PTR input,CK_LONG input_offset,CK_LONG input_count,
+ CK_BYTE_PTR output,CK_LONG output_offset);
+};
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/tdes.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -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
+ *
+ */
+#include "stdafx.h"
+#include "platconfig.h"
+#include "symmalgo.h"
+#include "tdes.h"
+
+CTripleDES::CTripleDES(){
+ this->_blockSize = 8;
+}
+
+CTripleDES::~CTripleDES(){
+}
+
+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];
+ }
+ }
+
+ algo_DES_3DESProcess((u1)_keyLength,key,&input[input_offset],&output[output_offset],(u1)encryptMode);
+
+ if(iv != NULL_PTR && this->_encryptMode == DECRYPT){
+ for(CK_LONG i=0;i<8;i++){
+ output[output_offset+i] ^= iv[i];
+ }
+ }
+}
+
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/tdes.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/tdes.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,42 @@
+/*
+ * 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_tdes_h
+#define _include_tdes_h
+
+#include "MarshallerCfg.h"
+#include "algo_des.h"
+
+class CTripleDES : public CSymmAlgo
+{
+
+public:
+ CTripleDES();
+ ~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);
+
+};
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/template.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/template.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,303 @@
+/*
+ * 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;
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/template.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/template.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/template.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/template.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,56 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/thread.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/thread.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,312 @@
+
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/thread.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/thread.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/timer.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/timer.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,49 @@
+/*
+ * 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
+
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/timer.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/timer.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,31 @@
+/*
+ * 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
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/transaction.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,57 @@
+/*
+ * 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(...) {}
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/transaction.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/transaction.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,37 @@
+/*
+ * 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
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/util.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/util.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,373 @@
+/*
+ * 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 "digest.h"
+#include "sha1.h"
+#include "error.h"
+#include "util.h"
+
+R_RANDOM_STRUCT Util::_randomStruct;
+
+void Util::SeedRandom(u1Array const & seed)
+{
+ InitRandomStruct(&_randomStruct);
+ R_RandomUpdate(&_randomStruct, const_cast<unsigned char*>(seed.GetBuffer()), seed.GetLength());
+}
+
+R_RANDOM_STRUCT & Util::RandomStruct()
+{
+ return _randomStruct;
+}
+
+CK_ULONG Util::MakeULong(CK_BYTE_PTR buffer,CK_ULONG offset)
+{
+ 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;
+ }
+
+
+ return CK_TRUE;
+}
+
+CK_BBOOL Util::CompareU1Arrays(u1Array* abuffer,CK_VOID_PTR bbuffer,CK_ULONG len)
+{
+ if((abuffer == NULL_PTR) && (bbuffer == NULL_PTR)){
+ return CK_TRUE;
+ }
+
+ if((abuffer != NULL_PTR) && (bbuffer != NULL_PTR)){
+ if(len == abuffer->GetLength()){
+ return Util::CompareByteArrays(abuffer->GetBuffer(),(CK_BYTE_PTR)bbuffer,len);
+ }
+ }
+
+ return CK_FALSE;
+}
+
+
+CK_BBOOL Util::CompareU4Arrays(u4Array* abuffer,CK_VOID_PTR bbuffer,CK_ULONG len)
+{
+ if((abuffer == NULL_PTR) && (bbuffer == NULL_PTR)){
+ return CK_TRUE;
+ }
+
+ if((abuffer != NULL_PTR) && (bbuffer != NULL_PTR)){
+ if(len == abuffer->GetLength()){
+ return Util::CompareByteArrays((u1*)abuffer->GetBuffer(),(CK_BYTE_PTR)bbuffer,len);
+ }
+ }
+
+ return CK_FALSE;
+}
+
+void Util::PushULongInVector(vector<u1>* to, CK_ULONG value)
+{
+ to->push_back((u1)(value >> 24));
+ to->push_back((u1)(value >> 16));
+ to->push_back((u1)(value >> 8));
+ to->push_back((u1)(value));
+}
+
+void Util::PushULongLongInVector(vector<u1>* to, u8 value)
+{
+ to->push_back((u1)(value >> 56));
+ to->push_back((u1)(value >> 48));
+ to->push_back((u1)(value >> 40));
+ to->push_back((u1)(value >> 32));
+ to->push_back((u1)(value >> 24));
+ to->push_back((u1)(value >> 16));
+ to->push_back((u1)(value >> 8));
+ to->push_back((u1)(value));
+}
+
+void Util::PushBBoolInVector(std::vector<u1>* to, CK_BBOOL value)
+{
+ // push the value
+ 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::PushIntArrayInVector(std::vector<u1>* to, u4Array *value)
+{
+ if((value == NULL_PTR) || value->GetLength() == 0){
+ 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]);
+ }
+ }
+}
+
+u1Array* Util::ReadByteArrayFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+ CK_ULONG len = Util::ReadLengthFromVector(from,idx);
+
+ if(len == 0){
+ return NULL_PTR;
+ }
+
+ u1Array* val = new u1Array(len);
+
+ for(u4 i=0;i<len;i++){
+ val->SetU1At(i,from.at(*idx));
+ *idx = *idx + 1;
+ }
+
+ return val;
+}
+
+u4Array* Util::ReadIntArrayFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+ CK_ULONG len = Util::ReadLengthFromVector(from,idx);
+
+ if(len == 0){
+ return NULL_PTR;
+ }
+
+ u4Array* val = new u4Array(len/4);
+
+ for(u4 i=0;i<(len/4);i++){
+
+ u1 a = from.at(*idx);
+ u1 b = from.at(*idx + 1);
+ u1 c = from.at(*idx + 2);
+ u1 d = from.at(*idx + 3);
+
+ // make an int
+ u4 anInt = (u4)(((u4)a << 24) | ((u4)b << 16) | ((u4)c << 8) | d);
+
+ val->SetU4At(i,anInt);
+
+ *idx = *idx + 4;
+ }
+
+ return val;
+}
+
+void Util::PushLengthInVector(std::vector<u1>* to, CK_USHORT len)
+{
+ if(len < (CK_USHORT)0x80){
+ to->push_back(len & 0x7F);
+ }else if(len <= (CK_USHORT)0xFF){
+ to->push_back(0x81);
+ to->push_back(len & 0xFF);
+ }else{
+ to->push_back(0x82);
+ to->push_back((u1)((len >> 8) & 0x00FF));
+ to->push_back((u1)(len));
+ }
+}
+
+CK_ULONG Util::ReadLengthFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+ CK_USHORT val = (CK_USHORT)from.at(*idx);
+
+ if(val < (CK_USHORT)0x80){
+ *idx = *idx + 1;
+ return val;
+ }else if(val == 0x81){
+ *idx = *idx + 1;
+ val = from.at(*idx);
+ *idx = *idx + 1;
+ return val;
+ }else if(val == 0x82){
+ *idx = *idx + 1;
+ val = (u2)(((u2)from.at(*idx)) << 8);
+ *idx = *idx + 1;
+ val = val | (u2)from.at(*idx);
+ *idx = *idx + 1;
+ return val;
+ }
+
+ PKCS11_ASSERT(CK_FALSE);
+
+ return 0;
+}
+
+CK_BBOOL Util::ReadBBoolFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+ CK_BBOOL val = (CK_BBOOL)from.at(*idx);
+ *idx = *idx + 1;
+
+ return val;
+}
+
+CK_ULONG Util::ReadULongFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+ CK_ULONG offset = *idx;
+
+ CK_ULONG val = (CK_ULONG)(((CK_ULONG)from.at(offset) << 24) | ((CK_ULONG)from.at(offset+1) << 16) | ((CK_ULONG)from.at(offset+2) << 8) | from.at(offset+3));
+
+ *idx = *idx + 4;
+
+ return val;
+}
+
+u8 Util::ReadULongLongFromVector(std::vector<u1> from, CK_ULONG_PTR idx)
+{
+ CK_ULONG offset = *idx;
+
+ u8 val = (u8)(((u8)from.at(offset ) << 56) | ((u8)from.at(offset+1) << 48) |
+ ((u8)from.at(offset+2) << 40) | ((u8)from.at(offset+3) << 32) |
+ ((u8)from.at(offset+4) << 24) | ((u8)from.at(offset+5) << 16) |
+ ((u8)from.at(offset+6) << 8) | from.at(offset+7));
+
+ *idx = *idx + 8;
+
+ return val;
+}
+
+void Util::ConvAscii(u1 *pIn, u4 dwLen,u1 *pOut)
+{
+ #define tohex(x) (((x) >= 0xA) ? ((x) - 0xA + 'A') : ((x) + '0'))
+ register u4 i;
+
+ for(i=0; i < dwLen; i++)
+ {
+ pOut[i*2] = tohex((pIn[i] >> 4) & 0xF);
+ pOut[i*2+1] = tohex(pIn[i] & 0xF);
+ }
+ #undef tohex
+}
+
+char* Util::ItoA(s4 value, char* str, s4 radix)
+{
+
+#ifdef WIN32
+
+ return _itoa(value,str,radix);
+
+#else
+
+ s4 rem = 0;
+ s4 pos = 0;
+ char ch = '!' ;
+
+ do
+ {
+ rem = value % radix ;
+ value /= radix;
+ if ( 16 == radix )
+ {
+ if( rem >= 10 && rem <= 15 )
+ {
+ switch( rem )
+ {
+ case 10:
+ ch = 'a' ;
+ break;
+ case 11:
+ ch ='b' ;
+ break;
+ case 12:
+ ch = 'c' ;
+ break;
+ case 13:
+ ch ='d' ;
+ break;
+ case 14:
+ ch = 'e' ;
+ break;
+ case 15:
+ ch ='f' ;
+ break;
+ }
+ }
+ }
+ if( '!' == ch )
+ {
+ str[pos++] = (char) ( rem + 0x30 );
+ }
+ else
+ {
+ str[pos++] = ch ;
+ }
+ }while( value != 0 );
+
+ str[pos] = '\0' ;
+
+ int i = strlen(str);
+ int t = !(i%2)? 1 : 0; // check the length of the string .
+
+ for(int j = i-1 , k = 0 ; j > (i/2 -t) ; j-- )
+ {
+ char ch2 = str[j];
+ str[j] = str[k];
+ str[k++] = ch2;
+ }
+
+ return str;
+
+#endif
+
+}
+
+u8 Util::MakeCheckValue(const unsigned char * pBuf, unsigned int length)
+{
+ CSHA1 sha1;
+ u1 hash[20];
+ sha1.HashCore(const_cast<unsigned char *>(pBuf), 0, length);
+ sha1.HashFinal(hash);
+ u8 val = 0;
+ for(size_t i = 0; i< sizeof(u8); ++i)
+ val = (val << 8) | hash[i];
+ return val;
+}
+
+u8 Util::MakeUniqueId()
+{
+ unsigned char buf[8];
+ if(R_GenerateBytes(buf, 8, &_randomStruct))
+ throw CkError(CKR_FUNCTION_FAILED);
+ u8 * value = reinterpret_cast<u8*>(buf);
+ return *value;
+}
+
+string Util::MakeIntString(unsigned int number, int width)
+{
+ if(width < 1)
+ return string();
+ char temp[16];
+ sprintf(temp, "%011d", number);
+ string s(temp);
+ return s.substr(s.size()-width, width);
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/util.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/util.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/util.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/util.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,107 @@
+/*
+ * 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_util_h
+#define _include_util_h
+
+#include <string>
+#include <vector>
+
+#include <MarshallerCfg.h>
+#include <Array.h>
+#include <cr_random.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.
+template<class T> class autoarray
+{
+public:
+ autoarray(T* t) : _t(t) {}
+ ~autoarray() { delete [] _t; }
+ T * get() { return _t; }
+ T & operator[](size_t index) { return _t[index]; }
+ const T & operator[](size_t index) const { return _t[index]; }
+
+private:
+ T * _t;
+};
+
+template<typename T> void IntToLittleEndian(T t, unsigned char * buf, size_t offset = 0)
+{
+ size_t n = sizeof(T);
+ for(size_t i = 0; i < n; i++)
+ {
+ buf[offset+i] = static_cast<unsigned char>(t & 0xFF);
+ t >>= 8;
+ }
+}
+
+template<typename T> T LittleEndianToInt(const unsigned char * buf, size_t offset = 0)
+{
+ size_t n = sizeof(T);
+ T t = 0;
+ for(size_t i = 0; i < n; i++)
+ {
+ t <<= 8;
+ t |= buf[offset+n-i-1];
+ }
+ return t;
+}
+
+class Util{
+
+public:
+ static void SeedRandom(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_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);
+
+private:
+ static R_RANDOM_STRUCT _randomStruct;
+
+};
+
+
+#endif
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/x509cert.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,564 @@
+/*
+ * 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 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()
+{
+}
+
+X509Cert::X509Cert(const X509Cert &cert)
+{
+ *this = cert;
+}
+
+X509Cert::X509Cert(const BEROctet::Blob &buffer)
+{
+ *this = buffer;
+}
+
+X509Cert::X509Cert(const unsigned char *buffer, const unsigned long size)
+{
+ m_Cert = BEROctet(BEROctet::Blob(buffer,size));
+ if(size != m_Cert.Octet().size())
+ throw runtime_error("X509CertFormatError");
+
+ Decode();
+}
+
+X509Cert& X509Cert::operator=(const X509Cert &cert)
+{
+ m_Cert = cert.m_Cert;
+ Decode();
+
+ return *this;
+}
+
+X509Cert& X509Cert::operator=(const BEROctet::Blob &buffer)
+{
+ m_Cert = BEROctet(buffer);
+ if(buffer.size() != m_Cert.Octet().size())
+ throw runtime_error("X509CertFormatError");
+ Decode();
+
+ return *this;
+}
+
+// Returns whole DER string of Serial Number.
+
+BEROctet::Blob X509Cert::SerialNumber() const
+{
+ return m_SerialNumber.Octet();
+}
+
+// Returns whole DER string of Issuer
+
+BEROctet::Blob X509Cert::Issuer() const
+{
+ return m_Issuer.Octet();
+}
+
+// Returns whole string of Issuer in UTF8.
+
+BEROctet::Blob X509Cert::UTF8Issuer() const
+{
+ return ToUTF8(m_Issuer.Tag(), m_Issuer.Octet() );
+}
+
+
+// Returns list of attributes in Issuer matching id-at-organizationName.
+// List will be invalidated when object changes.
+
+std::vector<std::string> X509Cert::IssuerOrg() const
+{
+
+ std::vector<std::string> orgNames;
+ std::vector<BEROctet const*> orgOcts;
+
+ 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()));
+
+ 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.
+
+std::vector<std::string> X509Cert::UTF8IssuerOrg() const
+{
+
+ std::vector<std::string> orgNames;
+ std::vector<BEROctet const*> orgOcts;
+
+ 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()));
+ }
+
+ return orgNames;
+}
+
+
+// Returns Validity notBefore attribute as "YYYYMMDDHHMMSS"
+
+string X509Cert::ValidityNotBefore() const
+{
+
+ if(m_Validity.SubOctetList().size()!=2)
+ throw runtime_error("X509CertFormatError");
+
+ return m_Validity.SubOctetList()[0]->Time();
+
+}
+
+// Returns Validity notAfter attribute as "YYYYMMDDHHMMSS"
+
+string X509Cert::ValidityNotAfter() const
+{
+
+ if(m_Validity.SubOctetList().size()!=2)
+ throw runtime_error("X509CertFormatError");
+
+ return m_Validity.SubOctetList()[1]->Time();
+
+}
+
+
+// Returns whole DER string of Subject
+
+BEROctet::Blob X509Cert::Subject() const
+{
+ return m_Subject.Octet();
+}
+
+// Returns Subject in UTF8 format.
+
+BEROctet::Blob X509Cert::UTF8Subject() const
+{
+ return ToUTF8(m_Subject.Tag(), m_Subject.Octet());
+}
+
+// Returns list of attributes in Subject matching id-at-commonName
+// List will be invalidated when object changes.
+
+std::vector<std::string> X509Cert::SubjectCommonName() const
+{
+
+ std::vector<std::string> cnNames;
+ std::vector<BEROctet const*> cnOcts;
+
+ 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()));
+
+ 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::vector<std::string> X509Cert::UTF8SubjectCommonName() const
+{
+
+ std::vector<std::string> cnNames;
+ std::vector<BEROctet const*> cnOcts;
+
+ 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()));
+ }
+
+ return cnNames;
+
+}
+
+// Returns modulus from SubjectPublicKeyInfo, stripped for any leading zero(s).
+
+BEROctet::Blob X509Cert::Modulus() const
+{
+
+ BEROctet::Blob RawMod = RawModulus();
+
+ unsigned long i = 0;
+ while(!RawMod[i] && i<RawMod.size()) i++; // Skip leading zero(s).
+
+ return BEROctet::Blob(&RawMod[i],RawMod.size()-i);
+
+}
+
+// Returns public exponent from SubjectPublicKeyInfo, possibly with leading zero(s).
+
+BEROctet::Blob X509Cert::RawModulus() const
+{
+
+ if(m_SubjectPublicKeyInfo.SubOctetList().size()!=2)
+ throw 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.
+
+
+
+ BEROctet PubKeyOct(KeyBlob.substr(1,BEROctet::Blob::npos));
+
+ if(PubKeyOct.SubOctetList().size()!=2) throw runtime_error("X509CertFormatError");
+
+ return PubKeyOct.SubOctetList()[0]->Data();
+
+}
+
+// Returns public exponent from SubjectPublicKeyInfo, stripped for any leading zero(s).
+
+BEROctet::Blob X509Cert::PublicExponent() const
+{
+
+ BEROctet::Blob RawPubExp = RawPublicExponent();
+
+ unsigned long i = 0;
+ while(!RawPubExp[i] && i<RawPubExp.size()) i++; // Skip leading zero(s).
+
+ return BEROctet::Blob(&RawPubExp[i],RawPubExp.size()-i);
+
+}
+// Returns public exponent from SubjectPublicKeyInfo, possibly with leading zero(s).
+
+BEROctet::Blob X509Cert::RawPublicExponent() const
+{
+
+ if(m_SubjectPublicKeyInfo.SubOctetList().size()!=2)
+ throw 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.
+
+
+ BEROctet PubKeyOct(KeyBlob.substr(1,BEROctet::Blob::npos));
+
+ if(PubKeyOct.SubOctetList().size()!=2) throw runtime_error("X509CertFormatError");
+
+ return PubKeyOct.SubOctetList()[1]->Data();
+
+}
+
+// Returns KeyUsage attribute, left justified with most significant bit as first bit (BER convention)
+
+unsigned long X509Cert::KeyUsage() const
+{
+
+ if(!m_Extensions.Data().size())
+ throw runtime_error("X509CertExtensionNotPresent");
+
+ unsigned long ReturnKeyUsage = 0;
+
+ const unsigned char UnusedBitsMask[] = {0xFF,0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80};
+
+ std::vector<BEROctet const*> ExtensionList;
+
+ m_Extensions.SearchOID(OID_id_ce_keyUsage,ExtensionList);
+
+ if(ExtensionList.size()!=1)
+ throw runtime_error("X509CertExtensionNotPresent"); // One and only one instance
+
+ BEROctet const* Extension = ExtensionList[0];
+ BEROctet* extnValue = 0;
+ if(Extension->SubOctetList().size()==2)
+ extnValue = Extension->SubOctetList()[1]; // No "critical" attribute present
+
+ else if(Extension->SubOctetList().size()==3)
+ extnValue = Extension->SubOctetList()[2]; // A "critical" attribute present
+
+ else
+ throw runtime_error("X509CertFormatError"); // "Extensions" must contain either 2 or 3 octets
+
+ BEROctet KeyUsage(extnValue->Data());
+ BEROctet::Blob KeyUsageBitString = KeyUsage.Data();
+
+ unsigned char UnusedBits = KeyUsageBitString[0];
+ size_t NumBytes = KeyUsageBitString.size()-1;
+ if(NumBytes>4)
+ {
+ NumBytes = 4; // Truncate to fit the ulong, should be plenty though
+ UnusedBits = 0;
+ }
+
+ unsigned long Shift = 24;
+ for(unsigned long i=0; i<NumBytes-1; i++)
+ {
+ ReturnKeyUsage |= (((unsigned long)KeyUsageBitString[i+1]) << Shift);
+ Shift -= 8;
+ }
+
+ ReturnKeyUsage |= ( (KeyUsageBitString[NumBytes] & UnusedBitsMask[UnusedBits]) << Shift );
+
+ return ReturnKeyUsage;
+
+}
+
+bool X509Cert::ExtendedKeyUsage(string const &strOID) const
+{
+ if(!m_Extensions.Data().size())
+ return false;
+
+ vector<BEROctet const*> veku;
+
+ m_Extensions.SearchOIDNext(OID_id_ce_extKeyUsage, veku);
+ if(veku.size() != 1)
+ return false;
+
+ try
+ {
+ BEROctet berEKU(veku[0]->Data());
+ vector<BEROctet const*> ekuOcts;
+ berEKU.SearchOID(strOID,ekuOcts);
+ if(ekuOcts.size() > 0)
+ return true;
+ else
+ return false;
+ }
+ catch(...)
+ {
+ return false;
+ }
+}
+
+bool X509Cert::IsCACert() const
+{
+ return m_bCACert;
+}
+
+bool X509Cert::IsRootCert() const
+{
+ return m_bRootCert;
+}
+
+void X509Cert::Decode()
+{
+
+ const unsigned int dwTagVersion = 0;
+ //const unsigned int dwTagIssuerUniqueID = 1;
+ //const unsigned int dwTagSubjectUniqueID = 2;
+ const unsigned int dwTagExtensions = 3;
+
+ if(m_Cert.SubOctetList().size()!=3) throw runtime_error("X509CertFormatError");
+
+ BEROctet *tbsCert = m_Cert.SubOctetList()[0];
+ size_t Size = tbsCert->SubOctetList().size();
+ if(!Size) throw 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");
+
+ m_SerialNumber = *(tbsCert->SubOctetList()[i]); i++; // SerialNumber
+ i++; // Signature (algorithm)
+ m_Issuer = *(tbsCert->SubOctetList()[i]); i++; // Issuer
+ m_Validity = *(tbsCert->SubOctetList()[i]); i++; // Validity
+ m_Subject = *(tbsCert->SubOctetList()[i]); i++; // Subject
+ m_SubjectPublicKeyInfo = *(tbsCert->SubOctetList()[i]); i++; // SubjectPublicKeyInfo
+
+ m_Extensions = BEROctet();
+ while(i<Size) {
+ BEROctet *oct = tbsCert->SubOctetList()[i];
+ if((oct->Class()==tcContext) && (oct->Tag()==dwTagExtensions)) {
+ m_Extensions = *oct;
+ break;
+ }
+ i++;
+ }
+
+ m_bCACert = false;
+ std::vector<BEROctet const*> ExtensionList;
+ m_Extensions.SearchOID(OID_id_ce_basicConstraints, ExtensionList);
+
+
+ if(1 == ExtensionList.size())
+ {
+ BEROctet const* Extension = ExtensionList[0];
+ BEROctet* extnValue = 0;
+ if(Extension->SubOctetList().size()==2)
+ extnValue = Extension->SubOctetList()[1]; // No "critical" attribute present
+
+ else if(Extension->SubOctetList().size()==3)
+ extnValue = Extension->SubOctetList()[2]; // A "critical" attribute present
+
+ if (extnValue)
+ {
+ BEROctet BasicContrainsts(extnValue->Data());
+ std::vector<BEROctet*> bcMembers(BasicContrainsts.SubOctetList());
+ if(bcMembers.size()>0 && bcMembers[0]->Tag() == dwBerUnivBool)
+ {
+ BEROctet::Blob flag(bcMembers[0]->Data());
+ if(flag.size()==1)
+ m_bCACert = flag[0] ? true : false;
+ }
+ }
+ }
+
+ m_bRootCert = false;
+ if (Issuer() == Subject())
+ {
+ m_bRootCert = true;
+ }
+}
+
+
+BEROctet::Blob X509Cert::ToUTF8( unsigned int dwTag, const BEROctet::Blob &blbData ) const
+{
+ BEROctet::Blob blbReturn;
+ size_t cUnicode = 0;
+ bool bConvert = false;
+ switch(dwTag)
+ {
+ case dwBerBMPString:
+ //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.
+ //this is hardly used but we never know.
+ cUnicode = 4;
+ bConvert = true;
+ break;
+ default:
+ //return as is.
+ blbReturn = blbData;
+ }
+
+ if(bConvert)
+ {
+ unsigned char bAppend = 0;
+ for(size_t i = 0; i < blbData.size() / cUnicode; i++ )
+ {
+ unsigned int dwUnicode = 0;
+ unsigned int dwTemp = 0;
+ int nBytesInUTF8 = 0;
+
+ //first get the Unicode unsigned int from BIG ENDIAN BYTES.
+ for(size_t j = 0; j < cUnicode; j++)
+ {
+ dwTemp = blbData.at(i*cUnicode + j);
+ dwUnicode += dwTemp << (8*(cUnicode-(j+1)));
+ }
+
+ //now calculate the number of bytes required to represent
+ // the unicode value in UTF8
+ if( dwUnicode <= 0x0000007F )
+ {
+ nBytesInUTF8 = 1;
+ }
+ else if( dwUnicode <= 0x000007FF )
+ {
+ nBytesInUTF8 = 2;
+ }
+ else if( dwUnicode <= 0x0000FFFF )
+ {
+ nBytesInUTF8 = 3;
+ }
+ else if( dwUnicode <= 0x001FFFFF )
+ {
+ nBytesInUTF8 = 4;
+ }
+ else if( dwUnicode <= 0x03FFFFFF )
+ {
+ nBytesInUTF8 = 5;
+ }
+ else if( dwUnicode <= 0x7FFFFFFF )
+ {
+ nBytesInUTF8 = 6;
+ }
+
+ //The bitwise & code is 0x7F (7 bits) when there is only one byte
+ // Otherwise the & code is 0x3f ( 6 bits)
+ // when there are more that one UTF8 bytes required,
+ // Ideally the MS unsigned char has to be & with less than 6 bits,
+ // but it does not matter since the other bits
+ // will be zero, so it is safe to & 6 bits.
+
+ unsigned char bBitWiseAndCode = 0x3f;
+ if( nBytesInUTF8 == 1)
+ {
+ bBitWiseAndCode = 0x7f;
+ }
+
+
+ // Shift in the multiples of 6 starting with maximum.
+ // This way the MSB will be appended first and then the rest.
+ // Add to MS Byte the bits which indicates number of bytes coded for UTF8
+ // for all other bytes add 0x80.
+ for( int k = nBytesInUTF8 - 1; k >= 0; k--)
+ {
+ unsigned char bytAdd = 0;
+ if( nBytesInUTF8 > 1 )
+ {
+ if( k == nBytesInUTF8 - 1 )
+ {
+ bytAdd = ( 0xFF << (8 - nBytesInUTF8 ) );
+ }
+ else
+ {
+ bytAdd = 0x80;
+ }
+
+ }
+ bAppend = static_cast<unsigned char>( ((dwUnicode >> k*6) & bBitWiseAndCode));
+ bAppend += bytAdd;
+ blbReturn.append( &bAppend, 1);
+ }
+ }
+ //append the NULL char.
+ bAppend = 0;
+ blbReturn.append( &bAppend, 1);
+ }
+ return blbReturn;
+}
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/x509cert.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509cert.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,95 @@
+/*
+ * 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
+
+#include <string>
+#include <vector>
+
+#include "beroctet.h"
+
+class X509Cert
+{
+
+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);
+
+ 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;
+
+private:
+ void Decode();
+
+ 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;
+
+
+};
+
+// Key Usage flags from X.509 spec
+
+const unsigned long digitalSignature = 0x80000000;
+const unsigned long nonRepudiation = 0x40000000;
+const unsigned long keyEncipherment = 0x20000000;
+const unsigned long dataEncipherment = 0x10000000;
+const unsigned long keyAgreement = 0x08000000;
+const unsigned long keyCertSign = 0x04000000;
+const unsigned long cRLSign = 0x02000000;
+const unsigned long encipherOnly = 0x01000000;
+const unsigned long decipherOnly = 0x00800000;
+
+
+#endif //_include_x509cert_h
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/x509pubkeycertobject.cpp)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.cpp 2012-02-20 13:52:47 UTC (rev 140)
@@ -0,0 +1,265 @@
+/*
+ * 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);
+
+}
+
Copied: trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h (from rev 139, trunk/SmartCardServices/src/PKCS11dotNetV2/PKCS11Module2/x509pubkeycertobject.h)
===================================================================
--- trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h (rev 0)
+++ trunk/SmartCardServices/src/PKCS11dotNetV2/x509pubkeycertobject.h 2012-02-20 13:52:47 UTC (rev 140)
@@ -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 _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/c4e06147/attachment-0001.html>
More information about the SmartcardServices-Changes
mailing list