--- old/src/jdk.crypto.token/share/native/libj2pkcs11/p11_sessmgmt.c 2017-01-18 23:07:03.759886051 -0800 +++ /dev/null 2017-01-18 09:30:05.425422781 -0800 @@ -1,634 +0,0 @@ -/* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. - */ - -/* Copyright (c) 2002 Graz University of Technology. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: - * - * "This product includes software developed by IAIK of Graz University of - * Technology." - * - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Graz University of Technology" and "IAIK of Graz University of - * Technology" must not be used to endorse or promote products derived from - * this software without prior written permission. - * - * 5. Products derived from this software may not be called - * "IAIK PKCS Wrapper", nor may "IAIK" appear in their name, without prior - * written permission of Graz University of Technology. - * - * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE LICENSOR BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "pkcs11wrapper.h" - -#include -#include -#include -#include - -#include "sun_security_pkcs11_wrapper_PKCS11.h" - -/* The list of notify callback handles that are currently active and waiting - * for callbacks from their sessions. - */ -#ifndef NO_CALLBACKS -NotifyListNode *notifyListHead = NULL; -jobject notifyListLock = NULL; -#endif /* NO_CALLBACKS */ - -#ifdef P11_ENABLE_C_OPENSESSION -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_OpenSession - * Signature: (JJLjava/lang/Object;Lsun/security/pkcs11/wrapper/CK_NOTIFY;)J - * Parametermapping: *PKCS11* - * @param jlong jSlotID CK_SLOT_ID slotID - * @param jlong jFlags CK_FLAGS flags - * @param jobject jApplication CK_VOID_PTR pApplication - * @param jobject jNotify CK_NOTIFY Notify - * @return jlong jSessionHandle CK_SESSION_HANDLE_PTR phSession - */ -JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1OpenSession - (JNIEnv *env, jobject obj, jlong jSlotID, jlong jFlags, jobject jApplication, jobject jNotify) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_SLOT_ID ckSlotID; - CK_FLAGS ckFlags; - CK_VOID_PTR ckpApplication; - CK_NOTIFY ckNotify; - jlong jSessionHandle; - CK_RV rv; -#ifndef NO_CALLBACKS - NotifyEncapsulation *notifyEncapsulation = NULL; -#endif /* NO_CALLBACKS */ - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return 0L; } - - ckSlotID = jLongToCKULong(jSlotID); - ckFlags = jLongToCKULong(jFlags); - -#ifndef NO_CALLBACKS - if (jNotify != NULL) { - notifyEncapsulation = (NotifyEncapsulation *) malloc(sizeof(NotifyEncapsulation)); - if (notifyEncapsulation == NULL) { - throwOutOfMemoryError(env, 0); - return 0L; - } - notifyEncapsulation->jApplicationData = (jApplication != NULL) - ? (*env)->NewGlobalRef(env, jApplication) - : NULL; - notifyEncapsulation->jNotifyObject = (*env)->NewGlobalRef(env, jNotify); - ckpApplication = notifyEncapsulation; - ckNotify = (CK_NOTIFY) ¬ifyCallback; - } else { - ckpApplication = NULL_PTR; - ckNotify = NULL_PTR; - } -#else - ckpApplication = NULL_PTR; - ckNotify = NULL_PTR; -#endif /* NO_CALLBACKS */ - - TRACE0("DEBUG: C_OpenSession"); - TRACE1(", slotID=%u", ckSlotID); - TRACE1(", flags=%x", ckFlags); - TRACE0(" ... "); - - rv = (*ckpFunctions->C_OpenSession)(ckSlotID, ckFlags, ckpApplication, ckNotify, &ckSessionHandle); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { -#ifndef NO_CALLBACKS - if (notifyEncapsulation != NULL) { - if (notifyEncapsulation->jApplicationData != NULL) { - (*env)->DeleteGlobalRef(env, jApplication); - } - (*env)->DeleteGlobalRef(env, jNotify); - free(notifyEncapsulation); - } -#endif /* NO_CALLBACKS */ - return 0L; - } - - TRACE0("got session"); - TRACE1(", SessionHandle=%u", ckSessionHandle); - TRACE0(" ... "); - - jSessionHandle = ckULongToJLong(ckSessionHandle); - -#ifndef NO_CALLBACKS - if (notifyEncapsulation != NULL) { - /* store the notifyEncapsulation to enable later cleanup */ - putNotifyEntry(env, ckSessionHandle, notifyEncapsulation); - } -#endif /* NO_CALLBACKS */ - - TRACE0("FINISHED\n"); - - return jSessionHandle ; -} -#endif - -#ifdef P11_ENABLE_C_CLOSESESSION -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_CloseSession - * Signature: (J)V - * Parametermapping: *PKCS11* - * @param jlong jSessionHandle CK_SESSION_HANDLE hSession - */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseSession - (JNIEnv *env, jobject obj, jlong jSessionHandle) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_RV rv; -#ifndef NO_CALLBACKS - NotifyEncapsulation *notifyEncapsulation; - jobject jApplicationData; -#endif /* NO_CALLBACKS */ - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return; } - - ckSessionHandle = jLongToCKULong(jSessionHandle); - - rv = (*ckpFunctions->C_CloseSession)(ckSessionHandle); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } - -#ifndef NO_CALLBACKS - notifyEncapsulation = removeNotifyEntry(env, ckSessionHandle); - - if (notifyEncapsulation != NULL) { - /* there was a notify object used with this session, now dump the - * encapsulation object - */ - (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject); - jApplicationData = notifyEncapsulation->jApplicationData; - if (jApplicationData != NULL) { - (*env)->DeleteGlobalRef(env, jApplicationData); - } - free(notifyEncapsulation); - } -#endif /* NO_CALLBACKS */ - -} -#endif - -#ifdef P11_ENABLE_C_CLOSEALLSESSIONS -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_CloseAllSessions - * Signature: (J)V - * Parametermapping: *PKCS11* - * @param jlong jSlotID CK_SLOT_ID slotID - */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CloseAllSessions - (JNIEnv *env, jobject obj, jlong jSlotID) -{ - CK_SLOT_ID ckSlotID; - CK_RV rv; -#ifndef NO_CALLBACKS - NotifyEncapsulation *notifyEncapsulation; - jobject jApplicationData; -#endif /* NO_CALLBACKS */ - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return; } - - ckSlotID = jLongToCKULong(jSlotID); - - rv = (*ckpFunctions->C_CloseAllSessions)(ckSlotID); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } - -#ifndef NO_CALLBACKS - /* Remove all notify callback helper objects. */ - while ((notifyEncapsulation = removeFirstNotifyEntry(env)) != NULL) { - /* there was a notify object used with this session, now dump the - * encapsulation object - */ - (*env)->DeleteGlobalRef(env, notifyEncapsulation->jNotifyObject); - jApplicationData = notifyEncapsulation->jApplicationData; - if (jApplicationData != NULL) { - (*env)->DeleteGlobalRef(env, jApplicationData); - } - free(notifyEncapsulation); - } -#endif /* NO_CALLBACKS */ -} -#endif - -#ifdef P11_ENABLE_C_GETSESSIONINFO -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_GetSessionInfo - * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SESSION_INFO; - * Parametermapping: *PKCS11* - * @param jlong jSessionHandle CK_SESSION_HANDLE hSession - * @return jobject jSessionInfo CK_SESSION_INFO_PTR pInfo - */ -JNIEXPORT jobject JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSessionInfo - (JNIEnv *env, jobject obj, jlong jSessionHandle) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_SESSION_INFO ckSessionInfo; - jobject jSessionInfo=NULL; - CK_RV rv; - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return NULL; } - - ckSessionHandle = jLongToCKULong(jSessionHandle); - - rv = (*ckpFunctions->C_GetSessionInfo)(ckSessionHandle, &ckSessionInfo); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - jSessionInfo = ckSessionInfoPtrToJSessionInfo(env, &ckSessionInfo); - } - return jSessionInfo ; -} -#endif - -#ifdef P11_ENABLE_C_GETOPERATIONSTATE -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_GetOperationState - * Signature: (J)[B - * Parametermapping: *PKCS11* - * @param jlong jSessionHandle CK_SESSION_HANDLE hSession - * @return jbyteArray jState CK_BYTE_PTR pOperationState - * CK_ULONG_PTR pulOperationStateLen - */ -JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetOperationState - (JNIEnv *env, jobject obj, jlong jSessionHandle) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_BYTE_PTR ckpState; - CK_ULONG ckStateLength; - jbyteArray jState = NULL; - CK_RV rv; - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return NULL; } - - ckSessionHandle = jLongToCKULong(jSessionHandle); - - rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, NULL_PTR, &ckStateLength); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; } - - ckpState = (CK_BYTE_PTR) malloc(ckStateLength); - if (ckpState == NULL) { - throwOutOfMemoryError(env, 0); - return NULL; - } - - rv = (*ckpFunctions->C_GetOperationState)(ckSessionHandle, ckpState, &ckStateLength); - if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { - jState = ckByteArrayToJByteArray(env, ckpState, ckStateLength); - } - free(ckpState); - - return jState ; -} -#endif - -#ifdef P11_ENABLE_C_SETOPERATIONSTATE -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_SetOperationState - * Signature: (J[BJJ)V - * Parametermapping: *PKCS11* - * @param jlong jSessionHandle CK_SESSION_HANDLE hSession - * @param jbyteArray jOperationState CK_BYTE_PTR pOperationState - * CK_ULONG ulOperationStateLen - * @param jlong jEncryptionKeyHandle CK_OBJECT_HANDLE hEncryptionKey - * @param jlong jAuthenticationKeyHandle CK_OBJECT_HANDLE hAuthenticationKey - */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState - (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jOperationState, jlong jEncryptionKeyHandle, jlong jAuthenticationKeyHandle) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_BYTE_PTR ckpState = NULL_PTR; - CK_ULONG ckStateLength; - CK_OBJECT_HANDLE ckEncryptionKeyHandle; - CK_OBJECT_HANDLE ckAuthenticationKeyHandle; - CK_RV rv; - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return; } - - ckSessionHandle = jLongToCKULong(jSessionHandle); - jByteArrayToCKByteArray(env, jOperationState, &ckpState, &ckStateLength); - if ((*env)->ExceptionCheck(env)) { return; } - - ckEncryptionKeyHandle = jLongToCKULong(jEncryptionKeyHandle); - ckAuthenticationKeyHandle = jLongToCKULong(jAuthenticationKeyHandle); - - rv = (*ckpFunctions->C_SetOperationState)(ckSessionHandle, ckpState, ckStateLength, ckEncryptionKeyHandle, ckAuthenticationKeyHandle); - - free(ckpState); - - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } -} -#endif - -#ifdef P11_ENABLE_C_LOGIN -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_Login - * Signature: (JJ[C)V - * Parametermapping: *PKCS11* - * @param jlong jSessionHandle CK_SESSION_HANDLE hSession - * @param jlong jUserType CK_USER_TYPE userType - * @param jcharArray jPin CK_CHAR_PTR pPin - * CK_ULONG ulPinLen - */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Login - (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jUserType, jcharArray jPin) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_USER_TYPE ckUserType; - CK_CHAR_PTR ckpPinArray = NULL_PTR; - CK_ULONG ckPinLength; - CK_RV rv; - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return; } - - ckSessionHandle = jLongToCKULong(jSessionHandle); - ckUserType = jLongToCKULong(jUserType); - jCharArrayToCKCharArray(env, jPin, &ckpPinArray, &ckPinLength); - if ((*env)->ExceptionCheck(env)) { return; } - - rv = (*ckpFunctions->C_Login)(ckSessionHandle, ckUserType, ckpPinArray, ckPinLength); - - free(ckpPinArray); - - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } -} -#endif - -#ifdef P11_ENABLE_C_LOGOUT -/* - * Class: sun_security_pkcs11_wrapper_PKCS11 - * Method: C_Logout - * Signature: (J)V - * Parametermapping: *PKCS11* - * @param jlong jSessionHandle CK_SESSION_HANDLE hSession - */ -JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Logout - (JNIEnv *env, jobject obj, jlong jSessionHandle) -{ - CK_SESSION_HANDLE ckSessionHandle; - CK_RV rv; - - CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); - if (ckpFunctions == NULL) { return; } - - ckSessionHandle = jLongToCKULong(jSessionHandle); - - rv = (*ckpFunctions->C_Logout)(ckSessionHandle); - if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } -} -#endif - -/* ************************************************************************** */ -/* Functions for keeping track of notify callbacks */ -/* ************************************************************************** */ - -#ifndef NO_CALLBACKS - -/* - * Add the given notify encapsulation object to the list of active notify - * objects. - * If notifyEncapsulation is NULL, this function does nothing. - */ -void putNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession, NotifyEncapsulation *notifyEncapsulation) { - NotifyListNode *currentNode, *newNode; - - if (notifyEncapsulation == NULL) { - return; - } - - newNode = (NotifyListNode *) malloc(sizeof(NotifyListNode)); - if (newNode == NULL) { - throwOutOfMemoryError(env, 0); - return; - } - newNode->hSession = hSession; - newNode->notifyEncapsulation = notifyEncapsulation; - newNode->next = NULL; - - (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */ - - if (notifyListHead == NULL) { - /* this is the first entry */ - notifyListHead = newNode; - } else { - /* go to the last entry; i.e. the first node which's 'next' is NULL. - */ - currentNode = notifyListHead; - while (currentNode->next != NULL) { - currentNode = currentNode->next; - } - currentNode->next = newNode; - } - - (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */ -} - -/* - * Removes the active notifyEncapsulation object used with the given session and - * returns it. If there is no notifyEncapsulation active for this session, this - * function returns NULL. - */ -NotifyEncapsulation * removeNotifyEntry(JNIEnv *env, CK_SESSION_HANDLE hSession) { - NotifyEncapsulation *notifyEncapsulation; - NotifyListNode *currentNode, *previousNode; - - (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */ - - if (notifyListHead == NULL) { - /* this is the first entry */ - notifyEncapsulation = NULL; - } else { - /* Find the node with the wanted session handle. Also stop, when we reach - * the last entry; i.e. the first node which's 'next' is NULL. - */ - currentNode = notifyListHead; - previousNode = NULL; - - while ((currentNode->hSession != hSession) && (currentNode->next != NULL)) { - previousNode = currentNode; - currentNode = currentNode->next; - } - - if (currentNode->hSession == hSession) { - /* We found a entry for the wanted session, now remove it. */ - if (previousNode == NULL) { - /* it's the first node */ - notifyListHead = currentNode->next; - } else { - previousNode->next = currentNode->next; - } - notifyEncapsulation = currentNode->notifyEncapsulation; - free(currentNode); - } else { - /* We did not find a entry for this session */ - notifyEncapsulation = NULL; - } - } - - (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */ - - return notifyEncapsulation ; -} - -/* - - * Removes the first notifyEncapsulation object. If there is no notifyEncapsulation, - * this function returns NULL. - */ -NotifyEncapsulation * removeFirstNotifyEntry(JNIEnv *env) { - NotifyEncapsulation *notifyEncapsulation; - NotifyListNode *currentNode; - - (*env)->MonitorEnter(env, notifyListLock); /* synchronize access to list */ - - if (notifyListHead == NULL) { - /* this is the first entry */ - notifyEncapsulation = NULL; - } else { - /* Remove the first entry. */ - currentNode = notifyListHead; - notifyListHead = notifyListHead->next; - notifyEncapsulation = currentNode->notifyEncapsulation; - free(currentNode); - } - - (*env)->MonitorExit(env, notifyListLock); /* synchronize access to list */ - - return notifyEncapsulation ; -} - -#endif /* NO_CALLBACKS */ - -#ifndef NO_CALLBACKS - -/* - * The function handling notify callbacks. It casts the pApplication parameter - * back to a NotifyEncapsulation structure and retrieves the Notify object and - * the application data from it. - * - * @param hSession The session, this callback is comming from. - * @param event The type of event that occurred. - * @param pApplication The application data as passed in upon OpenSession. In - this wrapper we always pass in a NotifyEncapsulation - object, which holds necessary information for delegating - the callback to the Java VM. - * @return - */ -CK_RV notifyCallback( - CK_SESSION_HANDLE hSession, /* the session's handle */ - CK_NOTIFICATION event, - CK_VOID_PTR pApplication /* passed to C_OpenSession */ -) -{ - NotifyEncapsulation *notifyEncapsulation; - extern JavaVM *jvm; - JNIEnv *env; - jint returnValue; - jlong jSessionHandle; - jlong jEvent; - jclass ckNotifyClass; - jmethodID jmethod; - jthrowable pkcs11Exception; - jclass pkcs11ExceptionClass; - jlong errorCode; - CK_RV rv = CKR_OK; - int wasAttached = 1; - - if (pApplication == NULL) { return rv ; } /* This should not occur in this wrapper. */ - - notifyEncapsulation = (NotifyEncapsulation *) pApplication; - - /* Get the currently running Java VM */ - if (jvm == NULL) { return rv ; } /* there is no VM running */ - - /* Determine, if current thread is already attached */ - returnValue = (*jvm)->GetEnv(jvm, (void **) &env, JNI_VERSION_1_2); - if (returnValue == JNI_EDETACHED) { - /* thread detached, so attach it */ - wasAttached = 0; - returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL); - } else if (returnValue == JNI_EVERSION) { - /* this version of JNI is not supported, so just try to attach */ - /* we assume it was attached to ensure that this thread is not detached - * afterwards even though it should not - */ - wasAttached = 1; - returnValue = (*jvm)->AttachCurrentThread(jvm, (void **) &env, NULL); - } else { - /* attached */ - wasAttached = 1; - } - - jSessionHandle = ckULongToJLong(hSession); - jEvent = ckULongToJLong(event); - - ckNotifyClass = (*env)->FindClass(env, CLASS_NOTIFY); - if (ckNotifyClass == NULL) { return rv; } - jmethod = (*env)->GetMethodID(env, ckNotifyClass, "CK_NOTIFY", "(JJLjava/lang/Object;)V"); - if (jmethod == NULL) { return rv; } - - (*env)->CallVoidMethod(env, notifyEncapsulation->jNotifyObject, jmethod, - jSessionHandle, jEvent, notifyEncapsulation->jApplicationData); - - /* check, if callback threw an exception */ - pkcs11Exception = (*env)->ExceptionOccurred(env); - - if (pkcs11Exception != NULL) { - /* TBD: clear the pending exception with ExceptionClear? */ - /* The was an exception thrown, now we get the error-code from it */ - pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION); - if (pkcs11ExceptionClass == NULL) { return rv; } - - jmethod = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J"); - if (jmethod == NULL) { return rv; } - - errorCode = (*env)->CallLongMethod(env, pkcs11Exception, jmethod); - rv = jLongToCKULong(errorCode); - } - - /* if we attached this thread to the VM just for callback, we detach it now */ - if (wasAttached) { - returnValue = (*jvm)->DetachCurrentThread(jvm); - } - - return rv ; -} - -#endif /* NO_CALLBACKS */