--- /dev/null 2017-01-18 09:30:05.425422781 -0800 +++ new/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_general.c 2017-01-18 23:07:37.731884769 -0800 @@ -0,0 +1,881 @@ +/* + * 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" + +/* declare file private functions */ + +void prefetchFields(JNIEnv *env, jclass thisClass); +jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo); +jobject ckSlotInfoPtrToJSlotInfo(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo); +jobject ckTokenInfoPtrToJTokenInfo(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo); +jobject ckMechanismInfoPtrToJMechanismInfo(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo); + +/* define variables */ + +jfieldID pNativeDataID; +jfieldID mech_mechanismID; +jfieldID mech_pParameterID; + +jclass jByteArrayClass; +jclass jLongClass; + +JavaVM* jvm = NULL; + +jboolean debug = 0; + +JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) { + jvm = vm; + return JNI_VERSION_1_4; +} + +/* ************************************************************************** */ +/* The native implementation of the methods of the PKCS11Implementation class */ +/* ************************************************************************** */ + +/* + * This method is used to do static initialization. This method is static and + * synchronized. Summary: use this method like a static initialization block. + * + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: initializeLibrary + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_initializeLibrary +(JNIEnv *env, jclass thisClass, jboolean enableDebug) +{ +#ifndef NO_CALLBACKS + if (notifyListLock == NULL) { + notifyListLock = createLockObject(env); + } +#endif + + prefetchFields(env, thisClass); + debug = enableDebug; +} + +jclass fetchClass(JNIEnv *env, const char *name) { + jclass tmpClass = (*env)->FindClass(env, name); + if (tmpClass == NULL) { return NULL; } + return (*env)->NewGlobalRef(env, tmpClass); +} + +void prefetchFields(JNIEnv *env, jclass thisClass) { + jclass tmpClass; + + /* PKCS11 */ + pNativeDataID = (*env)->GetFieldID(env, thisClass, "pNativeData", "J"); + if (pNativeDataID == NULL) { return; } + + /* CK_MECHANISM */ + tmpClass = (*env)->FindClass(env, CLASS_MECHANISM); + if (tmpClass == NULL) { return; } + mech_mechanismID = (*env)->GetFieldID(env, tmpClass, "mechanism", "J"); + if (mech_mechanismID == NULL) { return; } + mech_pParameterID = (*env)->GetFieldID(env, tmpClass, "pParameter", + "Ljava/lang/Object;"); + if (mech_pParameterID == NULL) { return; } + jByteArrayClass = fetchClass(env, "[B"); + if (jByteArrayClass == NULL) { return; } + jLongClass = fetchClass(env, "java/lang/Long"); +} + +/* This method is designed to do a clean-up. It releases all global resources + * of this library. By now, this function is not called. Calling from + * JNI_OnUnload would be an option, but some VMs do not support JNI_OnUnload. + * + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: finalizeLibrary + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_finalizeLibrary +(JNIEnv *env, jclass thisClass) +{ +/* XXX + * remove all left lists and release the resources and the lock + * objects that synchroniz access to these lists. + * + removeAllModuleEntries(env); + if (moduleListHead == NULL) { * check, if we removed the last active module * + * remove also the moduleListLock, it is no longer used * + if (moduleListLock != NULL) { + destroyLockObject(env, moduleListLock); + moduleListLock = NULL; + } +#ifndef NO_CALLBACKS + * remove all left notify callback entries * + while (removeFirstNotifyEntry(env)); + * remove also the notifyListLock, it is no longer used * + if (notifyListLock != NULL) { + destroyLockObject(env, notifyListLock); + notifyListLock = NULL; + } + if (jInitArgsObject != NULL) { + (*env)->DeleteGlobalRef(env, jInitArgsObject); + } + if (ckpGlobalInitArgs != NULL_PTR) { + free(ckpGlobalInitArgs); + } +#endif * NO_CALLBACKS * + } +*/ +} + +#ifdef P11_ENABLE_C_INITIALIZE +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_Initialize + * Signature: (Ljava/lang/Object;)V + * Parametermapping: *PKCS11* + * @param jobject jInitArgs CK_VOID_PTR pInitArgs + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1Initialize +(JNIEnv *env, jobject obj, jobject jInitArgs) +{ + /* + * Initalize Cryptoki + */ + CK_C_INITIALIZE_ARGS_PTR ckpInitArgs; + CK_RV rv; + CK_FUNCTION_LIST_PTR ckpFunctions; + + TRACE0("DEBUG: initializing module... "); + + ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { + TRACE0("failed getting module entry"); + return; + } + + ckpInitArgs = (jInitArgs != NULL) + ? makeCKInitArgsAdapter(env, jInitArgs) + : NULL_PTR; + + rv = (*ckpFunctions->C_Initialize)(ckpInitArgs); + + free(ckpInitArgs); + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } + + TRACE0("FINISHED\n"); +} +#endif + +#ifdef P11_ENABLE_C_FINALIZE +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_Finalize + * Signature: (Ljava/lang/Object;)V + * Parametermapping: *PKCS11* + * @param jobject jReserved CK_VOID_PTR pReserved + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1Finalize +(JNIEnv *env, jobject obj, jobject jReserved) +{ + /* + * Finalize Cryptoki + */ + CK_VOID_PTR ckpReserved; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckpReserved = jObjectToCKVoidPtr(jReserved); + + rv = (*ckpFunctions->C_Finalize)(ckpReserved); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_GETINFO +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_GetInfo + * Signature: ()Lsun/security/pkcs11/wrapper/CK_INFO; + * Parametermapping: *PKCS11* + * @return jobject jInfoObject CK_INFO_PTR pInfo + */ +JNIEXPORT jobject JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetInfo +(JNIEnv *env, jobject obj) +{ + CK_INFO ckLibInfo; + jobject jInfoObject=NULL; + CK_RV rv; + CK_FUNCTION_LIST_PTR ckpFunctions; + memset(&ckLibInfo, 0, sizeof(CK_INFO)); + + ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + rv = (*ckpFunctions->C_GetInfo)(&ckLibInfo); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jInfoObject = ckInfoPtrToJInfo(env, &ckLibInfo); + } + return jInfoObject ; +} + +/* + * converts a pointer to a CK_INFO structure into a Java CK_INFO Object. + * + * @param env - used to call JNI funktions to create the new Java object + * @param ckpInfo - the pointer to the CK_INFO structure + * @return - the new Java CK_INFO object + */ +jobject ckInfoPtrToJInfo(JNIEnv *env, const CK_INFO_PTR ckpInfo) +{ + jclass jInfoClass; + jmethodID jCtrId; + jobject jInfoObject; + jobject jCryptokiVer; + jcharArray jVendor; + jlong jFlags; + jcharArray jLibraryDesc; + jobject jLibraryVer; + + /* load CK_INFO class */ + jInfoClass = (*env)->FindClass(env, CLASS_INFO); + if (jInfoClass == NULL) { return NULL; }; + + /* load CK_INFO constructor */ + jCtrId = (*env)->GetMethodID + (env, jInfoClass, "", + "(Lsun/security/pkcs11/wrapper/CK_VERSION;[CJ[CLsun/security/pkcs11/wrapper/CK_VERSION;)V"); + if (jCtrId == NULL) { return NULL; } + + /* prep all fields */ + jCryptokiVer = ckVersionPtrToJVersion(env, &(ckpInfo->cryptokiVersion)); + if (jCryptokiVer == NULL) { return NULL; } + jVendor = + ckUTF8CharArrayToJCharArray(env, &(ckpInfo->manufacturerID[0]), 32); + if (jVendor == NULL) { return NULL; } + jFlags = ckULongToJLong(ckpInfo->flags); + jLibraryDesc = + ckUTF8CharArrayToJCharArray(env, &(ckpInfo->libraryDescription[0]), 32); + if (jLibraryDesc == NULL) { return NULL; } + jLibraryVer = ckVersionPtrToJVersion(env, &(ckpInfo->libraryVersion)); + if (jLibraryVer == NULL) { return NULL; } + + /* create new CK_INFO object */ + jInfoObject = (*env)->NewObject(env, jInfoClass, jCtrId, jCryptokiVer, + jVendor, jFlags, jLibraryDesc, jLibraryVer); + if (jInfoObject == NULL) { return NULL; } + + /* free local references */ + (*env)->DeleteLocalRef(env, jInfoClass); + (*env)->DeleteLocalRef(env, jCryptokiVer); + (*env)->DeleteLocalRef(env, jVendor); + (*env)->DeleteLocalRef(env, jLibraryDesc); + (*env)->DeleteLocalRef(env, jLibraryVer); + + return jInfoObject ; +} +#endif + +#ifdef P11_ENABLE_C_GETSLOTLIST +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_GetSlotList + * Signature: (Z)[J + * Parametermapping: *PKCS11* + * @param jboolean jTokenPresent CK_BBOOL tokenPresent + * @return jlongArray jSlotList CK_SLOT_ID_PTR pSlotList + * CK_ULONG_PTR pulCount + */ +JNIEXPORT jlongArray JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotList +(JNIEnv *env, jobject obj, jboolean jTokenPresent) +{ + CK_ULONG ckTokenNumber; + CK_SLOT_ID_PTR ckpSlotList; + CK_BBOOL ckTokenPresent; + jlongArray jSlotList = NULL; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckTokenPresent = jBooleanToCKBBool(jTokenPresent); + + rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, NULL_PTR, + &ckTokenNumber); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; } + + ckpSlotList = (CK_SLOT_ID_PTR) malloc(ckTokenNumber * sizeof(CK_SLOT_ID)); + if (ckpSlotList == NULL) { + throwOutOfMemoryError(env, 0); + return NULL; + } + + rv = (*ckpFunctions->C_GetSlotList)(ckTokenPresent, ckpSlotList, + &ckTokenNumber); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jSlotList = ckULongArrayToJLongArray(env, ckpSlotList, ckTokenNumber); + } + free(ckpSlotList); + + return jSlotList ; +} +#endif + +#ifdef P11_ENABLE_C_GETSLOTINFO +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_GetSlotInfo + * Signature: (J)Lsun/security/pkcs11/wrapper/CK_SLOT_INFO; + * Parametermapping: *PKCS11* + * @param jlong jSlotID CK_SLOT_ID slotID + * @return jobject jSlotInfoObject CK_SLOT_INFO_PTR pInfo + */ +JNIEXPORT jobject JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetSlotInfo +(JNIEnv *env, jobject obj, jlong jSlotID) +{ + CK_SLOT_ID ckSlotID; + CK_SLOT_INFO ckSlotInfo; + jobject jSlotInfoObject=NULL; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckSlotID = jLongToCKULong(jSlotID); + + rv = (*ckpFunctions->C_GetSlotInfo)(ckSlotID, &ckSlotInfo); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jSlotInfoObject = ckSlotInfoPtrToJSlotInfo(env, &ckSlotInfo); + } + return jSlotInfoObject; +} + +/* + * converts a pointer to a CK_SLOT_INFO structure into a Java CK_SLOT_INFO + * Object. + * + * @param env - used to call JNI funktions to create the new Java object + * @param ckpSlotInfo - the pointer to the CK_SLOT_INFO structure + * @return - the new Java CK_SLOT_INFO object + */ +jobject +ckSlotInfoPtrToJSlotInfo +(JNIEnv *env, const CK_SLOT_INFO_PTR ckpSlotInfo) +{ + jclass jSlotInfoClass; + jmethodID jCtrId; + jobject jSlotInfoObject; + jcharArray jSlotDesc; + jcharArray jVendor; + jlong jFlags; + jobject jHardwareVer; + jobject jFirmwareVer; + + /* load CK_SLOT_INFO class */ + jSlotInfoClass = (*env)->FindClass(env, CLASS_SLOT_INFO); + if (jSlotInfoClass == NULL) { return NULL; }; + + /* load CK_SLOT_INFO constructor */ + jCtrId = (*env)->GetMethodID + (env, jSlotInfoClass, "", + "([C[CJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;)V"); + if (jCtrId == NULL) { return NULL; } + + /* prep all fields */ + jSlotDesc = + ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->slotDescription[0]), 64); + if (jSlotDesc == NULL) { return NULL; } + jVendor = + ckUTF8CharArrayToJCharArray(env, &(ckpSlotInfo->manufacturerID[0]), 32); + if (jVendor == NULL) { return NULL; } + jFlags = ckULongToJLong(ckpSlotInfo->flags); + jHardwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->hardwareVersion)); + if (jHardwareVer == NULL) { return NULL; } + jFirmwareVer = ckVersionPtrToJVersion(env, &(ckpSlotInfo->firmwareVersion)); + if (jFirmwareVer == NULL) { return NULL; } + + /* create new CK_SLOT_INFO object */ + jSlotInfoObject = (*env)->NewObject + (env, jSlotInfoClass, jCtrId, jSlotDesc, jVendor, jFlags, + jHardwareVer, jFirmwareVer); + if (jSlotInfoObject == NULL) { return NULL; } + + /* free local references */ + (*env)->DeleteLocalRef(env, jSlotInfoClass); + (*env)->DeleteLocalRef(env, jSlotDesc); + (*env)->DeleteLocalRef(env, jVendor); + (*env)->DeleteLocalRef(env, jHardwareVer); + (*env)->DeleteLocalRef(env, jFirmwareVer); + + return jSlotInfoObject ; +} + +#endif + +#ifdef P11_ENABLE_C_GETTOKENINFO +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_GetTokenInfo + * Signature: (J)Lsun/security/pkcs11/wrapper/CK_TOKEN_INFO; + * Parametermapping: *PKCS11* + * @param jlong jSlotID CK_SLOT_ID slotID + * @return jobject jInfoTokenObject CK_TOKEN_INFO_PTR pInfo + */ +JNIEXPORT jobject JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetTokenInfo +(JNIEnv *env, jobject obj, jlong jSlotID) +{ + CK_SLOT_ID ckSlotID; + CK_TOKEN_INFO ckTokenInfo; + jobject jInfoTokenObject = NULL; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckSlotID = jLongToCKULong(jSlotID); + + rv = (*ckpFunctions->C_GetTokenInfo)(ckSlotID, &ckTokenInfo); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jInfoTokenObject = ckTokenInfoPtrToJTokenInfo(env, &ckTokenInfo); + } + return jInfoTokenObject ; +} + +/* + * converts a pointer to a CK_TOKEN_INFO structure into a Java CK_TOKEN_INFO + * Object. + * + * @param env - used to call JNI funktions to create the new Java object + * @param ckpTokenInfo - the pointer to the CK_TOKEN_INFO structure + * @return - the new Java CK_TOKEN_INFO object + */ +jobject +ckTokenInfoPtrToJTokenInfo +(JNIEnv *env, const CK_TOKEN_INFO_PTR ckpTokenInfo) +{ + jclass jTokenInfoClass; + jmethodID jCtrId; + jobject jTokenInfoObject; + jcharArray jLabel; + jcharArray jVendor; + jcharArray jModel; + jcharArray jSerialNo; + jlong jFlags; + jlong jMaxSnCnt; + jlong jSnCnt; + jlong jMaxRwSnCnt; + jlong jRwSnCnt; + jlong jMaxPinLen; + jlong jMinPinLen; + jlong jTotalPubMem; + jlong jFreePubMem; + jlong jTotalPrivMem; + jlong jFreePrivMem; + jobject jHardwareVer; + jobject jFirmwareVer; + jcharArray jUtcTime; + + /* load CK_TOKEN_INFO class */ + jTokenInfoClass = (*env)->FindClass(env, CLASS_TOKEN_INFO); + if (jTokenInfoClass == NULL) { return NULL; }; + + /* load CK_TOKEN_INFO constructor */ + jCtrId = (*env)->GetMethodID + (env, jTokenInfoClass, "", + "([C[C[C[CJJJJJJJJJJJLsun/security/pkcs11/wrapper/CK_VERSION;Lsun/security/pkcs11/wrapper/CK_VERSION;[C)V"); + if (jCtrId == NULL) { return NULL; }; + + /* prep all fields */ + jLabel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->label[0]), 32); + if (jLabel == NULL) { return NULL; }; + jVendor = + ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->manufacturerID[0]), 32); + if (jVendor == NULL) { return NULL; }; + jModel = ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->model[0]), 16); + if (jModel == NULL) { return NULL; }; + jSerialNo = + ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->serialNumber[0]), 16); + if (jSerialNo == NULL) { return NULL; }; + jFlags = ckULongToJLong(ckpTokenInfo->flags); + jMaxSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxSessionCount); + jSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulSessionCount); + jMaxRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulMaxRwSessionCount); + jRwSnCnt = ckULongSpecialToJLong(ckpTokenInfo->ulRwSessionCount); + jMaxPinLen = ckULongToJLong(ckpTokenInfo->ulMaxPinLen); + jMinPinLen = ckULongToJLong(ckpTokenInfo->ulMinPinLen); + jTotalPubMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPublicMemory); + jFreePubMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePublicMemory); + jTotalPrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulTotalPrivateMemory); + jFreePrivMem = ckULongSpecialToJLong(ckpTokenInfo->ulFreePrivateMemory); + jHardwareVer = + ckVersionPtrToJVersion(env, &(ckpTokenInfo->hardwareVersion)); + if (jHardwareVer == NULL) { return NULL; } + jFirmwareVer = + ckVersionPtrToJVersion(env, &(ckpTokenInfo->firmwareVersion)); + if (jFirmwareVer == NULL) { return NULL; } + jUtcTime = + ckUTF8CharArrayToJCharArray(env, &(ckpTokenInfo->utcTime[0]), 16); + if (jUtcTime == NULL) { return NULL; } + + /* create new CK_TOKEN_INFO object */ + jTokenInfoObject = + (*env)->NewObject(env, jTokenInfoClass, jCtrId, jLabel, jVendor, jModel, + jSerialNo, jFlags, + jMaxSnCnt, jSnCnt, jMaxRwSnCnt, jRwSnCnt, + jMaxPinLen, jMinPinLen, + jTotalPubMem, jFreePubMem, jTotalPrivMem, jFreePrivMem, + jHardwareVer, jFirmwareVer, jUtcTime); + if (jTokenInfoObject == NULL) { return NULL; } + + /* free local references */ + (*env)->DeleteLocalRef(env, jTokenInfoClass); + (*env)->DeleteLocalRef(env, jLabel); + (*env)->DeleteLocalRef(env, jVendor); + (*env)->DeleteLocalRef(env, jModel); + (*env)->DeleteLocalRef(env, jSerialNo); + (*env)->DeleteLocalRef(env, jHardwareVer); + (*env)->DeleteLocalRef(env, jFirmwareVer); + + return jTokenInfoObject ; +} +#endif + +#ifdef P11_ENABLE_C_WAITFORSLOTEVENT +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_WaitForSlotEvent + * Signature: (JLjava/lang/Object;)J + * Parametermapping: *PKCS11* + * @param jlong jFlags CK_FLAGS flags + * @param jobject jReserved CK_VOID_PTR pReserved + * @return jlong jSlotID CK_SLOT_ID_PTR pSlot + */ +JNIEXPORT jlong JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1WaitForSlotEvent +(JNIEnv *env, jobject obj, jlong jFlags, jobject jReserved) +{ + CK_FLAGS ckFlags; + CK_SLOT_ID ckSlotID; + jlong jSlotID = 0L; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return 0L; } + + ckFlags = jLongToCKULong(jFlags); + + rv = (*ckpFunctions->C_WaitForSlotEvent)(ckFlags, &ckSlotID, NULL_PTR); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jSlotID = ckULongToJLong(ckSlotID); + } + + return jSlotID ; +} +#endif + +#ifdef P11_ENABLE_C_GETMECHANISMLIST +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_GetMechanismList + * Signature: (J)[J + * Parametermapping: *PKCS11* + * @param jlong jSlotID CK_SLOT_ID slotID + * @return jlongArray jMechanismList CK_MECHANISM_TYPE_PTR pMechanismList + * CK_ULONG_PTR pulCount + */ +JNIEXPORT jlongArray JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismList +(JNIEnv *env, jobject obj, jlong jSlotID) +{ + CK_SLOT_ID ckSlotID; + CK_ULONG ckMechanismNumber; + CK_MECHANISM_TYPE_PTR ckpMechanismList; + jlongArray jMechanismList = NULL; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckSlotID = jLongToCKULong(jSlotID); + + rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, NULL_PTR, + &ckMechanismNumber); + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; } + + ckpMechanismList = (CK_MECHANISM_TYPE_PTR) + malloc(ckMechanismNumber * sizeof(CK_MECHANISM_TYPE)); + if (ckpMechanismList == NULL) { + throwOutOfMemoryError(env, 0); + return NULL; + } + + rv = (*ckpFunctions->C_GetMechanismList)(ckSlotID, ckpMechanismList, + &ckMechanismNumber); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jMechanismList = ckULongArrayToJLongArray(env, ckpMechanismList, + ckMechanismNumber); + } + free(ckpMechanismList); + + return jMechanismList ; +} +#endif + +#ifdef P11_ENABLE_C_GETMECHANISMINFO +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_GetMechanismInfo + * Signature: (JJ)Lsun/security/pkcs11/wrapper/CK_MECHANISM_INFO; + * Parametermapping: *PKCS11* + * @param jlong jSlotID CK_SLOT_ID slotID + * @param jlong jType CK_MECHANISM_TYPE type + * @return jobject jMechanismInfo CK_MECHANISM_INFO_PTR pInfo + */ +JNIEXPORT jobject JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetMechanismInfo +(JNIEnv *env, jobject obj, jlong jSlotID, jlong jType) +{ + CK_SLOT_ID ckSlotID; + CK_MECHANISM_TYPE ckMechanismType; + CK_MECHANISM_INFO ckMechanismInfo; + jobject jMechanismInfo = NULL; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return NULL; } + + ckSlotID = jLongToCKULong(jSlotID); + ckMechanismType = jLongToCKULong(jType); + + rv = (*ckpFunctions->C_GetMechanismInfo)(ckSlotID, ckMechanismType, + &ckMechanismInfo); + if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { + jMechanismInfo = ckMechanismInfoPtrToJMechanismInfo(env, &ckMechanismInfo); + } + return jMechanismInfo ; +} + +/* + * converts a pointer to a CK_MECHANISM_INFO structure into a Java + * CK_MECHANISM_INFO Object. + * + * @param env - used to call JNI funktions to create the new Java object + * @param ckpMechanismInfo - the pointer to the CK_MECHANISM_INFO structure + * @return - the new Java CK_MECHANISM_INFO object + */ +jobject +ckMechanismInfoPtrToJMechanismInfo +(JNIEnv *env, const CK_MECHANISM_INFO_PTR ckpMechanismInfo) +{ + + jclass jMechanismInfoClass; + jmethodID jCtrId; + jobject jMechanismInfoObject; + jlong jMinKeySize; + jlong jMaxKeySize; + jlong jFlags; + + /* load CK_MECHANISM_INFO class */ + jMechanismInfoClass = (*env)->FindClass(env, CLASS_MECHANISM_INFO); + if (jMechanismInfoClass == NULL) { return NULL; }; + + /* load CK_MECHANISM_INFO constructor */ + jCtrId = (*env)->GetMethodID(env, jMechanismInfoClass, "", "(JJJ)V"); + if (jCtrId == NULL) { return NULL; }; + + /* prep all fields */ + jMinKeySize = ckULongToJLong(ckpMechanismInfo->ulMinKeySize); + jMaxKeySize = ckULongToJLong(ckpMechanismInfo->ulMaxKeySize); + jFlags = ckULongToJLong(ckpMechanismInfo->flags); + + /* create new CK_MECHANISM_INFO object */ + jMechanismInfoObject = (*env)->NewObject(env, jMechanismInfoClass, jCtrId, + jMinKeySize, jMaxKeySize, jFlags); + if (jMechanismInfoObject == NULL) { return NULL; }; + + /* free local references */ + (*env)->DeleteLocalRef(env, jMechanismInfoClass); + + return jMechanismInfoObject ; +} +#endif + +#ifdef P11_ENABLE_C_INITTOKEN +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_InitToken + * Signature: (J[C[C)V + * Parametermapping: *PKCS11* + * @param jlong jSlotID CK_SLOT_ID slotID + * @param jcharArray jPin CK_CHAR_PTR pPin + * CK_ULONG ulPinLen + * @param jcharArray jLabel CK_UTF8CHAR_PTR pLabel + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitToken +(JNIEnv *env, jobject obj, jlong jSlotID, jcharArray jPin, jcharArray jLabel) +{ + CK_SLOT_ID ckSlotID; + CK_CHAR_PTR ckpPin = NULL_PTR; + CK_UTF8CHAR_PTR ckpLabel = NULL_PTR; + CK_ULONG ckPinLength; + CK_ULONG ckLabelLength; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSlotID = jLongToCKULong(jSlotID); + jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength); + if ((*env)->ExceptionCheck(env)) { return; } + /* ckLabelLength <= 32 !!! */ + jCharArrayToCKUTF8CharArray(env, jLabel, &ckpLabel, &ckLabelLength); + if ((*env)->ExceptionCheck(env)) { + free(ckpPin); + return; + } + + rv = (*ckpFunctions->C_InitToken)(ckSlotID, ckpPin, ckPinLength, ckpLabel); + TRACE1("InitToken return code: %d", rv); + + free(ckpPin); + free(ckpLabel); + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_INITPIN +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_InitPIN + * Signature: (J[C)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE + * @param jcharArray jPin CK_CHAR_PTR pPin + * CK_ULONG ulPinLen + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1InitPIN +(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jPin) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_CHAR_PTR ckpPin = NULL_PTR; + CK_ULONG ckPinLength; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jCharArrayToCKCharArray(env, jPin, &ckpPin, &ckPinLength); + if ((*env)->ExceptionCheck(env)) { return; } + + rv = (*ckpFunctions->C_InitPIN)(ckSessionHandle, ckpPin, ckPinLength); + + free(ckpPin); + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif + +#ifdef P11_ENABLE_C_SETPIN +/* + * Class: sun_security_pkcs11_wrapper_PKCS11 + * Method: C_SetPIN + * Signature: (J[C[C)V + * Parametermapping: *PKCS11* + * @param jlong jSessionHandle CK_SESSION_HANDLE hSession + * @param jcharArray jOldPin CK_CHAR_PTR pOldPin + * CK_ULONG ulOldLen + * @param jcharArray jNewPin CK_CHAR_PTR pNewPin + * CK_ULONG ulNewLen + */ +JNIEXPORT void JNICALL +Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetPIN +(JNIEnv *env, jobject obj, jlong jSessionHandle, jcharArray jOldPin, +jcharArray jNewPin) +{ + CK_SESSION_HANDLE ckSessionHandle; + CK_CHAR_PTR ckpOldPin = NULL_PTR; + CK_CHAR_PTR ckpNewPin = NULL_PTR; + CK_ULONG ckOldPinLength; + CK_ULONG ckNewPinLength; + CK_RV rv; + + CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); + if (ckpFunctions == NULL) { return; } + + ckSessionHandle = jLongToCKULong(jSessionHandle); + jCharArrayToCKCharArray(env, jOldPin, &ckpOldPin, &ckOldPinLength); + if ((*env)->ExceptionCheck(env)) { return; } + jCharArrayToCKCharArray(env, jNewPin, &ckpNewPin, &ckNewPinLength); + if ((*env)->ExceptionCheck(env)) { + free(ckpOldPin); + return; + } + + rv = (*ckpFunctions->C_SetPIN)(ckSessionHandle, ckpOldPin, ckOldPinLength, + ckpNewPin, ckNewPinLength); + + free(ckpOldPin); + free(ckpNewPin); + + if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } +} +#endif