jdk/src/jdk.crypto.token/share/native/libj2pkcs11/p11_util.c
changeset 42693 6645de32a866
parent 40563 4bff68330f39
equal deleted inserted replaced
42692:97247477b481 42693:6645de32a866
       
     1 /*
       
     2  * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  */
       
     4 
       
     5 /* Copyright  (c) 2002 Graz University of Technology. All rights reserved.
       
     6  *
       
     7  * Redistribution and use in  source and binary forms, with or without
       
     8  * modification, are permitted  provided that the following conditions are met:
       
     9  *
       
    10  * 1. Redistributions of  source code must retain the above copyright notice,
       
    11  *    this list of conditions and the following disclaimer.
       
    12  *
       
    13  * 2. Redistributions in  binary form must reproduce the above copyright notice,
       
    14  *    this list of conditions and the following disclaimer in the documentation
       
    15  *    and/or other materials provided with the distribution.
       
    16  *
       
    17  * 3. The end-user documentation included with the redistribution, if any, must
       
    18  *    include the following acknowledgment:
       
    19  *
       
    20  *    "This product includes software developed by IAIK of Graz University of
       
    21  *     Technology."
       
    22  *
       
    23  *    Alternately, this acknowledgment may appear in the software itself, if
       
    24  *    and wherever such third-party acknowledgments normally appear.
       
    25  *
       
    26  * 4. The names "Graz University of Technology" and "IAIK of Graz University of
       
    27  *    Technology" must not be used to endorse or promote products derived from
       
    28  *    this software without prior written permission.
       
    29  *
       
    30  * 5. Products derived from this software may not be called
       
    31  *    "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior
       
    32  *    written permission of Graz University of Technology.
       
    33  *
       
    34  *  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
       
    35  *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
    36  *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
       
    37  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE
       
    38  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
       
    39  *  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
       
    40  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
       
    41  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
       
    42  *  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
       
    43  *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
       
    44  *  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
       
    45  *  POSSIBILITY  OF SUCH DAMAGE.
       
    46  */
       
    47 
       
    48 #include "pkcs11wrapper.h"
       
    49 
       
    50 #include <stdio.h>
       
    51 #include <stdlib.h>
       
    52 #include <string.h>
       
    53 #include <assert.h>
       
    54 
       
    55 /* declare file private functions */
       
    56 
       
    57 ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation);
       
    58 int isModulePresent(JNIEnv *env, jobject pkcs11Implementation);
       
    59 void removeAllModuleEntries(JNIEnv *env);
       
    60 
       
    61 
       
    62 /* ************************************************************************** */
       
    63 /* Functions for keeping track of currently active and loaded modules         */
       
    64 /* ************************************************************************** */
       
    65 
       
    66 
       
    67 /*
       
    68  * Create a new object for locking.
       
    69  */
       
    70 jobject createLockObject(JNIEnv *env) {
       
    71     jclass jObjectClass;
       
    72     jobject jLockObject;
       
    73     jmethodID jConstructor;
       
    74 
       
    75     jObjectClass = (*env)->FindClass(env, "java/lang/Object");
       
    76     if (jObjectClass == NULL) { return NULL; }
       
    77     jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");
       
    78     if (jConstructor == NULL) { return NULL; }
       
    79     jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);
       
    80     if (jLockObject == NULL) { return NULL; }
       
    81     jLockObject = (*env)->NewGlobalRef(env, jLockObject);
       
    82 
       
    83     return jLockObject ;
       
    84 }
       
    85 
       
    86 /*
       
    87  * Create a new object for locking.
       
    88  */
       
    89 void destroyLockObject(JNIEnv *env, jobject jLockObject) {
       
    90     if (jLockObject != NULL) {
       
    91         (*env)->DeleteGlobalRef(env, jLockObject);
       
    92     }
       
    93 }
       
    94 
       
    95 /*
       
    96  * Add the given pkcs11Implementation object to the list of present modules.
       
    97  * Attach the given data to the entry. If the given pkcs11Implementation is
       
    98  * already in the lsit, just override its old module data with the new one.
       
    99  * None of the arguments can be NULL. If one of the arguments is NULL, this
       
   100  * function does nothing.
       
   101  */
       
   102 void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {
       
   103     if (pkcs11Implementation == NULL_PTR) {
       
   104         return ;
       
   105     }
       
   106     if (moduleData == NULL) {
       
   107         return ;
       
   108     }
       
   109     (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, ptr_to_jlong(moduleData));
       
   110 }
       
   111 
       
   112 
       
   113 /*
       
   114  * Get the module data of the entry for the given pkcs11Implementation. Returns
       
   115  * NULL, if the pkcs11Implementation is not in the list.
       
   116  */
       
   117 ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
       
   118     jlong jData;
       
   119     if (pkcs11Implementation == NULL) {
       
   120         return NULL;
       
   121     }
       
   122     jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID);
       
   123     return (ModuleData*)jlong_to_ptr(jData);
       
   124 }
       
   125 
       
   126 CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) {
       
   127     ModuleData *moduleData;
       
   128     CK_FUNCTION_LIST_PTR ckpFunctions;
       
   129 
       
   130     moduleData = getModuleEntry(env, pkcs11Implementation);
       
   131     if (moduleData == NULL) {
       
   132         throwDisconnectedRuntimeException(env);
       
   133         return NULL;
       
   134     }
       
   135     ckpFunctions = moduleData->ckFunctionListPtr;
       
   136     return ckpFunctions;
       
   137 }
       
   138 
       
   139 
       
   140 /*
       
   141  * Returns 1, if the given pkcs11Implementation is in the list.
       
   142  * 0, otherwise.
       
   143  */
       
   144 int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {
       
   145     int present;
       
   146 
       
   147     ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
       
   148 
       
   149     present = (moduleData != NULL) ? 1 : 0;
       
   150 
       
   151     return present ;
       
   152 }
       
   153 
       
   154 
       
   155 /*
       
   156  * Removes the entry for the given pkcs11Implementation from the list. Returns
       
   157  * the module's data, after the node was removed. If this function returns NULL
       
   158  * the pkcs11Implementation was not in the list.
       
   159  */
       
   160 ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {
       
   161     ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);
       
   162     if (moduleData == NULL) {
       
   163         return NULL;
       
   164     }
       
   165     (*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, 0);
       
   166     return moduleData;
       
   167 }
       
   168 
       
   169 /*
       
   170  * Removes all present entries from the list of modules and frees all
       
   171  * associated resources. This function is used for clean-up.
       
   172  */
       
   173 void removeAllModuleEntries(JNIEnv *env) {
       
   174     /* XXX empty */
       
   175 }
       
   176 
       
   177 /* ************************************************************************** */
       
   178 /* Below there follow the helper functions to support conversions between     */
       
   179 /* Java and Cryptoki types                                                    */
       
   180 /* ************************************************************************** */
       
   181 
       
   182 /*
       
   183  * function to convert a PKCS#11 return value into a PKCS#11Exception
       
   184  *
       
   185  * This function generates a PKCS#11Exception with the returnValue as the errorcode
       
   186  * if the returnValue is not CKR_OK. The functin returns 0, if the returnValue is
       
   187  * CKR_OK. Otherwise, it returns the returnValue as a jLong.
       
   188  *
       
   189  * @param env - used to call JNI funktions and to get the Exception class
       
   190  * @param returnValue - of the PKCS#11 function
       
   191  */
       
   192 jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue)
       
   193 {
       
   194     jclass jPKCS11ExceptionClass;
       
   195     jmethodID jConstructor;
       
   196     jthrowable jPKCS11Exception;
       
   197     jlong jErrorCode = 0L;
       
   198 
       
   199     if (returnValue != CKR_OK) {
       
   200         jErrorCode = ckULongToJLong(returnValue);
       
   201         jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);
       
   202         if (jPKCS11ExceptionClass != NULL) {
       
   203             jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass, "<init>", "(J)V");
       
   204             if (jConstructor != NULL) {
       
   205                 jPKCS11Exception = (jthrowable) (*env)->NewObject(env, jPKCS11ExceptionClass, jConstructor, jErrorCode);
       
   206                 if (jPKCS11Exception != NULL) {
       
   207                     (*env)->Throw(env, jPKCS11Exception);
       
   208                 }
       
   209             }
       
   210         }
       
   211         (*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);
       
   212     }
       
   213     return jErrorCode ;
       
   214 }
       
   215 
       
   216 
       
   217 /*
       
   218  * Throws a Java Exception by name
       
   219  */
       
   220 void throwByName(JNIEnv *env, const char *name, const char *msg)
       
   221 {
       
   222     jclass cls = (*env)->FindClass(env, name);
       
   223 
       
   224     if (cls != 0) /* Otherwise an exception has already been thrown */
       
   225         (*env)->ThrowNew(env, cls, msg);
       
   226 }
       
   227 
       
   228 /*
       
   229  * Throws java.lang.OutOfMemoryError
       
   230  */
       
   231 void throwOutOfMemoryError(JNIEnv *env, const char *msg)
       
   232 {
       
   233     throwByName(env, "java/lang/OutOfMemoryError", msg);
       
   234 }
       
   235 
       
   236 /*
       
   237  * Throws java.lang.NullPointerException
       
   238  */
       
   239 void throwNullPointerException(JNIEnv *env, const char *msg)
       
   240 {
       
   241     throwByName(env, "java/lang/NullPointerException", msg);
       
   242 }
       
   243 
       
   244 /*
       
   245  * Throws java.io.IOException
       
   246  */
       
   247 void throwIOException(JNIEnv *env, const char *msg)
       
   248 {
       
   249     throwByName(env, "java/io/IOException", msg);
       
   250 }
       
   251 
       
   252 /*
       
   253  * This function simply throws a PKCS#11RuntimeException with the given
       
   254  * string as its message.
       
   255  *
       
   256  * @param env Used to call JNI funktions and to get the Exception class.
       
   257  * @param jmessage The message string of the Exception object.
       
   258  */
       
   259 void throwPKCS11RuntimeException(JNIEnv *env, const char *message)
       
   260 {
       
   261     throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message);
       
   262 }
       
   263 
       
   264 /*
       
   265  * This function simply throws a PKCS#11RuntimeException. The message says that
       
   266  * the object is not connected to the module.
       
   267  *
       
   268  * @param env Used to call JNI funktions and to get the Exception class.
       
   269  */
       
   270 void throwDisconnectedRuntimeException(JNIEnv *env)
       
   271 {
       
   272     throwPKCS11RuntimeException(env, "This object is not connected to a module.");
       
   273 }
       
   274 
       
   275 /* This function frees the specified CK_ATTRIBUTE array.
       
   276  *
       
   277  * @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array.
       
   278  * @param len the length of the array
       
   279  */
       
   280 void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len)
       
   281 {
       
   282     int i;
       
   283 
       
   284     for (i=0; i<len; i++) {
       
   285         if (attrPtr[i].pValue != NULL_PTR) {
       
   286             free(attrPtr[i].pValue);
       
   287         }
       
   288     }
       
   289     free(attrPtr);
       
   290 }
       
   291 
       
   292 /*
       
   293  * the following functions convert Java arrays to PKCS#11 array pointers and
       
   294  * their array length and vice versa
       
   295  *
       
   296  * void j<Type>ArrayToCK<Type>Array(JNIEnv *env,
       
   297  *                                  const j<Type>Array jArray,
       
   298  *                                  CK_<Type>_PTR *ckpArray,
       
   299  *                                  CK_ULONG_PTR ckLength);
       
   300  *
       
   301  * j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env,
       
   302  *                                          const CK_<Type>_PTR ckpArray,
       
   303  *                                          CK_ULONG ckLength);
       
   304  *
       
   305  * PKCS#11 arrays consist always of a pointer to the beginning of the array and
       
   306  * the array length whereas Java arrays carry their array length.
       
   307  *
       
   308  * The Functions to convert a Java array to a PKCS#11 array are void functions.
       
   309  * Their arguments are the Java array object to convert, the reference to the
       
   310  * array pointer, where the new PKCS#11 array should be stored and the reference
       
   311  * to the array length where the PKCS#11 array length should be stored. These two
       
   312  * references must not be NULL_PTR.
       
   313  *
       
   314  * The functions first obtain the array length of the Java array and then allocate
       
   315  * the memory for the PKCS#11 array and set the array length. Then each element
       
   316  * gets converted depending on their type. After use the allocated memory of the
       
   317  * PKCS#11 array has to be explicitly freed.
       
   318  *
       
   319  * The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array
       
   320  * pointer and the array length and they return the new Java array object. The
       
   321  * Java array does not need to get freed after use.
       
   322  */
       
   323 
       
   324 /*
       
   325  * converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use!
       
   326  *
       
   327  * @param env - used to call JNI funktions to get the array informtaion
       
   328  * @param jArray - the Java array to convert
       
   329  * @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored
       
   330  * @param ckpLength - the reference, where the array length will be stored
       
   331  */
       
   332 void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)
       
   333 {
       
   334     jboolean* jpTemp;
       
   335     CK_ULONG i;
       
   336 
       
   337     if(jArray == NULL) {
       
   338         *ckpArray = NULL_PTR;
       
   339         *ckpLength = 0L;
       
   340         return;
       
   341     }
       
   342     *ckpLength = (*env)->GetArrayLength(env, jArray);
       
   343     jpTemp = (jboolean*) malloc((*ckpLength) * sizeof(jboolean));
       
   344     if (jpTemp == NULL) {
       
   345         throwOutOfMemoryError(env, 0);
       
   346         return;
       
   347     }
       
   348     (*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
       
   349     if ((*env)->ExceptionCheck(env)) {
       
   350         free(jpTemp);
       
   351         return;
       
   352     }
       
   353 
       
   354     *ckpArray = (CK_BBOOL*) malloc ((*ckpLength) * sizeof(CK_BBOOL));
       
   355     if (*ckpArray == NULL) {
       
   356         free(jpTemp);
       
   357         throwOutOfMemoryError(env, 0);
       
   358         return;
       
   359     }
       
   360     for (i=0; i<(*ckpLength); i++) {
       
   361         (*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);
       
   362     }
       
   363     free(jpTemp);
       
   364 }
       
   365 
       
   366 /*
       
   367  * converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use!
       
   368  *
       
   369  * @param env - used to call JNI funktions to get the array informtaion
       
   370  * @param jArray - the Java array to convert
       
   371  * @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored
       
   372  * @param ckpLength - the reference, where the array length will be stored
       
   373  */
       
   374 void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
       
   375 {
       
   376     jbyte* jpTemp;
       
   377     CK_ULONG i;
       
   378 
       
   379     if(jArray == NULL) {
       
   380         *ckpArray = NULL_PTR;
       
   381         *ckpLength = 0L;
       
   382         return;
       
   383     }
       
   384     *ckpLength = (*env)->GetArrayLength(env, jArray);
       
   385     jpTemp = (jbyte*) malloc((*ckpLength) * sizeof(jbyte));
       
   386     if (jpTemp == NULL) {
       
   387         throwOutOfMemoryError(env, 0);
       
   388         return;
       
   389     }
       
   390     (*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
       
   391     if ((*env)->ExceptionCheck(env)) {
       
   392         free(jpTemp);
       
   393         return;
       
   394     }
       
   395 
       
   396     /* if CK_BYTE is the same size as jbyte, we save an additional copy */
       
   397     if (sizeof(CK_BYTE) == sizeof(jbyte)) {
       
   398         *ckpArray = (CK_BYTE_PTR) jpTemp;
       
   399     } else {
       
   400         *ckpArray = (CK_BYTE_PTR) malloc ((*ckpLength) * sizeof(CK_BYTE));
       
   401         if (*ckpArray == NULL) {
       
   402             free(jpTemp);
       
   403             throwOutOfMemoryError(env, 0);
       
   404             return;
       
   405         }
       
   406         for (i=0; i<(*ckpLength); i++) {
       
   407             (*ckpArray)[i] = jByteToCKByte(jpTemp[i]);
       
   408         }
       
   409         free(jpTemp);
       
   410     }
       
   411 }
       
   412 
       
   413 /*
       
   414  * converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use!
       
   415  *
       
   416  * @param env - used to call JNI funktions to get the array informtaion
       
   417  * @param jArray - the Java array to convert
       
   418  * @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored
       
   419  * @param ckpLength - the reference, where the array length will be stored
       
   420  */
       
   421 void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)
       
   422 {
       
   423     jlong* jTemp;
       
   424     CK_ULONG i;
       
   425 
       
   426     if(jArray == NULL) {
       
   427         *ckpArray = NULL_PTR;
       
   428         *ckpLength = 0L;
       
   429         return;
       
   430     }
       
   431     *ckpLength = (*env)->GetArrayLength(env, jArray);
       
   432     jTemp = (jlong*) malloc((*ckpLength) * sizeof(jlong));
       
   433     if (jTemp == NULL) {
       
   434         throwOutOfMemoryError(env, 0);
       
   435         return;
       
   436     }
       
   437     (*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp);
       
   438     if ((*env)->ExceptionCheck(env)) {
       
   439         free(jTemp);
       
   440         return;
       
   441     }
       
   442 
       
   443     *ckpArray = (CK_ULONG_PTR) malloc (*ckpLength * sizeof(CK_ULONG));
       
   444     if (*ckpArray == NULL) {
       
   445         free(jTemp);
       
   446         throwOutOfMemoryError(env, 0);
       
   447         return;
       
   448     }
       
   449     for (i=0; i<(*ckpLength); i++) {
       
   450         (*ckpArray)[i] = jLongToCKULong(jTemp[i]);
       
   451     }
       
   452     free(jTemp);
       
   453 }
       
   454 
       
   455 /*
       
   456  * converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use!
       
   457  *
       
   458  * @param env - used to call JNI funktions to get the array informtaion
       
   459  * @param jArray - the Java array to convert
       
   460  * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
       
   461  * @param ckpLength - the reference, where the array length will be stored
       
   462  */
       
   463 void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
       
   464 {
       
   465     jchar* jpTemp;
       
   466     CK_ULONG i;
       
   467 
       
   468     if(jArray == NULL) {
       
   469         *ckpArray = NULL_PTR;
       
   470         *ckpLength = 0L;
       
   471         return;
       
   472     }
       
   473     *ckpLength = (*env)->GetArrayLength(env, jArray);
       
   474     jpTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
       
   475     if (jpTemp == NULL) {
       
   476         throwOutOfMemoryError(env, 0);
       
   477         return;
       
   478     }
       
   479     (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);
       
   480     if ((*env)->ExceptionCheck(env)) {
       
   481         free(jpTemp);
       
   482         return;
       
   483     }
       
   484 
       
   485     *ckpArray = (CK_CHAR_PTR) malloc (*ckpLength * sizeof(CK_CHAR));
       
   486     if (*ckpArray == NULL) {
       
   487         free(jpTemp);
       
   488         throwOutOfMemoryError(env, 0);
       
   489         return;
       
   490     }
       
   491     for (i=0; i<(*ckpLength); i++) {
       
   492         (*ckpArray)[i] = jCharToCKChar(jpTemp[i]);
       
   493     }
       
   494     free(jpTemp);
       
   495 }
       
   496 
       
   497 /*
       
   498  * converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use!
       
   499  *
       
   500  * @param env - used to call JNI funktions to get the array informtaion
       
   501  * @param jArray - the Java array to convert
       
   502  * @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored
       
   503  * @param ckpLength - the reference, where the array length will be stored
       
   504  */
       
   505 void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
       
   506 {
       
   507     jchar* jTemp;
       
   508     CK_ULONG i;
       
   509 
       
   510     if(jArray == NULL) {
       
   511         *ckpArray = NULL_PTR;
       
   512         *ckpLength = 0L;
       
   513         return;
       
   514     }
       
   515     *ckpLength = (*env)->GetArrayLength(env, jArray);
       
   516     jTemp = (jchar*) malloc((*ckpLength) * sizeof(jchar));
       
   517     if (jTemp == NULL) {
       
   518         throwOutOfMemoryError(env, 0);
       
   519         return;
       
   520     }
       
   521     (*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp);
       
   522     if ((*env)->ExceptionCheck(env)) {
       
   523         free(jTemp);
       
   524         return;
       
   525     }
       
   526 
       
   527     *ckpArray = (CK_UTF8CHAR_PTR) malloc (*ckpLength * sizeof(CK_UTF8CHAR));
       
   528     if (*ckpArray == NULL) {
       
   529         free(jTemp);
       
   530         throwOutOfMemoryError(env, 0);
       
   531         return;
       
   532     }
       
   533     for (i=0; i<(*ckpLength); i++) {
       
   534         (*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]);
       
   535     }
       
   536     free(jTemp);
       
   537 }
       
   538 
       
   539 /*
       
   540  * converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use!
       
   541  *
       
   542  * @param env - used to call JNI funktions to get the array informtaion
       
   543  * @param jArray - the Java array to convert
       
   544  * @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored
       
   545  * @param ckpLength - the reference, where the array length will be stored
       
   546  */
       
   547 void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)
       
   548 {
       
   549     const char* pCharArray;
       
   550     jboolean isCopy;
       
   551 
       
   552     if(jArray == NULL) {
       
   553         *ckpArray = NULL_PTR;
       
   554         *ckpLength = 0L;
       
   555         return;
       
   556     }
       
   557 
       
   558     pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);
       
   559     if (pCharArray == NULL) { return; }
       
   560 
       
   561     *ckpLength = (CK_ULONG) strlen(pCharArray);
       
   562     *ckpArray = (CK_UTF8CHAR_PTR) malloc((*ckpLength + 1) * sizeof(CK_UTF8CHAR));
       
   563     if (*ckpArray == NULL) {
       
   564         (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
       
   565         throwOutOfMemoryError(env, 0);
       
   566         return;
       
   567     }
       
   568     strcpy((char*)*ckpArray, pCharArray);
       
   569     (*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);
       
   570 }
       
   571 
       
   572 /*
       
   573  * converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory
       
   574  * has to be freed after use!
       
   575  *
       
   576  * @param env - used to call JNI funktions to get the array informtaion
       
   577  * @param jArray - the Java Attribute array (template) to convert
       
   578  * @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be
       
   579  *                   stored
       
   580  * @param ckpLength - the reference, where the array length will be stored
       
   581  */
       
   582 void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)
       
   583 {
       
   584     CK_ULONG i;
       
   585     jlong jLength;
       
   586     jobject jAttribute;
       
   587 
       
   588     TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray");
       
   589     if (jArray == NULL) {
       
   590         *ckpArray = NULL_PTR;
       
   591         *ckpLength = 0L;
       
   592         return;
       
   593     }
       
   594     jLength = (*env)->GetArrayLength(env, jArray);
       
   595     *ckpLength = jLongToCKULong(jLength);
       
   596     *ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE));
       
   597     if (*ckpArray == NULL) {
       
   598         throwOutOfMemoryError(env, 0);
       
   599         return;
       
   600     }
       
   601     TRACE1(", converting %d attributes", jLength);
       
   602     for (i=0; i<(*ckpLength); i++) {
       
   603         TRACE1(", getting %d. attribute", i);
       
   604         jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
       
   605         if ((*env)->ExceptionCheck(env)) {
       
   606             freeCKAttributeArray(*ckpArray, i);
       
   607             return;
       
   608         }
       
   609         TRACE1(", jAttribute = %d", jAttribute);
       
   610         TRACE1(", converting %d. attribute", i);
       
   611         (*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
       
   612         if ((*env)->ExceptionCheck(env)) {
       
   613             freeCKAttributeArray(*ckpArray, i);
       
   614             return;
       
   615         }
       
   616     }
       
   617     TRACE0("FINISHED\n");
       
   618 }
       
   619 
       
   620 /*
       
   621  * converts a CK_BYTE array and its length to a jbyteArray.
       
   622  *
       
   623  * @param env - used to call JNI funktions to create the new Java array
       
   624  * @param ckpArray - the pointer to the CK_BYTE array to convert
       
   625  * @param ckpLength - the length of the array to convert
       
   626  * @return - the new Java byte array or NULL if error occurred
       
   627  */
       
   628 jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)
       
   629 {
       
   630     CK_ULONG i;
       
   631     jbyte* jpTemp;
       
   632     jbyteArray jArray;
       
   633 
       
   634     /* if CK_BYTE is the same size as jbyte, we save an additional copy */
       
   635     if (sizeof(CK_BYTE) == sizeof(jbyte)) {
       
   636         jpTemp = (jbyte*) ckpArray;
       
   637     } else {
       
   638         jpTemp = (jbyte*) malloc((ckLength) * sizeof(jbyte));
       
   639         if (jpTemp == NULL) {
       
   640             throwOutOfMemoryError(env, 0);
       
   641             return NULL;
       
   642         }
       
   643         for (i=0; i<ckLength; i++) {
       
   644             jpTemp[i] = ckByteToJByte(ckpArray[i]);
       
   645         }
       
   646     }
       
   647 
       
   648     jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));
       
   649     if (jArray != NULL) {
       
   650         (*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
       
   651     }
       
   652 
       
   653     if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); }
       
   654 
       
   655     return jArray ;
       
   656 }
       
   657 
       
   658 /*
       
   659  * converts a CK_ULONG array and its length to a jlongArray.
       
   660  *
       
   661  * @param env - used to call JNI funktions to create the new Java array
       
   662  * @param ckpArray - the pointer to the CK_ULONG array to convert
       
   663  * @param ckpLength - the length of the array to convert
       
   664  * @return - the new Java long array
       
   665  */
       
   666 jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)
       
   667 {
       
   668     CK_ULONG i;
       
   669     jlong* jpTemp;
       
   670     jlongArray jArray;
       
   671 
       
   672     jpTemp = (jlong*) malloc((ckLength) * sizeof(jlong));
       
   673     if (jpTemp == NULL) {
       
   674         throwOutOfMemoryError(env, 0);
       
   675         return NULL;
       
   676     }
       
   677     for (i=0; i<ckLength; i++) {
       
   678         jpTemp[i] = ckLongToJLong(ckpArray[i]);
       
   679     }
       
   680     jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));
       
   681     if (jArray != NULL) {
       
   682         (*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
       
   683     }
       
   684     free(jpTemp);
       
   685 
       
   686     return jArray ;
       
   687 }
       
   688 
       
   689 /*
       
   690  * converts a CK_CHAR array and its length to a jcharArray.
       
   691  *
       
   692  * @param env - used to call JNI funktions to create the new Java array
       
   693  * @param ckpArray - the pointer to the CK_CHAR array to convert
       
   694  * @param ckpLength - the length of the array to convert
       
   695  * @return - the new Java char array
       
   696  */
       
   697 jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)
       
   698 {
       
   699     CK_ULONG i;
       
   700     jchar* jpTemp;
       
   701     jcharArray jArray;
       
   702 
       
   703     jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
       
   704     if (jpTemp == NULL) {
       
   705         throwOutOfMemoryError(env, 0);
       
   706         return NULL;
       
   707     }
       
   708     for (i=0; i<ckLength; i++) {
       
   709         jpTemp[i] = ckCharToJChar(ckpArray[i]);
       
   710     }
       
   711     jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
       
   712     if (jArray != NULL) {
       
   713         (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
       
   714     }
       
   715     free(jpTemp);
       
   716 
       
   717     return jArray ;
       
   718 }
       
   719 
       
   720 /*
       
   721  * converts a CK_UTF8CHAR array and its length to a jcharArray.
       
   722  *
       
   723  * @param env - used to call JNI funktions to create the new Java array
       
   724  * @param ckpArray - the pointer to the CK_UTF8CHAR array to convert
       
   725  * @param ckpLength - the length of the array to convert
       
   726  * @return - the new Java char array
       
   727  */
       
   728 jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)
       
   729 {
       
   730     CK_ULONG i;
       
   731     jchar* jpTemp;
       
   732     jcharArray jArray;
       
   733 
       
   734     jpTemp = (jchar*) malloc(ckLength * sizeof(jchar));
       
   735     if (jpTemp == NULL) {
       
   736         throwOutOfMemoryError(env, 0);
       
   737         return NULL;
       
   738     }
       
   739     for (i=0; i<ckLength; i++) {
       
   740         jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);
       
   741     }
       
   742     jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));
       
   743     if (jArray != NULL) {
       
   744         (*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);
       
   745     }
       
   746     free(jpTemp);
       
   747 
       
   748     return jArray ;
       
   749 }
       
   750 
       
   751 /*
       
   752  * the following functions convert Java objects to PKCS#11 pointers and the
       
   753  * length in bytes and vice versa
       
   754  *
       
   755  * CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject);
       
   756  *
       
   757  * jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue);
       
   758  *
       
   759  * The functions that convert a Java object to a PKCS#11 pointer first allocate
       
   760  * the memory for the PKCS#11 pointer. Then they set each element corresponding
       
   761  * to the fields in the Java object to convert. After use the allocated memory of
       
   762  * the PKCS#11 pointer has to be explicitly freed.
       
   763  *
       
   764  * The functions to convert a PKCS#11 pointer to a Java object create a new Java
       
   765  * object first and than they set all fields in the object depending on the values
       
   766  * of the type or structure where the PKCS#11 pointer points to.
       
   767  */
       
   768 
       
   769 /*
       
   770  * converts a CK_BBOOL pointer to a Java boolean Object.
       
   771  *
       
   772  * @param env - used to call JNI funktions to create the new Java object
       
   773  * @param ckpValue - the pointer to the CK_BBOOL value
       
   774  * @return - the new Java boolean object with the boolean value
       
   775  */
       
   776 jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)
       
   777 {
       
   778     jclass jValueObjectClass;
       
   779     jmethodID jConstructor;
       
   780     jobject jValueObject;
       
   781     jboolean jValue;
       
   782 
       
   783     jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
       
   784     if (jValueObjectClass == NULL) { return NULL; }
       
   785     jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");
       
   786     if (jConstructor == NULL) { return NULL; }
       
   787     jValue = ckBBoolToJBoolean(*ckpValue);
       
   788     jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
       
   789 
       
   790     return jValueObject ;
       
   791 }
       
   792 
       
   793 /*
       
   794  * converts a CK_ULONG pointer to a Java long Object.
       
   795  *
       
   796  * @param env - used to call JNI funktions to create the new Java object
       
   797  * @param ckpValue - the pointer to the CK_ULONG value
       
   798  * @return - the new Java long object with the long value
       
   799  */
       
   800 jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)
       
   801 {
       
   802     jclass jValueObjectClass;
       
   803     jmethodID jConstructor;
       
   804     jobject jValueObject;
       
   805     jlong jValue;
       
   806 
       
   807     jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");
       
   808     if (jValueObjectClass == NULL) { return NULL; }
       
   809     jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");
       
   810     if (jConstructor == NULL) { return NULL; }
       
   811     jValue = ckULongToJLong(*ckpValue);
       
   812     jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);
       
   813 
       
   814     return jValueObject ;
       
   815 }
       
   816 
       
   817 /*
       
   818  * converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be
       
   819  * freed after use!
       
   820  *
       
   821  * @param env - used to call JNI funktions to get the value out of the Java object
       
   822  * @param jObject - the "java/lang/Boolean" object to convert
       
   823  * @return - the pointer to the new CK_BBOOL value
       
   824  */
       
   825 CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)
       
   826 {
       
   827     jclass jObjectClass;
       
   828     jmethodID jValueMethod;
       
   829     jboolean jValue;
       
   830     CK_BBOOL *ckpValue;
       
   831 
       
   832     jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");
       
   833     if (jObjectClass == NULL) { return NULL; }
       
   834     jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");
       
   835     if (jValueMethod == NULL) { return NULL; }
       
   836     jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);
       
   837     ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));
       
   838     if (ckpValue == NULL) {
       
   839         throwOutOfMemoryError(env, 0);
       
   840         return NULL;
       
   841     }
       
   842     *ckpValue = jBooleanToCKBBool(jValue);
       
   843 
       
   844     return ckpValue ;
       
   845 }
       
   846 
       
   847 /*
       
   848  * converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be
       
   849  * freed after use!
       
   850  *
       
   851  * @param env - used to call JNI funktions to get the value out of the Java object
       
   852  * @param jObject - the "java/lang/Byte" object to convert
       
   853  * @return - the pointer to the new CK_BYTE value
       
   854  */
       
   855 CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)
       
   856 {
       
   857     jclass jObjectClass;
       
   858     jmethodID jValueMethod;
       
   859     jbyte jValue;
       
   860     CK_BYTE_PTR ckpValue;
       
   861 
       
   862     jObjectClass = (*env)->FindClass(env, "java/lang/Byte");
       
   863     if (jObjectClass == NULL) { return NULL; }
       
   864     jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");
       
   865     if (jValueMethod == NULL) { return NULL; }
       
   866     jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);
       
   867     ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));
       
   868     if (ckpValue == NULL) {
       
   869         throwOutOfMemoryError(env, 0);
       
   870         return NULL;
       
   871     }
       
   872     *ckpValue = jByteToCKByte(jValue);
       
   873     return ckpValue ;
       
   874 }
       
   875 
       
   876 /*
       
   877  * converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be
       
   878  * freed after use!
       
   879  *
       
   880  * @param env - used to call JNI funktions to get the value out of the Java object
       
   881  * @param jObject - the "java/lang/Integer" object to convert
       
   882  * @return - the pointer to the new CK_ULONG value
       
   883  */
       
   884 CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)
       
   885 {
       
   886     jclass jObjectClass;
       
   887     jmethodID jValueMethod;
       
   888     jint jValue;
       
   889     CK_ULONG *ckpValue;
       
   890 
       
   891     jObjectClass = (*env)->FindClass(env, "java/lang/Integer");
       
   892     if (jObjectClass == NULL) { return NULL; }
       
   893     jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");
       
   894     if (jValueMethod == NULL) { return NULL; }
       
   895     jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);
       
   896     ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
       
   897     if (ckpValue == NULL) {
       
   898         throwOutOfMemoryError(env, 0);
       
   899         return NULL;
       
   900     }
       
   901     *ckpValue = jLongToCKLong(jValue);
       
   902     return ckpValue ;
       
   903 }
       
   904 
       
   905 /*
       
   906  * converts a Java long object into a pointer to a CK_ULONG value. The memory has to be
       
   907  * freed after use!
       
   908  *
       
   909  * @param env - used to call JNI funktions to get the value out of the Java object
       
   910  * @param jObject - the "java/lang/Long" object to convert
       
   911  * @return - the pointer to the new CK_ULONG value
       
   912  */
       
   913 CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)
       
   914 {
       
   915     jclass jObjectClass;
       
   916     jmethodID jValueMethod;
       
   917     jlong jValue;
       
   918     CK_ULONG *ckpValue;
       
   919 
       
   920     jObjectClass = (*env)->FindClass(env, "java/lang/Long");
       
   921     if (jObjectClass == NULL) { return NULL; }
       
   922     jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");
       
   923     if (jValueMethod == NULL) { return NULL; }
       
   924     jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);
       
   925     ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));
       
   926     if (ckpValue == NULL) {
       
   927         throwOutOfMemoryError(env, 0);
       
   928         return NULL;
       
   929     }
       
   930     *ckpValue = jLongToCKULong(jValue);
       
   931 
       
   932     return ckpValue ;
       
   933 }
       
   934 
       
   935 /*
       
   936  * converts a Java char object into a pointer to a CK_CHAR value. The memory has to be
       
   937  * freed after use!
       
   938  *
       
   939  * @param env - used to call JNI funktions to get the value out of the Java object
       
   940  * @param jObject - the "java/lang/Char" object to convert
       
   941  * @return - the pointer to the new CK_CHAR value
       
   942  */
       
   943 CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)
       
   944 {
       
   945     jclass jObjectClass;
       
   946     jmethodID jValueMethod;
       
   947     jchar jValue;
       
   948     CK_CHAR_PTR ckpValue;
       
   949 
       
   950     jObjectClass = (*env)->FindClass(env, "java/lang/Char");
       
   951     if (jObjectClass == NULL) { return NULL; }
       
   952     jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");
       
   953     if (jValueMethod == NULL) { return NULL; }
       
   954     jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);
       
   955     ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));
       
   956     if (ckpValue == NULL) {
       
   957         throwOutOfMemoryError(env, 0);
       
   958         return NULL;
       
   959     }
       
   960     *ckpValue = jCharToCKChar(jValue);
       
   961 
       
   962     return ckpValue ;
       
   963 }
       
   964 
       
   965 /*
       
   966  * converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes.
       
   967  * The memory of *ckpObjectPtr to be freed after use! This function is only used by
       
   968  * jAttributeToCKAttribute by now.
       
   969  *
       
   970  * @param env - used to call JNI funktions to get the Java classes and objects
       
   971  * @param jObject - the Java object to convert
       
   972  * @param ckpObjectPtr - the reference of the new pointer to the new CK-value or CK-structure
       
   973  * @param ckpLength - the reference of the length in bytes of the new CK-value or CK-structure
       
   974  */
       
   975 void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *ckpLength)
       
   976 {
       
   977     jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass;
       
   978     jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass;
       
   979     jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass;
       
   980     jclass jStringClass;
       
   981     jclass jObjectClass, jClassClass;
       
   982     CK_VOID_PTR ckpVoid = *ckpObjectPtr;
       
   983     jmethodID jMethod;
       
   984     jobject jClassObject;
       
   985     jstring jClassNameString;
       
   986     char *classNameString, *exceptionMsgPrefix, *exceptionMsg;
       
   987 
       
   988     TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtrPtr");
       
   989     if (jObject == NULL) {
       
   990         *ckpObjectPtr = NULL;
       
   991         *ckpLength = 0;
       
   992         return;
       
   993     }
       
   994 
       
   995     jLongClass = (*env)->FindClass(env, "java/lang/Long");
       
   996     if (jLongClass == NULL) { return; }
       
   997     if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {
       
   998         *ckpObjectPtr = jLongObjectToCKULongPtr(env, jObject);
       
   999         *ckpLength = sizeof(CK_ULONG);
       
  1000         TRACE1("<converted long value %X>", *((CK_ULONG *) *ckpObjectPtr));
       
  1001         return;
       
  1002     }
       
  1003 
       
  1004     jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean");
       
  1005     if (jBooleanClass == NULL) { return; }
       
  1006     if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {
       
  1007         *ckpObjectPtr = jBooleanObjectToCKBBoolPtr(env, jObject);
       
  1008         *ckpLength = sizeof(CK_BBOOL);
       
  1009         TRACE0(" <converted boolean value ");
       
  1010         TRACE0((*((CK_BBOOL *) *ckpObjectPtr) == TRUE) ? "TRUE>" : "FALSE>");
       
  1011         return;
       
  1012     }
       
  1013 
       
  1014     jByteArrayClass = (*env)->FindClass(env, "[B");
       
  1015     if (jByteArrayClass == NULL) { return; }
       
  1016     if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {
       
  1017         jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*)ckpObjectPtr, ckpLength);
       
  1018         return;
       
  1019     }
       
  1020 
       
  1021     jCharArrayClass = (*env)->FindClass(env, "[C");
       
  1022     if (jCharArrayClass == NULL) { return; }
       
  1023     if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {
       
  1024         jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
       
  1025         return;
       
  1026     }
       
  1027 
       
  1028     jByteClass = (*env)->FindClass(env, "java/lang/Byte");
       
  1029     if (jByteClass == NULL) { return; }
       
  1030     if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {
       
  1031         *ckpObjectPtr = jByteObjectToCKBytePtr(env, jObject);
       
  1032         *ckpLength = sizeof(CK_BYTE);
       
  1033         TRACE1("<converted byte value %X>", *((CK_BYTE *) *ckpObjectPtr));
       
  1034         return;
       
  1035     }
       
  1036 
       
  1037     jDateClass = (*env)->FindClass(env, CLASS_DATE);
       
  1038     if (jDateClass == NULL) { return; }
       
  1039     if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {
       
  1040         *ckpObjectPtr = jDateObjectPtrToCKDatePtr(env, jObject);
       
  1041         *ckpLength = sizeof(CK_DATE);
       
  1042         TRACE3("<converted date value %.4s-%.2s-%.2s>", (*((CK_DATE *) *ckpObjectPtr)).year, (*((CK_DATE *) *ckpObjectPtr)).month, (*((CK_DATE *) *ckpObjectPtr)).day);
       
  1043         return;
       
  1044     }
       
  1045 
       
  1046     jCharacterClass = (*env)->FindClass(env, "java/lang/Character");
       
  1047     if (jCharacterClass == NULL) { return; }
       
  1048     if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {
       
  1049         *ckpObjectPtr = jCharObjectToCKCharPtr(env, jObject);
       
  1050         *ckpLength = sizeof(CK_UTF8CHAR);
       
  1051         TRACE1("<converted char value %c>", *((CK_CHAR *) *ckpObjectPtr));
       
  1052         return;
       
  1053     }
       
  1054 
       
  1055     jIntegerClass = (*env)->FindClass(env, "java/lang/Integer");
       
  1056     if (jIntegerClass == NULL) { return; }
       
  1057     if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {
       
  1058         *ckpObjectPtr = jIntegerObjectToCKULongPtr(env, jObject);
       
  1059         *ckpLength = sizeof(CK_ULONG);
       
  1060         TRACE1("<converted integer value %X>", *((CK_ULONG *) *ckpObjectPtr));
       
  1061         return;
       
  1062     }
       
  1063 
       
  1064     jBooleanArrayClass = (*env)->FindClass(env, "[Z");
       
  1065     if (jBooleanArrayClass == NULL) { return; }
       
  1066     if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {
       
  1067         jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**)ckpObjectPtr, ckpLength);
       
  1068         return;
       
  1069     }
       
  1070 
       
  1071     jIntArrayClass = (*env)->FindClass(env, "[I");
       
  1072     if (jIntArrayClass == NULL) { return; }
       
  1073     if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {
       
  1074         jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
       
  1075         return;
       
  1076     }
       
  1077 
       
  1078     jLongArrayClass = (*env)->FindClass(env, "[J");
       
  1079     if (jLongArrayClass == NULL) { return; }
       
  1080     if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {
       
  1081         jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength);
       
  1082         return;
       
  1083     }
       
  1084 
       
  1085     jStringClass = (*env)->FindClass(env, "java/lang/String");
       
  1086     if (jStringClass == NULL) { return; }
       
  1087     if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {
       
  1088         jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength);
       
  1089         return;
       
  1090     }
       
  1091 
       
  1092     /* type of jObject unknown, throw PKCS11RuntimeException */
       
  1093     jObjectClass = (*env)->FindClass(env, "java/lang/Object");
       
  1094     if (jObjectClass == NULL) { return; }
       
  1095     jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");
       
  1096     if (jMethod == NULL) { return; }
       
  1097     jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);
       
  1098     assert(jClassObject != 0);
       
  1099     jClassClass = (*env)->FindClass(env, "java/lang/Class");
       
  1100     if (jClassClass == NULL) { return; }
       
  1101     jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");
       
  1102     if (jMethod == NULL) { return; }
       
  1103     jClassNameString = (jstring)
       
  1104         (*env)->CallObjectMethod(env, jClassObject, jMethod);
       
  1105     assert(jClassNameString != 0);
       
  1106     classNameString = (char*)
       
  1107         (*env)->GetStringUTFChars(env, jClassNameString, NULL);
       
  1108     if (classNameString == NULL) { return; }
       
  1109     exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";
       
  1110     exceptionMsg = (char *)
       
  1111         malloc((strlen(exceptionMsgPrefix) + strlen(classNameString) + 1));
       
  1112     if (exceptionMsg == NULL) {
       
  1113         (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
       
  1114         throwOutOfMemoryError(env, 0);
       
  1115         return;
       
  1116     }
       
  1117     strcpy(exceptionMsg, exceptionMsgPrefix);
       
  1118     strcat(exceptionMsg, classNameString);
       
  1119     (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);
       
  1120     throwPKCS11RuntimeException(env, exceptionMsg);
       
  1121     free(exceptionMsg);
       
  1122     *ckpObjectPtr = NULL;
       
  1123     *ckpLength = 0;
       
  1124 
       
  1125     TRACE0("FINISHED\n");
       
  1126 }
       
  1127 
       
  1128 #ifdef P11_MEMORYDEBUG
       
  1129 
       
  1130 #undef malloc
       
  1131 #undef free
       
  1132 
       
  1133 void *p11malloc(size_t c, char *file, int line) {
       
  1134     void *p = malloc(c);
       
  1135     printf("malloc\t%08x\t%d\t%s:%d\n", p, c, file, line); fflush(stdout);
       
  1136     return p;
       
  1137 }
       
  1138 
       
  1139 void p11free(void *p, char *file, int line) {
       
  1140     printf("free\t%08x\t\t%s:%d\n", p, file, line); fflush(stdout);
       
  1141     free(p);
       
  1142 }
       
  1143 
       
  1144 #endif
       
  1145 
       
  1146 // prints a message to stdout if debug output is enabled
       
  1147 void printDebug(const char *format, ...) {
       
  1148     if (debug == JNI_TRUE) {
       
  1149         va_list args;
       
  1150         fprintf(stdout, "sunpkcs11: ");
       
  1151         va_start(args, format);
       
  1152         vfprintf(stdout, format, args);
       
  1153         va_end(args);
       
  1154         fflush(stdout);
       
  1155     }
       
  1156 }
       
  1157