diff -r c0b3077af726 -r e5d5f0f2d40d jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c --- a/jdk/src/jdk.crypto.pkcs11/share/native/libj2pkcs11/p11_mutex.c Tue Dec 06 14:54:11 2016 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,552 +0,0 @@ -/* - * Copyright (c) 2003, 2016, 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 initArgs that enable the application to do custom mutex-handling */ -#ifndef NO_CALLBACKS -jobject jInitArgsObject; -CK_C_INITIALIZE_ARGS_PTR ckpGlobalInitArgs; -#endif /* NO_CALLBACKS */ - -/* ************************************************************************** */ -/* Now come the functions for mutex handling and notification callbacks */ -/* ************************************************************************** */ - -/* - * converts the InitArgs object to a CK_C_INITIALIZE_ARGS structure and sets the functions - * that will call the right Java mutex functions - * - * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields - * @param pInitArgs - the InitArgs object with the Java mutex functions to call - * @return - the pointer to the CK_C_INITIALIZE_ARGS structure with the functions that will call - * the corresponding Java functions - */ -CK_C_INITIALIZE_ARGS_PTR makeCKInitArgsAdapter(JNIEnv *env, jobject jInitArgs) -{ - CK_C_INITIALIZE_ARGS_PTR ckpInitArgs; - jclass jInitArgsClass; - jfieldID fieldID; - jlong jFlags; - jobject jReserved; - CK_ULONG ckReservedLength; -#ifndef NO_CALLBACKS - jobject jMutexHandler; -#endif /* NO_CALLBACKS */ - - if(jInitArgs == NULL) { - return NULL_PTR; - } - - /* convert the Java InitArgs object to a pointer to a CK_C_INITIALIZE_ARGS structure */ - ckpInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS)); - if (ckpInitArgs == NULL) { - throwOutOfMemoryError(env, 0); - return NULL_PTR; - } - ckpInitArgs->flags = (CK_FLAGS)0; - ckpInitArgs->pReserved = (CK_VOID_PTR)NULL; - - /* Set the mutex functions that will call the Java mutex functions, but - * only set it, if the field is not null. - */ - jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS); - if (jInitArgsClass == NULL) { - free(ckpInitArgs); - return NULL; - } - -#ifdef NO_CALLBACKS - ckpInitArgs->CreateMutex = NULL_PTR; - ckpInitArgs->DestroyMutex = NULL_PTR; - ckpInitArgs->LockMutex = NULL_PTR; - ckpInitArgs->UnlockMutex = NULL_PTR; -#else - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;"); - if (fieldID == NULL) { - free(ckpInitArgs); - return NULL; - } - jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID); - ckpInitArgs->CreateMutex = (jMutexHandler != NULL) ? &callJCreateMutex : NULL_PTR; - - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "DestroyMutex", "Lsun/security/pkcs11/wrapper/CK_DESTROYMUTEX;"); - if (fieldID == NULL) { - free(ckpInitArgs); - return NULL; - } - jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID); - ckpInitArgs->DestroyMutex = (jMutexHandler != NULL) ? &callJDestroyMutex : NULL_PTR; - - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;"); - if (fieldID == NULL) { - free(ckpInitArgs); - return NULL; - } - jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID); - ckpInitArgs->LockMutex = (jMutexHandler != NULL) ? &callJLockMutex : NULL_PTR; - - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "UnlockMutex", "Lsun/security/pkcs11/wrapper/CK_UNLOCKMUTEX;"); - if (fieldID == NULL) { - free(ckpInitArgs); - return NULL; - } - jMutexHandler = (*env)->GetObjectField(env, jInitArgs, fieldID); - ckpInitArgs->UnlockMutex = (jMutexHandler != NULL) ? &callJUnlockMutex : NULL_PTR; - - if ((ckpInitArgs->CreateMutex != NULL_PTR) - || (ckpInitArgs->DestroyMutex != NULL_PTR) - || (ckpInitArgs->LockMutex != NULL_PTR) - || (ckpInitArgs->UnlockMutex != NULL_PTR)) { - /* we only need to keep a global copy, if we need callbacks */ - /* set the global object jInitArgs so that the right Java mutex functions will be called */ - jInitArgsObject = (*env)->NewGlobalRef(env, jInitArgs); - ckpGlobalInitArgs = (CK_C_INITIALIZE_ARGS_PTR) malloc(sizeof(CK_C_INITIALIZE_ARGS)); - if (ckpGlobalInitArgs == NULL) { - free(ckpInitArgs); - throwOutOfMemoryError(env, 0); - return NULL_PTR; - } - - memcpy(ckpGlobalInitArgs, ckpInitArgs, sizeof(CK_C_INITIALIZE_ARGS)); - } -#endif /* NO_CALLBACKS */ - - /* convert and set the flags field */ - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J"); - if (fieldID == NULL) { - free(ckpInitArgs); - return NULL; - } - jFlags = (*env)->GetLongField(env, jInitArgs, fieldID); - ckpInitArgs->flags = jLongToCKULong(jFlags); - - /* pReserved should be NULL_PTR in this version */ - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "pReserved", "Ljava/lang/Object;"); - if (fieldID == NULL) { - free(ckpInitArgs); - return NULL; - } - jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID); - - /* we try to convert the reserved parameter also */ - jObjectToPrimitiveCKObjectPtrPtr(env, jReserved, &(ckpInitArgs->pReserved), &ckReservedLength); - - return ckpInitArgs ; -} - -#ifndef NO_CALLBACKS - -/* - * is the function that gets called by PKCS#11 to create a mutex and calls the Java - * CreateMutex function - * - * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields - * @param ppMutex - the new created mutex - * @return - should return CKR_OK if the mutex creation was ok - */ -CK_RV callJCreateMutex(CK_VOID_PTR_PTR ppMutex) -{ - extern JavaVM *jvm; - JNIEnv *env; - jint returnValue; - jthrowable pkcs11Exception; - jclass pkcs11ExceptionClass; - jlong errorCode; - CK_RV rv = CKR_OK; - int wasAttached = 1; - jclass jCreateMutexClass; - jclass jInitArgsClass; - jmethodID methodID; - jfieldID fieldID; - jobject jCreateMutex; - 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; - } - - jCreateMutexClass = (*env)->FindClass(env, CLASS_CREATEMUTEX); - if (jCreateMutexClass == NULL) { return rv; } - jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS); - if (jInitArgsClass == NULL) { return rv; } - - /* get the CreateMutex object out of the jInitArgs object */ - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "CreateMutex", "Lsun/security/pkcs11/wrapper/CK_CREATEMUTEX;"); - if (fieldID == NULL) { return rv; } - jCreateMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID); - assert(jCreateMutex != 0); - - /* call the CK_CREATEMUTEX function of the CreateMutex object */ - /* and get the new Java mutex object */ - methodID = (*env)->GetMethodID(env, jCreateMutexClass, "CK_CREATEMUTEX", "()Ljava/lang/Object;"); - if (methodID == NULL) { return rv; } - jMutex = (*env)->CallObjectMethod(env, jCreateMutex, methodID); - - /* set a global reference on the Java mutex */ - jMutex = (*env)->NewGlobalRef(env, jMutex); - /* convert the Java mutex to a CK mutex */ - *ppMutex = jObjectToCKVoidPtr(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 ; -} - -/* - * 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 ; -} - -/* - * is the function that gets called by PKCS#11 to lock a mutex and calls the Java - * LockMutex function - * - * @param env - used to call JNI funktions to get the Java classes, objects, methods and fields - * @param pMutex - the mutex to lock - * @return - should return CKR_OK if the mutex was not locked already - */ -CK_RV callJLockMutex(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 jLockMutexClass; - jclass jInitArgsClass; - jmethodID methodID; - jfieldID fieldID; - jobject jLockMutex; - 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; - } - - jLockMutexClass = (*env)->FindClass(env, CLASS_LOCKMUTEX); - if (jLockMutexClass == 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 LockMutex object out of the jInitArgs object */ - fieldID = (*env)->GetFieldID(env, jInitArgsClass, "LockMutex", "Lsun/security/pkcs11/wrapper/CK_LOCKMUTEX;"); - if (fieldID == NULL) { return rv; } - jLockMutex = (*env)->GetObjectField(env, jInitArgsObject, fieldID); - assert(jLockMutex != 0); - - /* call the CK_LOCKMUTEX method of the LockMutex object */ - methodID = (*env)->GetMethodID(env, jLockMutexClass, "CK_LOCKMUTEX", "(Ljava/lang/Object;)V"); - if (methodID == NULL) { return rv; } - (*env)->CallVoidMethod(env, jLockMutex, methodID, 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 ; -} - -/* - * 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) -{ - extern JavaVM *jvm; - JNIEnv *env; - 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 */ - 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; - } - - jUnlockMutexClass = (*env)->FindClass(env, CLASS_UNLOCKMUTEX); - if (jUnlockMutexClass == NULL) { return rv; } - jInitArgsClass = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS); - if (jInitArgsClass == NULL) { return rv; } - - /* 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;"); - if (fieldID == NULL) { return rv; } - 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"); - if (methodID == NULL) { return rv; } - (*env)->CallVoidMethod(env, jUnlockMutex, methodID, 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 ; -} - -#endif /* NO_CALLBACKS */