/* * is the function that gets called by PKCS#11 to unlock a mutex and calls the Java * UnlockMutex function * * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields * @param pMutex - the mutex to unlock * @return - should return CKR_OK if the mutex was not unlocked already */ CK_RV callJUnlockMutex(CK_VOID_PTR pMutex) { JavaVM *jvm; JNIEnv *env; jsize actualNumberVMs; jint returnValue; jthrowable pkcs11Exception; jclass pkcs11ExceptionClass; jlong errorCode; CK_RV rv = CKR_OK; int wasAttached = 1; jclass jUnlockMutexClass; jclass jInitArgsClass; jmethodID methodID; jfieldID fieldID; jobject jUnlockMutex; jobject jMutex; /* Get the currently running Java VM */ returnValue = JNI_GetCreatedJavaVMs(&jvm, (jsize) 1, &actualNumberVMs); if ((returnValue != 0) || (actualNumberVMs <= 0)) { 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; } jUnlockMutexClass = (*env)->FindClass(env, CLASS_UNLOCKMUTEX); jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS); /* convert the CK-type mutex to a Java mutex */ jMutex = ckVoidPtrToJObject(pMutex); /* get the UnlockMutex object out of the jInitArgs object */ fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;"); assert(fieldID != 0); jUnlockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID); assert(jUnlockMutex != 0); /* call the CK_UNLOCKMUTEX method of the UnLockMutex object */ methodID = (*env)->GetMethodID(env, jUnlockMutexClass, "CK_UNLOCKMUTEX", "(Ljava/lang/Object;)V"); assert(methodID != 0); (*env)->CallVoidMethod(env, jUnlockMutex, methodID, jMutex); /* check, if callback threw an exception */ pkcs11Exception = (*env)->ExceptionOccurred(env); if (pkcs11Exception != NULL) { /* The was an exception thrown, now we get the error-code from it */ pkcs11ExceptionClass = (*env)->FindClass(env, CLASS_PKCS11EXCEPTION); methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J"); assert(methodID != 0); errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID); 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 ; }
/* * is the function that gets called by PKCS#11 to destroy a mutex and calls the Java * DestroyMutex function * * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields * @param pMutex - the mutex to destroy * @return - should return CKR_OK if the mutex was destroyed */ CK_RV callJDestroyMutex(CK_VOID_PTR pMutex) { extern JavaVM *jvm; JNIEnv *env; jint returnValue; jthrowable pkcs11Exception; jclass pkcs11ExceptionClass; jlong errorCode; CK_RV rv = CKR_OK; int wasAttached = 1; jclass jDestroyMutexClass; jclass jInitArgsClass; jmethodID methodID; jfieldID fieldID; jobject jDestroyMutex; jobject jMutex; /* 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; } jDestroyMutexClass = (*env)->FindClass(env, CLASS_DESTROYMUTEX); if (jDestroyMutexClass == NULL) { return rv; } jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS); if (jInitArgsClass == NULL) { return rv; } /* convert the CK mutex to a Java mutex */ jMutex = ckVoidPtrToJObject(pMutex); /* get the DestroyMutex object out of the jInitArgs object */ fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;"); if (fieldID == NULL) { return rv; } jDestroyMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID); assert(jDestroyMutex != 0); /* call the CK_DESTROYMUTEX method of the DestroyMutex object */ methodID = (*env)->GetMethodID(env, jDestroyMutexClass, "CK_DESTROYMUTEX", "(Ljava/lang/Object;)V"); if (methodID == NULL) { return rv; } (*env)->CallVoidMethod(env, jDestroyMutex, methodID, jMutex); /* delete the global reference on the Java mutex */ (*env)->DeleteGlobalRef(env, jMutex); /* 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; } methodID = (*env)->GetMethodID(env, pkcs11ExceptionClass, "getErrorCode", "()J"); if (methodID == NULL) { return rv; } errorCode = (*env)->CallLongMethod(env, pkcs11Exception, methodID); 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 ; }