jdk/src/share/native/sun/security/pkcs11/wrapper/p11_general.c
changeset 2 90ce3da70b43
child 2180 9994f4f08a59
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_general.c	Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,841 @@
+/*
+ * Portions Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ */
+
+/* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
+ *
+ * Redistribution and use in  source and binary forms, with or without
+ * modification, are permitted  provided that the following conditions are met:
+ *
+ * 1. Redistributions of  source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in  binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if any, must
+ *    include the following acknowledgment:
+ *
+ *    "This product includes software developed by IAIK of Graz University of
+ *     Technology."
+ *
+ *    Alternately, this acknowledgment may appear in the software itself, if
+ *    and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Graz University of Technology" and "IAIK of Graz University of
+ *    Technology" must not be used to endorse or promote products derived from
+ *    this software without prior written permission.
+ *
+ * 5. Products derived from this software may not be called
+ *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
+ *    written permission of Graz University of Technology.
+ *
+ *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
+ *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
+ *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *  POSSIBILITY  OF SUCH DAMAGE.
+ */
+
+#include "pkcs11wrapper.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "sun_security_pkcs11_wrapper_PKCS11.h"
+
+/* declare file private functions */
+
+void prefetchFields(JNIEnv *env, jclass thisClass);
+jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo);
+jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo);
+jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo);
+jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo);
+
+/* define variables */
+
+jfieldID pNativeDataID;
+jfieldID mech_mechanismID;
+jfieldID mech_pParameterID;
+
+jclass jByteArrayClass;
+jclass jLongClass;
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
+    return JNI_VERSION_1_4;
+}
+
+/* ************************************************************************** */
+/* The native implementation of the methods of the PKCS11Implementation class */
+/* ************************************************************************** */
+
+/*
+ * This method is used to do static initialization. This method is static and
+ * synchronized. Summary: use this method like a static initialization block.
+ *
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    initializeLibrary
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary
+(JNIEnv *env, jclass thisClass)
+{
+#ifndef NO_CALLBACKS
+    if (notifyListLock == NULL) {
+        notifyListLock = createLockObject(env);
+    }
+#endif
+
+    prefetchFields(env, thisClass);
+}
+
+jclass fetchClass(JNIEnv *env, const char *name) {
+    jclass tmpClass = (*env)->FindClass(env, name);
+    return (*env)->NewGlobalRef(env, tmpClass);
+}
+
+void prefetchFields(JNIEnv *env, jclass thisClass) {
+    jclass tmpClass;
+
+    /* PKCS11 */
+    pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J");
+
+    /* CK_MECHANISM */
+    tmpClass = (*env)->FindClass(env, CLASS_MECHANISM);
+    mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J");
+    mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter",
+                                           "Ljava/lang/Object;");
+
+    jByteArrayClass = fetchClass(env, "[B");
+    jLongClass = fetchClass(env, "java/lang/Long");
+}
+
+/* This method is designed to do a clean-up. It releases all global resources
+ * of this library. By now, this function is not called. Calling from
+ * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload.
+ *
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    finalizeLibrary
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary
+(JNIEnv *env, jclass thisClass)
+{
+/* XXX
+    * remove all left lists and release the resources and the lock
+     * objects that synchroniz access to these lists.
+     *
+    removeAllModuleEntries(env);
+    if (moduleListHead == NULL) { * check, if we removed the last active module *
+        * remove also the moduleListLock, it is no longer used *
+        if (moduleListLock != NULL) {
+            destroyLockObject(env, moduleListLock);
+            moduleListLock = NULL;
+        }
+#ifndef NO_CALLBACKS
+        * remove all left notify callback entries *
+        while (removeFirstNotifyEntry(env));
+        * remove also the notifyListLock, it is no longer used *
+        if (notifyListLock != NULL) {
+            destroyLockObject(env, notifyListLock);
+            notifyListLock = NULL;
+        }
+        if (jInitArgsObject != NULL) {
+            (*env)->DeleteGlobalRef(env, jInitArgsObject);
+        }
+        if (ckpGlobalInitArgs != NULL_PTR) {
+            free(ckpGlobalInitArgs);
+        }
+#endif * NO_CALLBACKS *
+    }
+*/
+}
+
+#ifdef P11_ENABLE_C_INITIALIZE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Initialize
+ * Signature: (Ljava/lang/Object;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jobject jInitArgs           CK_VOID_PTR pInitArgs
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize
+(JNIEnv *env, jobject obj, jobject jInitArgs)
+{
+    /*
+     * Initalize Cryptoki
+     */
+    CK_C_INITIALIZE_ARGS_PTR ckpInitArgs;
+    CK_RV rv;
+    CK_FUNCTION_LIST_PTR ckpFunctions;
+
+    TRACE0("DEBUG: initializing module... ");
+
+    ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) {
+        TRACE0("failed getting module entry");
+        return;
+    }
+
+    ckpInitArgs = (jInitArgs != NULL)
+                ? makeCKInitArgsAdapter(env, jInitArgs)
+                : NULL_PTR;
+
+    rv = (*ckpFunctions->C_Initialize)(ckpInitArgs);
+
+    free(ckpInitArgs);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+
+    TRACE0("FINISHED\n");
+}
+#endif
+
+#ifdef P11_ENABLE_C_FINALIZE
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_Finalize
+ * Signature: (Ljava/lang/Object;)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jobject jReserved           CK_VOID_PTR pReserved
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize
+(JNIEnv *env, jobject obj, jobject jReserved)
+{
+    /*
+     * Finalize Cryptoki
+     */
+    CK_VOID_PTR ckpReserved;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckpReserved = jObjectToCKVoidPtr(jReserved);
+
+    rv = (*ckpFunctions->C_Finalize)(ckpReserved);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetInfo
+ * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @return  jobject jInfoObject         CK_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo
+(JNIEnv *env, jobject obj)
+{
+    CK_INFO ckLibInfo;
+    jobject jInfoObject;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo);
+
+    return jInfoObject ;
+}
+
+/*
+ * converts a pointer to a CK_INFO structure into a Java CK_INFO Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpInfo - the pointer to the CK_INFO structure
+ * @return - the new Java CK_INFO object
+ */
+jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo)
+{
+    jclass jInfoClass;
+    jmethodID jCtrId;
+    jobject jInfoObject;
+    jobject jCryptokiVer;
+    jcharArray jVendor;
+    jlong jFlags;
+    jcharArray jLibraryDesc;
+    jobject jLibraryVer;
+
+    /* load CK_INFO class */
+    jInfoClass = (*env)->FindClass(env, CLASS_INFO);
+    assert(jInfoClass != 0);
+
+    /* load CK_INFO constructor */
+    jCtrId = (*env)->GetMethodID
+      (env, jInfoClass, "<init>",
+       "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V");
+
+    assert(jCtrId != 0);
+
+    /* prep all fields */
+    jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion));
+    jVendor =
+      ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32);
+    jFlags = ckULongToJLong(ckpInfo->flags);
+    jLibraryDesc =
+      ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32);
+    jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion));
+
+    /* create new CK_INFO object */
+    jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer,
+                                    jVendor, jFlags, jLibraryDesc, jLibraryVer);
+    assert(jInfoObject != 0);
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jInfoClass);
+    (*env)->DeleteLocalRef(env, jCryptokiVer);
+    (*env)->DeleteLocalRef(env, jVendor);
+    (*env)->DeleteLocalRef(env, jLibraryDesc);
+    (*env)->DeleteLocalRef(env, jLibraryVer);
+
+    return jInfoObject ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETSLOTLIST
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetSlotList
+ * Signature: (Z)[J
+ * Parametermapping:                    *PKCS11*
+ * @param   jboolean jTokenPresent      CK_BBOOL tokenPresent
+ * @return  jlongArray jSlotList        CK_SLOT_ID_PTR pSlotList
+ *                                      CK_ULONG_PTR pulCount
+ */
+JNIEXPORT jlongArray JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList
+(JNIEnv *env, jobject obj, jboolean jTokenPresent)
+{
+    CK_ULONG ckTokenNumber;
+    CK_SLOT_ID_PTR ckpSlotList;
+    CK_BBOOL ckTokenPresent;
+    jlongArray jSlotList;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckTokenPresent = jBooleanToCKBBool(jTokenPresent);
+
+    rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR,
+                                        &ckTokenNumber);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID));
+
+    rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList,
+                                        &ckTokenNumber);
+
+    jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber);
+    free(ckpSlotList);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    return jSlotList ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETSLOTINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetSlotInfo
+ * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @return  jobject jSlotInfoObject     CK_SLOT_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo
+(JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_SLOT_INFO ckSlotInfo;
+    jobject jSlotInfoObject;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo);
+
+    return jSlotInfoObject ;
+}
+
+/*
+ * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO
+ * Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure
+ * @return - the new Java CK_SLOT_INFO object
+ */
+jobject
+ckSlotInfoPtrToJSlotInfo
+(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo)
+{
+    jclass jSlotInfoClass;
+    jmethodID jCtrId;
+    jobject jSlotInfoObject;
+    jcharArray jSlotDesc;
+    jcharArray jVendor;
+    jlong jFlags;
+    jobject jHardwareVer;
+    jobject jFirmwareVer;
+
+    /* load CK_SLOT_INFO class */
+    jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO);
+    assert(jSlotInfoClass != 0);
+
+    /* load CK_SLOT_INFO constructor */
+    jCtrId = (*env)->GetMethodID
+      (env, jSlotInfoClass, "<init>",
+       "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V");
+    assert(jCtrId != 0);
+
+    /* prep all fields */
+    jSlotDesc =
+      ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64);
+    jVendor =
+      ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32);
+    jFlags = ckULongToJLong(ckpSlotInfo->flags);
+    jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion));
+    jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion));
+
+    /* create new CK_SLOT_INFO object */
+    jSlotInfoObject = (*env)->NewObject
+      (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags,
+       jHardwareVer, jFirmwareVer);
+    assert(jSlotInfoObject != 0);
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jSlotInfoClass);
+    (*env)->DeleteLocalRef(env, jSlotDesc);
+    (*env)->DeleteLocalRef(env, jVendor);
+    (*env)->DeleteLocalRef(env, jHardwareVer);
+    (*env)->DeleteLocalRef(env, jFirmwareVer);
+
+    return jSlotInfoObject ;
+}
+
+#endif
+
+#ifdef P11_ENABLE_C_GETTOKENINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetTokenInfo
+ * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @return  jobject jInfoTokenObject    CK_TOKEN_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo
+(JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_TOKEN_INFO ckTokenInfo;
+    jobject jInfoTokenObject;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo);
+
+    return jInfoTokenObject ;
+}
+
+/*
+ * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO
+ * Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure
+ * @return - the new Java CK_TOKEN_INFO object
+ */
+jobject
+ckTokenInfoPtrToJTokenInfo
+(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo)
+{
+    jclass jTokenInfoClass;
+    jmethodID jCtrId;
+    jobject jTokenInfoObject;
+    jcharArray jLabel;
+    jcharArray jVendor;
+    jcharArray jModel;
+    jcharArray jSerialNo;
+    jlong jFlags;
+    jlong jMaxSnCnt;
+    jlong jSnCnt;
+    jlong jMaxRwSnCnt;
+    jlong jRwSnCnt;
+    jlong jMaxPinLen;
+    jlong jMinPinLen;
+    jlong jTotalPubMem;
+    jlong jFreePubMem;
+    jlong jTotalPrivMem;
+    jlong jFreePrivMem;
+    jobject jHardwareVer;
+    jobject jFirmwareVer;
+    jcharArray jUtcTime;
+
+    /* load CK_TOKEN_INFO class */
+    jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO);
+    assert(jTokenInfoClass != 0);
+
+    /* load CK_TOKEN_INFO constructor */
+    jCtrId = (*env)->GetMethodID
+      (env, jTokenInfoClass, "<init>",
+       "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V");
+    assert(jCtrId != 0);
+
+    /* prep all fields */
+    jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32);
+    jVendor =
+      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32);
+    jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16);
+    jSerialNo =
+      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16);
+    jFlags = ckULongToJLong(ckpTokenInfo->flags);
+    jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount);
+    jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount);
+    jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount);
+    jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount);
+    jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen);
+    jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen);
+    jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory);
+    jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory);
+    jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory);
+    jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory);
+    jHardwareVer =
+      ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion));
+    jFirmwareVer =
+      ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion));
+    jUtcTime =
+      ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16);
+
+    /* create new CK_TOKEN_INFO object */
+    jTokenInfoObject =
+      (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel,
+                        jSerialNo, jFlags,
+                        jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt,
+                        jMaxPinLen, jMinPinLen,
+                        jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem,
+                        jHardwareVer, jFirmwareVer, jUtcTime);
+    assert(jTokenInfoObject != 0);
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jTokenInfoClass);
+    (*env)->DeleteLocalRef(env, jLabel);
+    (*env)->DeleteLocalRef(env, jVendor);
+    (*env)->DeleteLocalRef(env, jModel);
+    (*env)->DeleteLocalRef(env, jSerialNo);
+    (*env)->DeleteLocalRef(env, jHardwareVer);
+    (*env)->DeleteLocalRef(env, jFirmwareVer);
+
+    return jTokenInfoObject ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_WAITFORSLOTEVENT
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_WaitForSlotEvent
+ * Signature: (JLjava/lang/Object;)J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jFlags                CK_FLAGS flags
+ * @param   jobject jReserved           CK_VOID_PTR pReserved
+ * @return  jlong jSlotID               CK_SLOT_ID_PTR pSlot
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent
+(JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved)
+{
+    CK_FLAGS ckFlags;
+    CK_SLOT_ID ckSlotID;
+    jlong jSlotID;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return 0L; }
+
+    ckFlags = jLongToCKULong(jFlags);
+
+    rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L; }
+
+    jSlotID = ckULongToJLong(ckSlotID);
+
+    return jSlotID ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETMECHANISMLIST
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetMechanismList
+ * Signature: (J)[J
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @return  jlongArray jMechanismList   CK_MECHANISM_TYPE_PTR pMechanismList
+ *                                      CK_ULONG_PTR pulCount
+ */
+JNIEXPORT jlongArray JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList
+(JNIEnv *env, jobject obj, jlong jSlotID)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_ULONG ckMechanismNumber;
+    CK_MECHANISM_TYPE_PTR ckpMechanismList;
+    jlongArray jMechanismList;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+
+    rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR,
+                                             &ckMechanismNumber);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    ckpMechanismList = (CK_MECHANISM_TYPE_PTR)
+      malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE));
+
+    rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList,
+                                             &ckMechanismNumber);
+
+    jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList,
+                                              ckMechanismNumber);
+    free(ckpMechanismList);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    return jMechanismList ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_GETMECHANISMINFO
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_GetMechanismInfo
+ * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO;
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @param   jlong jType                 CK_MECHANISM_TYPE type
+ * @return  jobject jMechanismInfo      CK_MECHANISM_INFO_PTR pInfo
+ */
+JNIEXPORT jobject JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo
+(JNIEnv *env, jobject obj, jlong jSlotID, jlong jType)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_MECHANISM_TYPE ckMechanismType;
+    CK_MECHANISM_INFO ckMechanismInfo;
+    jobject jMechanismInfo;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return NULL; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+    ckMechanismType = jLongToCKULong(jType);
+
+    rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType,
+                                             &ckMechanismInfo);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; }
+
+    jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo);
+
+    return jMechanismInfo ;
+}
+
+/*
+ * converts a pointer to a CK_MECHANISM_INFO structure into a Java
+ * CK_MECHANISM_INFO Object.
+ *
+ * @param env - used to call JNI funktions to create the new Java object
+ * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure
+ * @return - the new Java CK_MECHANISM_INFO object
+ */
+jobject
+ckMechanismInfoPtrToJMechanismInfo
+(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo)
+{
+
+    jclass jMechanismInfoClass;
+    jmethodID jCtrId;
+    jobject jMechanismInfoObject;
+    jlong jMinKeySize;
+    jlong jMaxKeySize;
+    jlong jFlags;
+
+    /* load CK_MECHANISM_INFO class */
+    jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO);
+    assert(jMechanismInfoClass != 0);
+
+    /* load CK_MECHANISM_INFO constructor */
+    jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "<init>", "(JJJ)V");
+    assert(jCtrId != 0);
+
+    /* prep all fields */
+    jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize);
+    jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize);
+    jFlags = ckULongToJLong(ckpMechanismInfo->flags);
+
+    /* create new CK_MECHANISM_INFO object */
+    jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId,
+                                             jMinKeySize, jMaxKeySize, jFlags);
+    assert(jMechanismInfoObject != 0);
+
+    /* free local references */
+    (*env)->DeleteLocalRef(env, jMechanismInfoClass);
+
+    return jMechanismInfoObject ;
+}
+#endif
+
+#ifdef P11_ENABLE_C_INITTOKEN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_InitToken
+ * Signature: (J[C[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSlotID               CK_SLOT_ID slotID
+ * @param   jcharArray jPin             CK_CHAR_PTR pPin
+ *                                      CK_ULONG ulPinLen
+ * @param   jcharArray jLabel           CK_UTF8CHAR_PTR pLabel
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken
+(JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel)
+{
+    CK_SLOT_ID ckSlotID;
+    CK_CHAR_PTR ckpPin = NULL_PTR;
+    CK_UTF8CHAR_PTR ckpLabel = NULL_PTR;
+    CK_ULONG ckPinLength;
+    CK_ULONG ckLabelLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSlotID = jLongToCKULong(jSlotID);
+    jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
+    jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength);
+    /* ckLabelLength <= 32 !!! */
+
+    rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel);
+    TRACE1("InitToken return code: %d", rv);
+
+    free(ckpPin);
+    free(ckpLabel);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_INITPIN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_InitPIN
+ * Signature: (J[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE
+ * @param   jcharArray jPin             CK_CHAR_PTR pPin
+ *                                      CK_ULONG ulPinLen
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN
+(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_CHAR_PTR ckpPin = NULL_PTR;
+    CK_ULONG ckPinLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength);
+
+    rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength);
+
+    free(ckpPin);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif
+
+#ifdef P11_ENABLE_C_SETPIN
+/*
+ * Class:     sun_security_pkcs11_wrapper_PKCS11
+ * Method:    C_SetPIN
+ * Signature: (J[C[C)V
+ * Parametermapping:                    *PKCS11*
+ * @param   jlong jSessionHandle        CK_SESSION_HANDLE hSession
+ * @param   jcharArray jOldPin          CK_CHAR_PTR pOldPin
+ *                                      CK_ULONG ulOldLen
+ * @param   jcharArray jNewPin          CK_CHAR_PTR pNewPin
+ *                                      CK_ULONG ulNewLen
+ */
+JNIEXPORT void JNICALL
+Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN
+(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin,
+jcharArray jNewPin)
+{
+    CK_SESSION_HANDLE ckSessionHandle;
+    CK_CHAR_PTR ckpOldPin = NULL_PTR;
+    CK_CHAR_PTR ckpNewPin = NULL_PTR;
+    CK_ULONG ckOldPinLength;
+    CK_ULONG ckNewPinLength;
+    CK_RV rv;
+
+    CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj);
+    if (ckpFunctions == NULL) { return; }
+
+    ckSessionHandle = jLongToCKULong(jSessionHandle);
+    jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength);
+    jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength);
+
+    rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength,
+                                   ckpNewPin, ckNewPinLength);
+
+    free(ckpOldPin);
+    free(ckpNewPin);
+
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+}
+#endif