Path: blob/master/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c
41149 views
/*1* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.2*/34/* Copyright (c) 2002 Graz University of Technology. All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions are met:8*9* 1. Redistributions of source code must retain the above copyright notice,10* this list of conditions and the following disclaimer.11*12* 2. Redistributions in binary form must reproduce the above copyright notice,13* this list of conditions and the following disclaimer in the documentation14* and/or other materials provided with the distribution.15*16* 3. The end-user documentation included with the redistribution, if any, must17* include the following acknowledgment:18*19* "This product includes software developed by IAIK of Graz University of20* Technology."21*22* Alternately, this acknowledgment may appear in the software itself, if23* and wherever such third-party acknowledgments normally appear.24*25* 4. The names "Graz University of Technology" and "IAIK of Graz University of26* Technology" must not be used to endorse or promote products derived from27* this software without prior written permission.28*29* 5. Products derived from this software may not be called30* "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior31* written permission of Graz University of Technology.32*33* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED34* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED35* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR36* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE37* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,38* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,39* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,40* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON41* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,42* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY43* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE44* POSSIBILITY OF SUCH DAMAGE.45*/4647#include "pkcs11wrapper.h"4849#include <stdio.h>50#include <stdlib.h>51#include <string.h>52#include <assert.h>5354/* declare file private functions */5556ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation);57int isModulePresent(JNIEnv *env, jobject pkcs11Implementation);58void removeAllModuleEntries(JNIEnv *env);596061/* ************************************************************************** */62/* Functions for keeping track of currently active and loaded modules */63/* ************************************************************************** */646566/*67* Create a new object for locking.68*/69jobject createLockObject(JNIEnv *env) {70jclass jObjectClass;71jobject jLockObject;72jmethodID jConstructor;7374jObjectClass = (*env)->FindClass(env, "java/lang/Object");75if (jObjectClass == NULL) { return NULL; }76jConstructor = (*env)->GetMethodID(env, jObjectClass, "<init>", "()V");77if (jConstructor == NULL) { return NULL; }78jLockObject = (*env)->NewObject(env, jObjectClass, jConstructor);79if (jLockObject == NULL) { return NULL; }80jLockObject = (*env)->NewGlobalRef(env, jLockObject);8182return jLockObject ;83}8485/*86* Create a new object for locking.87*/88void destroyLockObject(JNIEnv *env, jobject jLockObject) {89if (jLockObject != NULL) {90(*env)->DeleteGlobalRef(env, jLockObject);91}92}9394/*95* Add the given pkcs11Implementation object to the list of present modules.96* Attach the given data to the entry. If the given pkcs11Implementation is97* already in the list, just override its old module data with the new one.98* None of the arguments can be NULL. If one of the arguments is NULL, this99* function does nothing.100*/101void putModuleEntry(JNIEnv *env, jobject pkcs11Implementation, ModuleData *moduleData) {102if (pkcs11Implementation == NULL_PTR) {103return ;104}105if (moduleData == NULL) {106return ;107}108(*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, ptr_to_jlong(moduleData));109}110111112/*113* Get the module data of the entry for the given pkcs11Implementation. Returns114* NULL, if the pkcs11Implementation is not in the list.115*/116ModuleData * getModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {117jlong jData;118if (pkcs11Implementation == NULL) {119return NULL;120}121jData = (*env)->GetLongField(env, pkcs11Implementation, pNativeDataID);122return (ModuleData*)jlong_to_ptr(jData);123}124125CK_FUNCTION_LIST_PTR getFunctionList(JNIEnv *env, jobject pkcs11Implementation) {126ModuleData *moduleData;127CK_FUNCTION_LIST_PTR ckpFunctions;128129moduleData = getModuleEntry(env, pkcs11Implementation);130if (moduleData == NULL) {131throwDisconnectedRuntimeException(env);132return NULL;133}134ckpFunctions = moduleData->ckFunctionListPtr;135return ckpFunctions;136}137138139/*140* Returns 1, if the given pkcs11Implementation is in the list.141* 0, otherwise.142*/143int isModulePresent(JNIEnv *env, jobject pkcs11Implementation) {144int present;145146ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);147148present = (moduleData != NULL) ? 1 : 0;149150return present ;151}152153154/*155* Removes the entry for the given pkcs11Implementation from the list. Returns156* the module's data, after the node was removed. If this function returns NULL157* the pkcs11Implementation was not in the list.158*/159ModuleData * removeModuleEntry(JNIEnv *env, jobject pkcs11Implementation) {160ModuleData *moduleData = getModuleEntry(env, pkcs11Implementation);161if (moduleData == NULL) {162return NULL;163}164(*env)->SetLongField(env, pkcs11Implementation, pNativeDataID, 0);165return moduleData;166}167168/*169* Removes all present entries from the list of modules and frees all170* associated resources. This function is used for clean-up.171*/172void removeAllModuleEntries(JNIEnv *env) {173/* XXX empty */174}175176/* ************************************************************************** */177/* Below there follow the helper functions to support conversions between */178/* Java and Cryptoki types */179/* ************************************************************************** */180181/*182* function to convert a PKCS#11 return value into a PKCS#11Exception183*184* This function generates a PKCS#11Exception with the returnValue as the185* errorcode. If the returnValue is not CKR_OK. The function returns 0, if the186* returnValue is CKR_OK. Otherwise, it returns the returnValue as a jLong.187*188* @param env - used to call JNI functions and to get the Exception class189* @param returnValue - of the PKCS#11 function190*/191jlong ckAssertReturnValueOK(JNIEnv *env, CK_RV returnValue) {192return ckAssertReturnValueOK2(env, returnValue, NULL);193}194195/*196* function to convert a PKCS#11 return value and additional message into a197* PKCS#11Exception198*199* This function generates a PKCS#11Exception with the returnValue as the200* errorcode. If the returnValue is not CKR_OK. The function returns 0, if the201* returnValue is CKR_OK. Otherwise, it returns the returnValue as a jLong.202*203* @param env - used to call JNI functions and to get the Exception class204* @param returnValue - of the PKCS#11 function205* @param msg - additional message for the generated PKCS11Exception206*/207jlong ckAssertReturnValueOK2(JNIEnv *env, CK_RV returnValue, const char* msg) {208jclass jPKCS11ExceptionClass;209jmethodID jConstructor;210jthrowable jPKCS11Exception;211jlong jErrorCode = 0L;212jstring jMsg = NULL;213214if (returnValue != CKR_OK) {215jErrorCode = ckULongToJLong(returnValue);216jPKCS11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION);217if (jPKCS11ExceptionClass != NULL) {218jConstructor = (*env)->GetMethodID(env, jPKCS11ExceptionClass,219"<init>", "(JLjava/lang/String;)V");220if (jConstructor != NULL) {221if (msg != NULL) {222jMsg = (*env)->NewStringUTF(env, msg);223}224jPKCS11Exception = (jthrowable) (*env)->NewObject(env,225jPKCS11ExceptionClass, jConstructor, jErrorCode, jMsg);226if (jPKCS11Exception != NULL) {227(*env)->Throw(env, jPKCS11Exception);228}229}230}231(*env)->DeleteLocalRef(env, jPKCS11ExceptionClass);232}233return jErrorCode;234}235236237/*238* Throws a Java Exception by name239*/240void throwByName(JNIEnv *env, const char *name, const char *msg)241{242jclass cls = (*env)->FindClass(env, name);243244if (cls != 0) /* Otherwise an exception has already been thrown */245(*env)->ThrowNew(env, cls, msg);246}247248/*249* Throws java.lang.OutOfMemoryError250*/251void throwOutOfMemoryError(JNIEnv *env, const char *msg)252{253throwByName(env, "java/lang/OutOfMemoryError", msg);254}255256/*257* Throws java.lang.NullPointerException258*/259void throwNullPointerException(JNIEnv *env, const char *msg)260{261throwByName(env, "java/lang/NullPointerException", msg);262}263264/*265* Throws java.io.IOException266*/267void throwIOException(JNIEnv *env, const char *msg)268{269throwByName(env, "java/io/IOException", msg);270}271272/*273* This function simply throws a PKCS#11RuntimeException with the given274* string as its message.275*276* @param env Used to call JNI functions and to get the Exception class.277* @param jmessage The message string of the Exception object.278*/279void throwPKCS11RuntimeException(JNIEnv *env, const char *message)280{281throwByName(env, CLASS_PKCS11RUNTIMEEXCEPTION, message);282}283284/*285* This function simply throws a PKCS#11RuntimeException. The message says that286* the object is not connected to the module.287*288* @param env Used to call JNI functions and to get the Exception class.289*/290void throwDisconnectedRuntimeException(JNIEnv *env)291{292throwPKCS11RuntimeException(env, "This object is not connected to a module.");293}294295/* This function frees the specified CK_ATTRIBUTE array.296*297* @param attrPtr pointer to the to-be-freed CK_ATTRIBUTE array.298* @param len the length of the array299*/300void freeCKAttributeArray(CK_ATTRIBUTE_PTR attrPtr, int len) {301if (attrPtr != NULL) {302int i;303for (i=0; i<len; i++) {304if (attrPtr[i].pValue != NULL_PTR) {305free(attrPtr[i].pValue);306}307}308free(attrPtr);309}310}311312/* This function frees the specified CK_MECHANISM_PTR pointer and its313* pParameter including mechanism-specific memory allocations.314*315* @param mechPtr pointer to the to-be-freed CK_MECHANISM structure.316*/317void freeCKMechanismPtr(CK_MECHANISM_PTR mechPtr) {318void *tmp;319CK_SSL3_MASTER_KEY_DERIVE_PARAMS *sslMkdTmp;320CK_SSL3_KEY_MAT_PARAMS* sslKmTmp;321CK_TLS12_MASTER_KEY_DERIVE_PARAMS *tlsMkdTmp;322CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;323324if (mechPtr != NULL) {325TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",326mechPtr, mechPtr->mechanism);327if (mechPtr->pParameter != NULL) {328tmp = mechPtr->pParameter;329switch (mechPtr->mechanism) {330case CKM_AES_GCM:331if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {332TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");333free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);334free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);335} else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {336TRACE0("[ GCM_PARAMS ]\n");337free(((CK_GCM_PARAMS*)tmp)->pIv);338free(((CK_GCM_PARAMS*)tmp)->pAAD);339}340break;341case CKM_AES_CCM:342TRACE0("[ CK_CCM_PARAMS ]\n");343free(((CK_CCM_PARAMS*)tmp)->pNonce);344free(((CK_CCM_PARAMS*)tmp)->pAAD);345break;346case CKM_CHACHA20_POLY1305:347TRACE0("[ CK_SALSA20_CHACHA20_POLY1305_PARAMS ]\n");348free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pNonce);349free(((CK_SALSA20_CHACHA20_POLY1305_PARAMS*)tmp)->pAAD);350break;351case CKM_TLS_PRF:352case CKM_NSS_TLS_PRF_GENERAL:353TRACE0("[ CK_TLS_PRF_PARAMS ]\n");354free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);355free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);356free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);357free(((CK_TLS_PRF_PARAMS*)tmp)->pOutput);358break;359case CKM_SSL3_MASTER_KEY_DERIVE:360case CKM_TLS_MASTER_KEY_DERIVE:361case CKM_SSL3_MASTER_KEY_DERIVE_DH:362case CKM_TLS_MASTER_KEY_DERIVE_DH:363sslMkdTmp = tmp;364TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");365free(sslMkdTmp->RandomInfo.pClientRandom);366free(sslMkdTmp->RandomInfo.pServerRandom);367free(sslMkdTmp->pVersion);368break;369case CKM_SSL3_KEY_AND_MAC_DERIVE:370case CKM_TLS_KEY_AND_MAC_DERIVE:371sslKmTmp = tmp;372TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");373free(sslKmTmp->RandomInfo.pClientRandom);374free(sslKmTmp->RandomInfo.pServerRandom);375if (sslKmTmp->pReturnedKeyMaterial != NULL) {376free(sslKmTmp->pReturnedKeyMaterial->pIVClient);377free(sslKmTmp->pReturnedKeyMaterial->pIVServer);378free(sslKmTmp->pReturnedKeyMaterial);379}380break;381case CKM_TLS12_MASTER_KEY_DERIVE:382case CKM_TLS12_MASTER_KEY_DERIVE_DH:383tlsMkdTmp = tmp;384TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");385free(tlsMkdTmp->RandomInfo.pClientRandom);386free(tlsMkdTmp->RandomInfo.pServerRandom);387free(tlsMkdTmp->pVersion);388break;389case CKM_TLS12_KEY_AND_MAC_DERIVE:390tlsKmTmp = tmp;391TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");392free(tlsKmTmp->RandomInfo.pClientRandom);393free(tlsKmTmp->RandomInfo.pServerRandom);394if (tlsKmTmp->pReturnedKeyMaterial != NULL) {395free(tlsKmTmp->pReturnedKeyMaterial->pIVClient);396free(tlsKmTmp->pReturnedKeyMaterial->pIVServer);397free(tlsKmTmp->pReturnedKeyMaterial);398}399break;400case CKM_ECDH1_DERIVE:401case CKM_ECDH1_COFACTOR_DERIVE:402TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");403free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);404free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);405break;406case CKM_TLS_MAC:407case CKM_AES_CTR:408case CKM_RSA_PKCS_PSS:409case CKM_CAMELLIA_CTR:410// params do not contain pointers411break;412default:413// currently unsupported mechs by SunPKCS11 provider414// CKM_RSA_PKCS_OAEP, CKM_ECMQV_DERIVE,415// CKM_X9_42_*, CKM_KEA_DERIVE, CKM_RC2_*, CKM_RC5_*,416// CKM_SKIPJACK_*, CKM_KEY_WRAP_SET_OAEP, CKM_PKCS5_PBKD2,417// PBE mechs, WTLS mechs, CMS mechs,418// CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP,419// CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_*420// CK_any_CBC_ENCRYPT_DATA?421TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");422break;423}424TRACE1("\t=> freed param %p\n", tmp);425free(tmp);426} else {427TRACE0("\t=> param NULL\n");428}429free(mechPtr);430TRACE0("FINISHED\n");431}432}433434/* This function replaces the CK_GCM_PARAMS_NO_IVBITS structure associated435* with the specified CK_MECHANISM structure with CK_GCM_PARAMS436* structure.437*438* @param mechPtr pointer to the CK_MECHANISM structure containing439* the to-be-converted CK_GCM_PARAMS_NO_IVBITS structure.440* @return pointer to the CK_MECHANISM structure containing the441* converted CK_GCM_PARAMS structure or NULL if no conversion took place.442*/443CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {444CK_GCM_PARAMS* pGcmParams2 = NULL;445CK_GCM_PARAMS_NO_IVBITS* pParams = NULL;446if ((mechPtr->mechanism == CKM_AES_GCM) &&447(mechPtr->pParameter != NULL_PTR) &&448(mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS))) {449pGcmParams2 = calloc(1, sizeof(CK_GCM_PARAMS));450if (pGcmParams2 == NULL) {451throwOutOfMemoryError(env, 0);452return NULL;453}454pParams = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;455pGcmParams2->pIv = pParams->pIv;456pGcmParams2->ulIvLen = pParams->ulIvLen;457pGcmParams2->ulIvBits = (pGcmParams2->ulIvLen << 3);458pGcmParams2->pAAD = pParams->pAAD;459pGcmParams2->ulAADLen = pParams->ulAADLen;460pGcmParams2->ulTagBits = pParams->ulTagBits;461TRACE1("DEBUG updateGCMParams: pMech %p\n", mechPtr);462TRACE2("\t=> GCM param w/o ulIvBits %p => GCM param %p\n", pParams,463pGcmParams2);464free(pParams);465mechPtr->pParameter = pGcmParams2;466mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);467return mechPtr;468} else {469TRACE0("DEBUG updateGCMParams: no conversion done\n");470}471return NULL;472}473474/*475* the following functions convert Java arrays to PKCS#11 array pointers and476* their array length and vice versa477*478* void j<Type>ArrayToCK<Type>Array(JNIEnv *env,479* const j<Type>Array jArray,480* CK_<Type>_PTR *ckpArray,481* CK_ULONG_PTR ckLength);482*483* j<Type>Array ck<Type>ArrayToJ<Type>Array(JNIEnv *env,484* const CK_<Type>_PTR ckpArray,485* CK_ULONG ckLength);486*487* PKCS#11 arrays consist always of a pointer to the beginning of the array and488* the array length whereas Java arrays carry their array length.489*490* The Functions to convert a Java array to a PKCS#11 array are void functions.491* Their arguments are the Java array object to convert, the reference to the492* array pointer, where the new PKCS#11 array should be stored and the reference493* to the array length where the PKCS#11 array length should be stored. These two494* references must not be NULL_PTR.495*496* The functions first obtain the array length of the Java array and then allocate497* the memory for the PKCS#11 array and set the array length. Then each element498* gets converted depending on their type. After use the allocated memory of the499* PKCS#11 array has to be explicitly freed.500*501* The Functions to convert a PKCS#11 array to a Java array get the PKCS#11 array502* pointer and the array length and they return the new Java array object. The503* Java array does not need to get freed after use.504*/505506/*507* converts a jbooleanArray to a CK_BBOOL array. The allocated memory has to be freed after use!508*509* @param env - used to call JNI functions to get the array informtaion510* @param jArray - the Java array to convert511* @param ckpArray - the reference, where the pointer to the new CK_BBOOL array will be stored512* @param ckpLength - the reference, where the array length will be stored513*/514void jBooleanArrayToCKBBoolArray(JNIEnv *env, const jbooleanArray jArray, CK_BBOOL **ckpArray, CK_ULONG_PTR ckpLength)515{516jboolean* jpTemp;517CK_ULONG i;518519if(jArray == NULL) {520*ckpArray = NULL_PTR;521*ckpLength = 0L;522return;523}524*ckpLength = (*env)->GetArrayLength(env, jArray);525jpTemp = (jboolean*) calloc(*ckpLength, sizeof(jboolean));526if (jpTemp == NULL) {527throwOutOfMemoryError(env, 0);528return;529}530(*env)->GetBooleanArrayRegion(env, jArray, 0, *ckpLength, jpTemp);531if ((*env)->ExceptionCheck(env)) {532free(jpTemp);533return;534}535536*ckpArray = (CK_BBOOL*) calloc (*ckpLength, sizeof(CK_BBOOL));537if (*ckpArray == NULL) {538free(jpTemp);539throwOutOfMemoryError(env, 0);540return;541}542for (i=0; i<(*ckpLength); i++) {543(*ckpArray)[i] = jBooleanToCKBBool(jpTemp[i]);544}545free(jpTemp);546}547548/*549* converts a jbyteArray to a CK_BYTE array. The allocated memory has to be freed after use!550*551* @param env - used to call JNI functions to get the array informtaion552* @param jArray - the Java array to convert553* @param ckpArray - the reference, where the pointer to the new CK_BYTE array will be stored554* @param ckpLength - the reference, where the array length will be stored555*/556void jByteArrayToCKByteArray(JNIEnv *env, const jbyteArray jArray, CK_BYTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)557{558jbyte* jpTemp;559CK_ULONG i;560561if(jArray == NULL) {562*ckpArray = NULL_PTR;563*ckpLength = 0L;564return;565}566*ckpLength = (*env)->GetArrayLength(env, jArray);567jpTemp = (jbyte*) calloc(*ckpLength, sizeof(jbyte));568if (jpTemp == NULL) {569throwOutOfMemoryError(env, 0);570return;571}572(*env)->GetByteArrayRegion(env, jArray, 0, *ckpLength, jpTemp);573if ((*env)->ExceptionCheck(env)) {574free(jpTemp);575return;576}577578/* if CK_BYTE is the same size as jbyte, we save an additional copy */579if (sizeof(CK_BYTE) == sizeof(jbyte)) {580*ckpArray = (CK_BYTE_PTR) jpTemp;581} else {582*ckpArray = (CK_BYTE_PTR) calloc (*ckpLength, sizeof(CK_BYTE));583if (*ckpArray == NULL) {584free(jpTemp);585throwOutOfMemoryError(env, 0);586return;587}588for (i=0; i<(*ckpLength); i++) {589(*ckpArray)[i] = jByteToCKByte(jpTemp[i]);590}591free(jpTemp);592}593}594595/*596* converts a jlongArray to a CK_ULONG array. The allocated memory has to be freed after use!597*598* @param env - used to call JNI functions to get the array informtaion599* @param jArray - the Java array to convert600* @param ckpArray - the reference, where the pointer to the new CK_ULONG array will be stored601* @param ckpLength - the reference, where the array length will be stored602*/603void jLongArrayToCKULongArray(JNIEnv *env, const jlongArray jArray, CK_ULONG_PTR *ckpArray, CK_ULONG_PTR ckpLength)604{605jlong* jTemp;606CK_ULONG i;607608if(jArray == NULL) {609*ckpArray = NULL_PTR;610*ckpLength = 0L;611return;612}613*ckpLength = (*env)->GetArrayLength(env, jArray);614jTemp = (jlong*) calloc(*ckpLength, sizeof(jlong));615if (jTemp == NULL) {616throwOutOfMemoryError(env, 0);617return;618}619(*env)->GetLongArrayRegion(env, jArray, 0, *ckpLength, jTemp);620if ((*env)->ExceptionCheck(env)) {621free(jTemp);622return;623}624625*ckpArray = (CK_ULONG_PTR) calloc(*ckpLength, sizeof(CK_ULONG));626if (*ckpArray == NULL) {627free(jTemp);628throwOutOfMemoryError(env, 0);629return;630}631for (i=0; i<(*ckpLength); i++) {632(*ckpArray)[i] = jLongToCKULong(jTemp[i]);633}634free(jTemp);635}636637/*638* converts a jcharArray to a CK_CHAR array. The allocated memory has to be freed after use!639*640* @param env - used to call JNI functions to get the array informtaion641* @param jArray - the Java array to convert642* @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored643* @param ckpLength - the reference, where the array length will be stored644*/645void jCharArrayToCKCharArray(JNIEnv *env, const jcharArray jArray, CK_CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)646{647jchar* jpTemp;648CK_ULONG i;649650if(jArray == NULL) {651*ckpArray = NULL_PTR;652*ckpLength = 0L;653return;654}655*ckpLength = (*env)->GetArrayLength(env, jArray);656jpTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));657if (jpTemp == NULL) {658throwOutOfMemoryError(env, 0);659return;660}661(*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jpTemp);662if ((*env)->ExceptionCheck(env)) {663free(jpTemp);664return;665}666667*ckpArray = (CK_CHAR_PTR) calloc (*ckpLength, sizeof(CK_CHAR));668if (*ckpArray == NULL) {669free(jpTemp);670throwOutOfMemoryError(env, 0);671return;672}673for (i=0; i<(*ckpLength); i++) {674(*ckpArray)[i] = jCharToCKChar(jpTemp[i]);675}676free(jpTemp);677}678679/*680* converts a jcharArray to a CK_UTF8CHAR array. The allocated memory has to be freed after use!681*682* @param env - used to call JNI functions to get the array informtaion683* @param jArray - the Java array to convert684* @param ckpArray - the reference, where the pointer to the new CK_UTF8CHAR array will be stored685* @param ckpLength - the reference, where the array length will be stored686*/687void jCharArrayToCKUTF8CharArray(JNIEnv *env, const jcharArray jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)688{689jchar* jTemp;690CK_ULONG i;691692if(jArray == NULL) {693*ckpArray = NULL_PTR;694*ckpLength = 0L;695return;696}697*ckpLength = (*env)->GetArrayLength(env, jArray);698jTemp = (jchar*) calloc(*ckpLength, sizeof(jchar));699if (jTemp == NULL) {700throwOutOfMemoryError(env, 0);701return;702}703(*env)->GetCharArrayRegion(env, jArray, 0, *ckpLength, jTemp);704if ((*env)->ExceptionCheck(env)) {705free(jTemp);706return;707}708709*ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength, sizeof(CK_UTF8CHAR));710if (*ckpArray == NULL) {711free(jTemp);712throwOutOfMemoryError(env, 0);713return;714}715for (i=0; i<(*ckpLength); i++) {716(*ckpArray)[i] = jCharToCKUTF8Char(jTemp[i]);717}718free(jTemp);719}720721/*722* converts a jstring to a CK_CHAR array. The allocated memory has to be freed after use!723*724* @param env - used to call JNI functions to get the array informtaion725* @param jArray - the Java array to convert726* @param ckpArray - the reference, where the pointer to the new CK_CHAR array will be stored727* @param ckpLength - the reference, where the array length will be stored728*/729void jStringToCKUTF8CharArray(JNIEnv *env, const jstring jArray, CK_UTF8CHAR_PTR *ckpArray, CK_ULONG_PTR ckpLength)730{731const char* pCharArray;732jboolean isCopy;733734if(jArray == NULL) {735*ckpArray = NULL_PTR;736*ckpLength = 0L;737return;738}739740pCharArray = (*env)->GetStringUTFChars(env, jArray, &isCopy);741if (pCharArray == NULL) { return; }742743*ckpLength = (CK_ULONG) strlen(pCharArray);744*ckpArray = (CK_UTF8CHAR_PTR) calloc(*ckpLength + 1, sizeof(CK_UTF8CHAR));745if (*ckpArray == NULL) {746(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);747throwOutOfMemoryError(env, 0);748return;749}750strcpy((char*)*ckpArray, pCharArray);751(*env)->ReleaseStringUTFChars(env, (jstring) jArray, pCharArray);752}753754/*755* converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory756* has to be freed after use!757*758* @param env - used to call JNI functions to get the array informtaion759* @param jArray - the Java Attribute array (template) to convert760* @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be761* stored762* @param ckpLength - the reference, where the array length will be stored763*/764void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength)765{766CK_ULONG i;767jlong jLength;768jobject jAttribute;769770TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray");771if (jArray == NULL) {772*ckpArray = NULL_PTR;773*ckpLength = 0L;774return;775}776jLength = (*env)->GetArrayLength(env, jArray);777*ckpLength = jLongToCKULong(jLength);778*ckpArray = (CK_ATTRIBUTE_PTR) calloc(*ckpLength, sizeof(CK_ATTRIBUTE));779if (*ckpArray == NULL) {780throwOutOfMemoryError(env, 0);781return;782}783TRACE1(", converting %lld attributes", (long long int) jLength);784for (i=0; i<(*ckpLength); i++) {785TRACE1(", getting %lu. attribute", i);786jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);787if ((*env)->ExceptionCheck(env)) {788freeCKAttributeArray(*ckpArray, i);789return;790}791TRACE1(", jAttribute , converting %lu. attribute", i);792(*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);793if ((*env)->ExceptionCheck(env)) {794freeCKAttributeArray(*ckpArray, i);795return;796}797}798TRACE0("FINISHED\n");799}800801/*802* converts a CK_BYTE array and its length to a jbyteArray.803*804* @param env - used to call JNI functions to create the new Java array805* @param ckpArray - the pointer to the CK_BYTE array to convert806* @param ckpLength - the length of the array to convert807* @return - the new Java byte array or NULL if error occurred808*/809jbyteArray ckByteArrayToJByteArray(JNIEnv *env, const CK_BYTE_PTR ckpArray, CK_ULONG ckLength)810{811CK_ULONG i;812jbyte* jpTemp;813jbyteArray jArray;814815/* if CK_BYTE is the same size as jbyte, we save an additional copy */816if (sizeof(CK_BYTE) == sizeof(jbyte)) {817jpTemp = (jbyte*) ckpArray;818} else {819jpTemp = (jbyte*) calloc(ckLength, sizeof(jbyte));820if (jpTemp == NULL) {821throwOutOfMemoryError(env, 0);822return NULL;823}824for (i=0; i<ckLength; i++) {825jpTemp[i] = ckByteToJByte(ckpArray[i]);826}827}828829jArray = (*env)->NewByteArray(env, ckULongToJSize(ckLength));830if (jArray != NULL) {831(*env)->SetByteArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);832}833834if (sizeof(CK_BYTE) != sizeof(jbyte)) { free(jpTemp); }835836return jArray ;837}838839/*840* converts a CK_ULONG array and its length to a jlongArray.841*842* @param env - used to call JNI functions to create the new Java array843* @param ckpArray - the pointer to the CK_ULONG array to convert844* @param ckpLength - the length of the array to convert845* @return - the new Java long array846*/847jlongArray ckULongArrayToJLongArray(JNIEnv *env, const CK_ULONG_PTR ckpArray, CK_ULONG ckLength)848{849CK_ULONG i;850jlong* jpTemp;851jlongArray jArray;852853jpTemp = (jlong*) calloc(ckLength, sizeof(jlong));854if (jpTemp == NULL) {855throwOutOfMemoryError(env, 0);856return NULL;857}858for (i=0; i<ckLength; i++) {859jpTemp[i] = ckLongToJLong(ckpArray[i]);860}861jArray = (*env)->NewLongArray(env, ckULongToJSize(ckLength));862if (jArray != NULL) {863(*env)->SetLongArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);864}865free(jpTemp);866867return jArray ;868}869870/*871* converts a CK_CHAR array and its length to a jcharArray.872*873* @param env - used to call JNI functions to create the new Java array874* @param ckpArray - the pointer to the CK_CHAR array to convert875* @param ckpLength - the length of the array to convert876* @return - the new Java char array877*/878jcharArray ckCharArrayToJCharArray(JNIEnv *env, const CK_CHAR_PTR ckpArray, CK_ULONG ckLength)879{880CK_ULONG i;881jchar* jpTemp;882jcharArray jArray;883884jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));885if (jpTemp == NULL) {886throwOutOfMemoryError(env, 0);887return NULL;888}889for (i=0; i<ckLength; i++) {890jpTemp[i] = ckCharToJChar(ckpArray[i]);891}892jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));893if (jArray != NULL) {894(*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);895}896free(jpTemp);897898return jArray ;899}900901/*902* converts a CK_UTF8CHAR array and its length to a jcharArray.903*904* @param env - used to call JNI functions to create the new Java array905* @param ckpArray - the pointer to the CK_UTF8CHAR array to convert906* @param ckpLength - the length of the array to convert907* @return - the new Java char array908*/909jcharArray ckUTF8CharArrayToJCharArray(JNIEnv *env, const CK_UTF8CHAR_PTR ckpArray, CK_ULONG ckLength)910{911CK_ULONG i;912jchar* jpTemp;913jcharArray jArray;914915jpTemp = (jchar*) calloc(ckLength, sizeof(jchar));916if (jpTemp == NULL) {917throwOutOfMemoryError(env, 0);918return NULL;919}920for (i=0; i<ckLength; i++) {921jpTemp[i] = ckUTF8CharToJChar(ckpArray[i]);922}923jArray = (*env)->NewCharArray(env, ckULongToJSize(ckLength));924if (jArray != NULL) {925(*env)->SetCharArrayRegion(env, jArray, 0, ckULongToJSize(ckLength), jpTemp);926}927free(jpTemp);928929return jArray ;930}931932/*933* the following functions convert Java objects to PKCS#11 pointers and the934* length in bytes and vice versa935*936* CK_<Type>_PTR j<Object>ToCK<Type>Ptr(JNIEnv *env, jobject jObject);937*938* jobject ck<Type>PtrToJ<Object>(JNIEnv *env, const CK_<Type>_PTR ckpValue);939*940* The functions that convert a Java object to a PKCS#11 pointer first allocate941* the memory for the PKCS#11 pointer. Then they set each element corresponding942* to the fields in the Java object to convert. After use the allocated memory of943* the PKCS#11 pointer has to be explicitly freed.944*945* The functions to convert a PKCS#11 pointer to a Java object create a new Java946* object first and than they set all fields in the object depending on the values947* of the type or structure where the PKCS#11 pointer points to.948*/949950/*951* converts a CK_BBOOL pointer to a Java boolean Object.952*953* @param env - used to call JNI functions to create the new Java object954* @param ckpValue - the pointer to the CK_BBOOL value955* @return - the new Java boolean object with the boolean value956*/957jobject ckBBoolPtrToJBooleanObject(JNIEnv *env, const CK_BBOOL *ckpValue)958{959jclass jValueObjectClass;960jmethodID jConstructor;961jobject jValueObject;962jboolean jValue;963964jValueObjectClass = (*env)->FindClass(env, "java/lang/Boolean");965if (jValueObjectClass == NULL) { return NULL; }966jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(Z)V");967if (jConstructor == NULL) { return NULL; }968jValue = ckBBoolToJBoolean(*ckpValue);969jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);970971return jValueObject ;972}973974/*975* converts a CK_ULONG pointer to a Java long Object.976*977* @param env - used to call JNI functions to create the new Java object978* @param ckpValue - the pointer to the CK_ULONG value979* @return - the new Java long object with the long value980*/981jobject ckULongPtrToJLongObject(JNIEnv *env, const CK_ULONG_PTR ckpValue)982{983jclass jValueObjectClass;984jmethodID jConstructor;985jobject jValueObject;986jlong jValue;987988jValueObjectClass = (*env)->FindClass(env, "java/lang/Long");989if (jValueObjectClass == NULL) { return NULL; }990jConstructor = (*env)->GetMethodID(env, jValueObjectClass, "<init>", "(J)V");991if (jConstructor == NULL) { return NULL; }992jValue = ckULongToJLong(*ckpValue);993jValueObject = (*env)->NewObject(env, jValueObjectClass, jConstructor, jValue);994995return jValueObject ;996}997998/*999* converts a Java boolean object into a pointer to a CK_BBOOL value. The memory has to be1000* freed after use!1001*1002* @param env - used to call JNI functions to get the value out of the Java object1003* @param jObject - the "java/lang/Boolean" object to convert1004* @return - the pointer to the new CK_BBOOL value1005*/1006CK_BBOOL* jBooleanObjectToCKBBoolPtr(JNIEnv *env, jobject jObject)1007{1008jclass jObjectClass;1009jmethodID jValueMethod;1010jboolean jValue;1011CK_BBOOL *ckpValue;10121013jObjectClass = (*env)->FindClass(env, "java/lang/Boolean");1014if (jObjectClass == NULL) { return NULL; }1015jValueMethod = (*env)->GetMethodID(env, jObjectClass, "booleanValue", "()Z");1016if (jValueMethod == NULL) { return NULL; }1017jValue = (*env)->CallBooleanMethod(env, jObject, jValueMethod);1018ckpValue = (CK_BBOOL *) malloc(sizeof(CK_BBOOL));1019if (ckpValue == NULL) {1020throwOutOfMemoryError(env, 0);1021return NULL;1022}1023*ckpValue = jBooleanToCKBBool(jValue);10241025return ckpValue ;1026}10271028/*1029* converts a Java byte object into a pointer to a CK_BYTE value. The memory has to be1030* freed after use!1031*1032* @param env - used to call JNI functions to get the value out of the Java object1033* @param jObject - the "java/lang/Byte" object to convert1034* @return - the pointer to the new CK_BYTE value1035*/1036CK_BYTE_PTR jByteObjectToCKBytePtr(JNIEnv *env, jobject jObject)1037{1038jclass jObjectClass;1039jmethodID jValueMethod;1040jbyte jValue;1041CK_BYTE_PTR ckpValue;10421043jObjectClass = (*env)->FindClass(env, "java/lang/Byte");1044if (jObjectClass == NULL) { return NULL; }1045jValueMethod = (*env)->GetMethodID(env, jObjectClass, "byteValue", "()B");1046if (jValueMethod == NULL) { return NULL; }1047jValue = (*env)->CallByteMethod(env, jObject, jValueMethod);1048ckpValue = (CK_BYTE_PTR) malloc(sizeof(CK_BYTE));1049if (ckpValue == NULL) {1050throwOutOfMemoryError(env, 0);1051return NULL;1052}1053*ckpValue = jByteToCKByte(jValue);1054return ckpValue ;1055}10561057/*1058* converts a Java integer object into a pointer to a CK_ULONG value. The memory has to be1059* freed after use!1060*1061* @param env - used to call JNI functions to get the value out of the Java object1062* @param jObject - the "java/lang/Integer" object to convert1063* @return - the pointer to the new CK_ULONG value1064*/1065CK_ULONG* jIntegerObjectToCKULongPtr(JNIEnv *env, jobject jObject)1066{1067jclass jObjectClass;1068jmethodID jValueMethod;1069jint jValue;1070CK_ULONG *ckpValue;10711072jObjectClass = (*env)->FindClass(env, "java/lang/Integer");1073if (jObjectClass == NULL) { return NULL; }1074jValueMethod = (*env)->GetMethodID(env, jObjectClass, "intValue", "()I");1075if (jValueMethod == NULL) { return NULL; }1076jValue = (*env)->CallIntMethod(env, jObject, jValueMethod);1077ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));1078if (ckpValue == NULL) {1079throwOutOfMemoryError(env, 0);1080return NULL;1081}1082*ckpValue = jLongToCKLong(jValue);1083return ckpValue ;1084}10851086/*1087* converts a Java long object into a pointer to a CK_ULONG value. The memory has to be1088* freed after use!1089*1090* @param env - used to call JNI functions to get the value out of the Java object1091* @param jObject - the "java/lang/Long" object to convert1092* @return - the pointer to the new CK_ULONG value1093*/1094CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject)1095{1096jclass jObjectClass;1097jmethodID jValueMethod;1098jlong jValue;1099CK_ULONG *ckpValue;11001101jObjectClass = (*env)->FindClass(env, "java/lang/Long");1102if (jObjectClass == NULL) { return NULL; }1103jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J");1104if (jValueMethod == NULL) { return NULL; }1105jValue = (*env)->CallLongMethod(env, jObject, jValueMethod);1106ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG));1107if (ckpValue == NULL) {1108throwOutOfMemoryError(env, 0);1109return NULL;1110}1111*ckpValue = jLongToCKULong(jValue);11121113return ckpValue ;1114}11151116/*1117* converts a Java char object into a pointer to a CK_CHAR value. The memory has to be1118* freed after use!1119*1120* @param env - used to call JNI functions to get the value out of the Java object1121* @param jObject - the "java/lang/Char" object to convert1122* @return - the pointer to the new CK_CHAR value1123*/1124CK_CHAR_PTR jCharObjectToCKCharPtr(JNIEnv *env, jobject jObject)1125{1126jclass jObjectClass;1127jmethodID jValueMethod;1128jchar jValue;1129CK_CHAR_PTR ckpValue;11301131jObjectClass = (*env)->FindClass(env, "java/lang/Char");1132if (jObjectClass == NULL) { return NULL; }1133jValueMethod = (*env)->GetMethodID(env, jObjectClass, "charValue", "()C");1134if (jValueMethod == NULL) { return NULL; }1135jValue = (*env)->CallCharMethod(env, jObject, jValueMethod);1136ckpValue = (CK_CHAR_PTR) malloc(sizeof(CK_CHAR));1137if (ckpValue == NULL) {1138throwOutOfMemoryError(env, 0);1139return NULL;1140}1141*ckpValue = jCharToCKChar(jValue);11421143return ckpValue ;1144}11451146/*1147* converts a Java object into a pointer to CK-type or a CK-structure with the length in Bytes.1148* The memory of the returned pointer MUST BE FREED BY CALLER!1149*1150* @param env - used to call JNI functions to get the Java classes and objects1151* @param jObject - the Java object to convert1152* @param ckpLength - pointer to the length (bytes) of the newly-allocated CK-value or CK-structure1153* @return ckpObject - pointer to the newly-allocated CK-value or CK-structure1154*/1155CK_VOID_PTR jObjectToPrimitiveCKObjectPtr(JNIEnv *env, jobject jObject, CK_ULONG *ckpLength)1156{1157jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass;1158jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass;1159jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass;1160jclass jStringClass;1161jclass jObjectClass, jClassClass;1162CK_VOID_PTR ckpObject;1163jmethodID jMethod;1164jobject jClassObject;1165jstring jClassNameString;1166char *classNameString, *exceptionMsgPrefix, *exceptionMsg;11671168TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtr");1169if (jObject == NULL) {1170*ckpLength = 0;1171return NULL;1172}11731174jLongClass = (*env)->FindClass(env, "java/lang/Long");1175if (jLongClass == NULL) { return NULL; }1176if ((*env)->IsInstanceOf(env, jObject, jLongClass)) {1177ckpObject = jLongObjectToCKULongPtr(env, jObject);1178*ckpLength = sizeof(CK_ULONG);1179TRACE1("<converted long value %lu>", *((CK_ULONG *) ckpObject));1180return ckpObject;1181}11821183jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean");1184if (jBooleanClass == NULL) { return NULL; }1185if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) {1186ckpObject = jBooleanObjectToCKBBoolPtr(env, jObject);1187*ckpLength = sizeof(CK_BBOOL);1188TRACE0(" <converted boolean value ");1189TRACE0((*((CK_BBOOL *) ckpObject) == TRUE) ? "TRUE>" : "FALSE>");1190return ckpObject;1191}11921193jByteArrayClass = (*env)->FindClass(env, "[B");1194if (jByteArrayClass == NULL) { return NULL; }1195if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) {1196jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*) &ckpObject, ckpLength);1197return ckpObject;1198}11991200jCharArrayClass = (*env)->FindClass(env, "[C");1201if (jCharArrayClass == NULL) { return NULL; }1202if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) {1203jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*) &ckpObject, ckpLength);1204return ckpObject;1205}12061207jByteClass = (*env)->FindClass(env, "java/lang/Byte");1208if (jByteClass == NULL) { return NULL; }1209if ((*env)->IsInstanceOf(env, jObject, jByteClass)) {1210ckpObject = jByteObjectToCKBytePtr(env, jObject);1211*ckpLength = sizeof(CK_BYTE);1212TRACE1("<converted byte value %X>", *((CK_BYTE *) ckpObject));1213return ckpObject;1214}12151216jDateClass = (*env)->FindClass(env, CLASS_DATE);1217if (jDateClass == NULL) { return NULL; }1218if ((*env)->IsInstanceOf(env, jObject, jDateClass)) {1219ckpObject = jDateObjectToCKDatePtr(env, jObject);1220*ckpLength = sizeof(CK_DATE);1221TRACE3("<converted date value %.4s-%.2s-%.2s>", ((CK_DATE *) ckpObject)->year,1222((CK_DATE *) ckpObject)->month, ((CK_DATE *) ckpObject)->day);1223return ckpObject;1224}12251226jCharacterClass = (*env)->FindClass(env, "java/lang/Character");1227if (jCharacterClass == NULL) { return NULL; }1228if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) {1229ckpObject = jCharObjectToCKCharPtr(env, jObject);1230*ckpLength = sizeof(CK_UTF8CHAR);1231TRACE1("<converted char value %c>", *((CK_CHAR *) ckpObject));1232return ckpObject;1233}12341235jIntegerClass = (*env)->FindClass(env, "java/lang/Integer");1236if (jIntegerClass == NULL) { return NULL; }1237if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) {1238ckpObject = jIntegerObjectToCKULongPtr(env, jObject);1239*ckpLength = sizeof(CK_ULONG);1240TRACE1("<converted integer value %lu>", *((CK_ULONG *) ckpObject));1241return ckpObject;1242}12431244jBooleanArrayClass = (*env)->FindClass(env, "[Z");1245if (jBooleanArrayClass == NULL) { return NULL; }1246if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) {1247jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**) &ckpObject, ckpLength);1248return ckpObject;1249}12501251jIntArrayClass = (*env)->FindClass(env, "[I");1252if (jIntArrayClass == NULL) { return NULL; }1253if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) {1254jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*) &ckpObject, ckpLength);1255return ckpObject;1256}12571258jLongArrayClass = (*env)->FindClass(env, "[J");1259if (jLongArrayClass == NULL) { return NULL; }1260if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) {1261jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*) &ckpObject, ckpLength);1262return ckpObject;1263}12641265jStringClass = (*env)->FindClass(env, "java/lang/String");1266if (jStringClass == NULL) { return NULL; }1267if ((*env)->IsInstanceOf(env, jObject, jStringClass)) {1268jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*) &ckpObject, ckpLength);1269return ckpObject;1270}12711272/* type of jObject unknown, throw PKCS11RuntimeException */1273jObjectClass = (*env)->FindClass(env, "java/lang/Object");1274if (jObjectClass == NULL) { return NULL; }1275jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;");1276if (jMethod == NULL) { return NULL; }1277jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod);1278assert(jClassObject != 0);1279jClassClass = (*env)->FindClass(env, "java/lang/Class");1280if (jClassClass == NULL) { return NULL; }1281jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;");1282if (jMethod == NULL) { return NULL; }1283jClassNameString = (jstring)1284(*env)->CallObjectMethod(env, jClassObject, jMethod);1285assert(jClassNameString != 0);1286classNameString = (char*)1287(*env)->GetStringUTFChars(env, jClassNameString, NULL);1288if (classNameString == NULL) { return NULL; }1289exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: ";1290exceptionMsg = (char *)1291malloc(strlen(exceptionMsgPrefix) + strlen(classNameString) + 1);1292if (exceptionMsg == NULL) {1293(*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);1294throwOutOfMemoryError(env, 0);1295return NULL;1296}1297strcpy(exceptionMsg, exceptionMsgPrefix);1298strcat(exceptionMsg, classNameString);1299(*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString);1300throwPKCS11RuntimeException(env, exceptionMsg);1301free(exceptionMsg);1302*ckpLength = 0;13031304TRACE0("FINISHED\n");1305return NULL;1306}13071308#ifdef P11_MEMORYDEBUG13091310#undef malloc1311#undef calloc1312#undef free13131314void *p11malloc(size_t c, char *file, int line) {1315void *p = malloc(c);1316fprintf(stdout, "malloc\t%08lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, file, line);1317fflush(stdout);1318return p;1319}13201321void *p11calloc(size_t c, size_t s, char *file, int line) {1322void *p = calloc(c, s);1323fprintf(stdout, "calloc\t%08lX\t%lX\t%lX\t%s:%d\n", ptr_to_jlong(p), c, s, file, line);1324fflush(stdout);1325return p;1326}13271328void p11free(void *p, char *file, int line) {1329fprintf(stdout, "free\t%08lX\t\t%s:%d\n", ptr_to_jlong(p), file, line);1330fflush(stdout);1331free(p);1332}13331334#endif13351336// prints a message to stdout if debug output is enabled1337void printDebug(const char *format, ...) {1338if (debug == JNI_TRUE) {1339va_list args;1340fprintf(stdout, "sunpkcs11: ");1341va_start(args, format);1342vfprintf(stdout, format, args);1343va_end(args);1344fflush(stdout);1345}1346}1347134813491350