/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_VerifyRecover * Signature: (J[BII[BII)I * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jSignature CK_BYTE_PTR pSignature * CK_ULONG ulSignatureLen * @return jbyteArray jData CK_BYTE_PTR pData * CK_ULONG_PTR pulDataLen */ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyRecover (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen) { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; CK_BYTE INBUF[MAX_STACK_BUFFER_LEN]; CK_BYTE OUTBUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP = OUTBUF; CK_ULONG ckDataLength = MAX_STACK_BUFFER_LEN; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0; } ckSessionHandle = jLongToCKULong(jSessionHandle); if (jInLen <= MAX_STACK_BUFFER_LEN) { inBufP = INBUF; } else { inBufP = (CK_BYTE_PTR) malloc((size_t)jInLen); if (inBufP == NULL) { JNU_ThrowOutOfMemoryError(env, 0); return 0; } } (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); if ((*env)->ExceptionCheck(env)) { if (inBufP != INBUF) { free(inBufP); } return 0; } rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength); /* re-alloc larger buffer if it fits into our Java buffer */ if ((rv == CKR_BUFFER_TOO_SMALL) && (ckDataLength <= jIntToCKULong(jOutLen))) { outBufP = (CK_BYTE_PTR) malloc(ckDataLength); if (outBufP == NULL) { if (inBufP != INBUF) { free(inBufP); } JNU_ThrowOutOfMemoryError(env, 0); return 0; } rv = (*ckpFunctions->C_VerifyRecover)(ckSessionHandle, inBufP, jInLen, outBufP, &ckDataLength); } if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckDataLength, (jbyte *)outBufP); } if (inBufP != INBUF) { free(inBufP); } if (outBufP != OUTBUF) { free(outBufP); } return ckDataLength; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_Decrypt * Signature: (J[BII[BII)I * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jEncryptedData CK_BYTE_PTR pEncryptedData * CK_ULONG ulEncryptedDataLen * @return jbyteArray jData CK_BYTE_PTR pData * CK_ULONG_PTR pulDataLen */ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Decrypt (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jOut, jint jOutOfs, jint jOutLen) { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; CK_BYTE IBUF[MAX_STACK_BUFFER_LEN]; CK_BYTE OBUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR inBufP; CK_BYTE_PTR outBufP; CK_ULONG ckPartLen; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0; } ckSessionHandle = jLongToCKULong(jSessionHandle); if (jInLen > MAX_STACK_BUFFER_LEN) { inBufP = (CK_BYTE_PTR)malloc((size_t)jInLen); } else { inBufP = IBUF; } (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)inBufP); ckPartLen = jOutLen; if (jOutLen > MAX_STACK_BUFFER_LEN) { outBufP = (CK_BYTE_PTR)malloc((size_t)jOutLen); } else { outBufP = OBUF; } rv = (*ckpFunctions->C_Decrypt)(ckSessionHandle, inBufP, jInLen, outBufP, &ckPartLen); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { if (ckPartLen > 0) { (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckPartLen, (jbyte *)outBufP); } } if (inBufP != IBUF) { free(inBufP); } if (outBufP != OBUF) { free(outBufP); } return ckPartLen; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_Digest * Signature: (J[BII[BII)I * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jData CK_BYTE_PTR pData * CK_ULONG ulDataLen * @return jbyteArray jDigest CK_BYTE_PTR pDigest * CK_ULONG_PTR pulDigestLen */ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestSingle (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jbyteArray jIn, jint jInOfs, jint jInLen, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen) { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; CK_BYTE_PTR bufP; CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE DIGESTBUF[MAX_DIGEST_LEN]; CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen); CK_MECHANISM ckMechanism; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0; } ckSessionHandle = jLongToCKULong(jSessionHandle); jMechanismToCKMechanism(env, jMechanism, &ckMechanism); if ((*env)->ExceptionCheck(env)) { return 0; } rv = (*ckpFunctions->C_DigestInit)(ckSessionHandle, &ckMechanism); if (ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0; } if (jInLen <= MAX_STACK_BUFFER_LEN) { bufP = BUF; } else { /* always use single part op, even for large data */ bufP = (CK_BYTE_PTR) malloc((size_t)jInLen); if (bufP == NULL) { JNU_ThrowOutOfMemoryError(env, 0); return 0; } } (*env)->GetByteArrayRegion(env, jIn, jInOfs, jInLen, (jbyte *)bufP); if ((*env)->ExceptionCheck(env)) { if (bufP != BUF) { free(bufP); } return 0; } rv = (*ckpFunctions->C_Digest)(ckSessionHandle, bufP, jInLen, DIGESTBUF, &ckDigestLength); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)DIGESTBUF); } if (bufP != BUF) { free(bufP); } return ckDigestLength; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_SignUpdate * Signature: (J[BII)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jPart CK_BYTE_PTR pPart * CK_ULONG ulPartLen */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignUpdate (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directIn, jbyteArray jIn, jint jInOfs, jint jInLen) { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; CK_BYTE_PTR bufP; CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; jsize bufLen; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); if (directIn != 0) { rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, (CK_BYTE_PTR) jlong_to_ptr(directIn), jInLen); ckAssertReturnValueOK(env, rv); return; } if (jInLen <= MAX_STACK_BUFFER_LEN) { bufLen = MAX_STACK_BUFFER_LEN; bufP = BUF; } else { bufLen = min(MAX_HEAP_BUFFER_LEN, jInLen); bufP = (CK_BYTE_PTR) malloc((size_t)bufLen); if (bufP == NULL) { throwOutOfMemoryError(env, 0); return; } } while (jInLen > 0) { jsize chunkLen = min(bufLen, jInLen); (*env)->GetByteArrayRegion(env, jIn, jInOfs, chunkLen, (jbyte *)bufP); if ((*env)->ExceptionCheck(env)) { if (bufP != BUF) { free(bufP); } return; } rv = (*ckpFunctions->C_SignUpdate)(ckSessionHandle, bufP, chunkLen); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { if (bufP != BUF) { free(bufP); } return; } jInOfs += chunkLen; jInLen -= chunkLen; } if (bufP != BUF) { free(bufP); } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_GetObjectSize * Signature: (JJ)J * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject * @return jlong jObjectSize CK_ULONG_PTR pulSize */ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetObjectSize (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle) { CK_SESSION_HANDLE ckSessionHandle; CK_OBJECT_HANDLE ckObjectHandle; CK_ULONG ckObjectSize; jlong jObjectSize = 0L; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0L; } ckSessionHandle = jLongToCKULong(jSessionHandle); ckObjectHandle = jLongToCKULong(jObjectHandle); rv = (*ckpFunctions->C_GetObjectSize)(ckSessionHandle, ckObjectHandle, &ckObjectSize); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; } jObjectSize = ckULongToJLong(ckObjectSize); return jObjectSize ; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_FindObjectsFinal * Signature: (J)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1FindObjectsFinal (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_FindObjectsFinal)(ckSessionHandle); if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_Sign * Signature: (J[B)[B * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jData CK_BYTE_PTR pData * CK_ULONG ulDataLen * @return jbyteArray jSignature CK_BYTE_PTR pSignature * CK_ULONG_PTR pulSignatureLen */ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Sign (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData) { CK_SESSION_HANDLE ckSessionHandle; CK_BYTE_PTR ckpData = NULL_PTR; CK_BYTE_PTR ckpSignature; CK_ULONG ckDataLength; CK_ULONG ckSignatureLength = 0; jbyteArray jSignature; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return NULL; } ckSessionHandle = jLongToCKULong(jSessionHandle); jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength); /* START standard code */ /* first determine the length of the signature */ rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, NULL_PTR, &ckSignatureLength); if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; } ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE)); /* now get the signature */ rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength); /* END standard code */ /* START workaround code for operation abort bug in pkcs#11 of Datakey and iButton */ /* ckpSignature = (CK_BYTE_PTR) malloc(256 * sizeof(CK_BYTE)); rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength); if (rv == CKR_BUFFER_TOO_SMALL) { free(ckpSignature); ckpSignature = (CK_BYTE_PTR) malloc(ckSignatureLength * sizeof(CK_BYTE)); rv = (*ckpFunctions->C_Sign)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, &ckSignatureLength); } */ /* END workaround code */ jSignature = ckByteArrayToJByteArray(env, ckpSignature, ckSignatureLength); free(ckpData); free(ckpSignature); if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return NULL ; } return jSignature ; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_SignInit * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jobject jMechanism CK_MECHANISM_PTR pMechanism * @return jlong jKeyHandle CK_OBJECT_HANDLE hKey */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignInit (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jKeyHandle) { CK_SESSION_HANDLE ckSessionHandle; CK_MECHANISM ckMechanism; CK_OBJECT_HANDLE ckKeyHandle; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); jMechanismToCKMechanism(env, jMechanism, &ckMechanism); ckKeyHandle = jLongToCKULong(jKeyHandle); rv = (*ckpFunctions->C_SignInit)(ckSessionHandle, &ckMechanism, ckKeyHandle); if(ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_SetAttributeValue * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate * CK_ULONG ulCount */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetAttributeValue (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate) { CK_SESSION_HANDLE ckSessionHandle; CK_OBJECT_HANDLE ckObjectHandle; CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; CK_ULONG ckAttributesLength; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); ckObjectHandle = jLongToCKULong(jObjectHandle); jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); if ((*env)->ExceptionCheck(env)) { return; } rv = (*ckpFunctions->C_SetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength); freeCKAttributeArray(ckpAttributes, ckAttributesLength); if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * 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; } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_CancelFunction * Signature: (J)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1CancelFunction (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); /* C_GetFunctionStatus should always return CKR_FUNCTION_NOT_PARALLEL */ rv = (*ckpFunctions->C_CancelFunction)(ckSessionHandle); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_EncryptFinal * Signature: (J[BII)I * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @return jbyteArray jLastEncryptedPart CK_BYTE_PTR pLastEncryptedDataPart * CK_ULONG_PTR pulLastEncryptedDataPartLen */ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1EncryptFinal (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong directOut, jbyteArray jOut, jint jOutOfs, jint jOutLen) { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR outBufP; CK_ULONG ckLastEncryptedPartLen; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0; } ckSessionHandle = jLongToCKULong(jSessionHandle); ckLastEncryptedPartLen = jOutLen; if (directOut != 0) { outBufP = (CK_BYTE_PTR)(directOut + jOutOfs); } else { // output length should always be less than MAX_STACK_BUFFER_LEN outBufP = BUF; } //printf("EF: outBufP=%i\n", outBufP); rv = (*ckpFunctions->C_EncryptFinal)(ckSessionHandle, outBufP, &ckLastEncryptedPartLen); //printf("EF: ckLastEncryptedPartLen=%i", ckLastEncryptedPartLen); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { if (directOut == 0 && ckLastEncryptedPartLen > 0) { (*env)->SetByteArrayRegion(env, jOut, jOutOfs, ckLastEncryptedPartLen, (jbyte *)outBufP); } } if (directOut == 0 && outBufP != BUF) { free(outBufP); } return ckLastEncryptedPartLen; }
/* * 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 ; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_DigestFinal * Signature: (J[BII)I * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @return jbyteArray jDigest CK_BYTE_PTR pDigest * CK_ULONG_PTR pulDigestLen */ JNIEXPORT jint JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestFinal (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jDigest, jint jDigestOfs, jint jDigestLen) { CK_SESSION_HANDLE ckSessionHandle; CK_RV rv; CK_BYTE BUF[MAX_DIGEST_LEN]; CK_ULONG ckDigestLength = min(MAX_DIGEST_LEN, jDigestLen); CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0; } ckSessionHandle = jLongToCKULong(jSessionHandle); rv = (*ckpFunctions->C_DigestFinal)(ckSessionHandle, BUF, &ckDigestLength); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { (*env)->SetByteArrayRegion(env, jDigest, jDigestOfs, ckDigestLength, (jbyte *)BUF); } return ckDigestLength; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_SeedRandom * Signature: (J[B)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jSeed CK_BYTE_PTR pSeed * CK_ULONG ulSeedLen */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SeedRandom (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSeed) { CK_SESSION_HANDLE ckSessionHandle; CK_BYTE_PTR ckpSeed = NULL_PTR; CK_ULONG ckSeedLength; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); jByteArrayToCKByteArray(env, jSeed, &ckpSeed, &ckSeedLength); rv = (*ckpFunctions->C_SeedRandom)(ckSessionHandle, ckpSeed, ckSeedLength); free(ckpSeed); if(ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * converts a Java long object into a pointer to a CK_ULONG value. The memory has to be * freed after use! * * @param env - used to call JNI funktions to get the value out of the Java object * @param jObject - the "java/lang/Long" object to convert * @return - the pointer to the new CK_ULONG value */ CK_ULONG* jLongObjectToCKULongPtr(JNIEnv *env, jobject jObject) { jclass jObjectClass; jmethodID jValueMethod; jlong jValue; CK_ULONG *ckpValue; jObjectClass = (*env)->FindClass(env, "java/lang/Long"); if (jObjectClass == NULL) { return NULL; } jValueMethod = (*env)->GetMethodID(env, jObjectClass, "longValue", "()J"); if (jValueMethod == NULL) { return NULL; } jValue = (*env)->CallLongMethod(env, jObject, jValueMethod); ckpValue = (CK_ULONG *) malloc(sizeof(CK_ULONG)); if (ckpValue == NULL) { throwOutOfMemoryError(env, 0); return NULL; } *ckpValue = jLongToCKULong(jValue); return ckpValue ; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_VerifyFinal * Signature: (J[B)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jSignature CK_BYTE_PTR pSignature * CK_ULONG ulSignatureLen */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1VerifyFinal (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jSignature) { CK_SESSION_HANDLE ckSessionHandle; CK_BYTE_PTR ckpSignature = NULL_PTR; CK_ULONG ckSignatureLength; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength); if ((*env)->ExceptionCheck(env)) { return; } /* verify the signature */ rv = (*ckpFunctions->C_VerifyFinal)(ckSessionHandle, ckpSignature, ckSignatureLength); free(ckpSignature); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_DigestEncryptUpdate * Signature: (J[B)[B * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jPart CK_BYTE_PTR pPart * CK_ULONG ulPartLen * @return jbyteArray jEncryptedPart CK_BYTE_PTR pEncryptedPart * CK_ULONG_PTR pulEncryptedPartLen */ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DigestEncryptUpdate (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jPart) { CK_SESSION_HANDLE ckSessionHandle; CK_BYTE_PTR ckpPart = NULL_PTR, ckpEncryptedPart; CK_ULONG ckPartLength, ckEncryptedPartLength = 0; jbyteArray jEncryptedPart = NULL; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return NULL; } ckSessionHandle = jLongToCKULong(jSessionHandle); jByteArrayToCKByteArray(env, jPart, &ckpPart, &ckPartLength); if ((*env)->ExceptionCheck(env)) { return NULL; } rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, NULL_PTR, &ckEncryptedPartLength); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { free(ckpPart); return NULL; } ckpEncryptedPart = (CK_BYTE_PTR) malloc(ckEncryptedPartLength * sizeof(CK_BYTE)); if (ckpEncryptedPart == NULL) { free(ckpPart); JNU_ThrowOutOfMemoryError(env, 0); return NULL; } rv = (*ckpFunctions->C_DigestEncryptUpdate)(ckSessionHandle, ckpPart, ckPartLength, ckpEncryptedPart, &ckEncryptedPartLength); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { jEncryptedPart = ckByteArrayToJByteArray(env, ckpEncryptedPart, ckEncryptedPartLength); } free(ckpPart); free(ckpEncryptedPart); return jEncryptedPart ; }
/* * converts a jobjectArray with Java Attributes to a CK_ATTRIBUTE array. The allocated memory * has to be freed after use! * * @param env - used to call JNI funktions to get the array informtaion * @param jArray - the Java Attribute array (template) to convert * @param ckpArray - the reference, where the pointer to the new CK_ATTRIBUTE array will be * stored * @param ckpLength - the reference, where the array length will be stored */ void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTRIBUTE_PTR *ckpArray, CK_ULONG_PTR ckpLength) { CK_ULONG i; jlong jLength; jobject jAttribute; TRACE0("\nDEBUG: jAttributeArrayToCKAttributeArray"); if (jArray == NULL) { *ckpArray = NULL_PTR; *ckpLength = 0L; return; } jLength = (*env)->GetArrayLength(env, jArray); *ckpLength = jLongToCKULong(jLength); *ckpArray = (CK_ATTRIBUTE_PTR) malloc(*ckpLength * sizeof(CK_ATTRIBUTE)); if (*ckpArray == NULL) { throwOutOfMemoryError(env, 0); return; } TRACE1(", converting %d attributes", jLength); for (i=0; i<(*ckpLength); i++) { TRACE1(", getting %d. attribute", i); jAttribute = (*env)->GetObjectArrayElement(env, jArray, i); if ((*env)->ExceptionCheck(env)) { freeCKAttributeArray(*ckpArray, i); return; } TRACE1(", jAttribute = %d", jAttribute); TRACE1(", converting %d. attribute", i); (*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute); if ((*env)->ExceptionCheck(env)) { freeCKAttributeArray(*ckpArray, i); return; } } TRACE0("FINISHED\n"); }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_SignFinal * Signature: (J)[B * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @return jbyteArray jSignature CK_BYTE_PTR pSignature * CK_ULONG_PTR pulSignatureLen */ JNIEXPORT jbyteArray JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SignFinal (JNIEnv *env, jobject obj, jlong jSessionHandle, jint jExpectedLength) { CK_SESSION_HANDLE ckSessionHandle; jbyteArray jSignature = NULL; CK_RV rv; CK_BYTE BUF[MAX_STACK_BUFFER_LEN]; CK_BYTE_PTR bufP = BUF; CK_ULONG ckSignatureLength = MAX_STACK_BUFFER_LEN; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return NULL; } ckSessionHandle = jLongToCKULong(jSessionHandle); if ((jExpectedLength > 0) && ((CK_ULONG)jExpectedLength < ckSignatureLength)) { ckSignatureLength = jExpectedLength; } rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength); if (rv == CKR_BUFFER_TOO_SMALL) { bufP = (CK_BYTE_PTR) malloc(ckSignatureLength); if (bufP == NULL) { throwOutOfMemoryError(env, 0); return NULL; } rv = (*ckpFunctions->C_SignFinal)(ckSessionHandle, bufP, &ckSignatureLength); } if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { jSignature = ckByteArrayToJByteArray(env, bufP, ckSignatureLength); } if (bufP != BUF) { free(bufP); } return jSignature; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_DeriveKey * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jobject jMechanism CK_MECHANISM_PTR pMechanism * @param jlong jBaseKeyHandle CK_OBJECT_HANDLE hBaseKey * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate * CK_ULONG ulCount * @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey */ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1DeriveKey (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jBaseKeyHandle, jobjectArray jTemplate) { CK_SESSION_HANDLE ckSessionHandle; CK_MECHANISM ckMechanism; CK_OBJECT_HANDLE ckBaseKeyHandle; CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; CK_ULONG ckAttributesLength; CK_OBJECT_HANDLE ckKeyHandle = 0; jlong jKeyHandle = 0L; CK_RV rv; CK_OBJECT_HANDLE_PTR phKey = &ckKeyHandle; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0L; } ckSessionHandle = jLongToCKULong(jSessionHandle); jMechanismToCKMechanism(env, jMechanism, &ckMechanism); if ((*env)->ExceptionCheck(env)) { return 0L; } ckBaseKeyHandle = jLongToCKULong(jBaseKeyHandle); jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); if ((*env)->ExceptionCheck(env)) { if (ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } return 0L; } switch (ckMechanism.mechanism) { case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_TLS_KEY_AND_MAC_DERIVE: case CKM_TLS_PRF: // these mechanism do not return a key handle via phKey // set to NULL in case pedantic implementations check for it phKey = NULL; break; default: // empty break; } rv = (*ckpFunctions->C_DeriveKey)(ckSessionHandle, &ckMechanism, ckBaseKeyHandle, ckpAttributes, ckAttributesLength, phKey); jKeyHandle = ckLongToJLong(ckKeyHandle); freeCKAttributeArray(ckpAttributes, ckAttributesLength); switch (ckMechanism.mechanism) { case CKM_SSL3_MASTER_KEY_DERIVE: case CKM_TLS_MASTER_KEY_DERIVE: /* we must copy back the client version */ copyBackClientVersion(env, &ckMechanism, jMechanism); freeMasterKeyDeriveParams(&ckMechanism); break; case CKM_SSL3_MASTER_KEY_DERIVE_DH: case CKM_TLS_MASTER_KEY_DERIVE_DH: freeMasterKeyDeriveParams(&ckMechanism); break; case CKM_SSL3_KEY_AND_MAC_DERIVE: case CKM_TLS_KEY_AND_MAC_DERIVE: /* we must copy back the unwrapped key info to the jMechanism object */ copyBackSSLKeyMatParams(env, &ckMechanism, jMechanism); break; case CKM_TLS_PRF: copyBackTLSPrfParams(env, &ckMechanism, jMechanism); break; case CKM_ECDH1_DERIVE: freeEcdh1DeriveParams(&ckMechanism); break; default: // empty break; } if (ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return 0L ; } return jKeyHandle ; }
/* * Copy back the derived keys and initialization vectors from the native * structure to the Java object. This is only used for the * CKM_SSL3_KEY_AND_MAC_DERIVE mechanism when used for deriving a key. * */ void copyBackSSLKeyMatParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) { jclass jMechanismClass, jSSL3KeyMatParamsClass, jSSL3KeyMatOutClass; CK_SSL3_KEY_MAT_PARAMS *ckSSL3KeyMatParam; CK_SSL3_KEY_MAT_OUT *ckSSL3KeyMatOut; jfieldID fieldID; CK_MECHANISM_TYPE ckMechanismType; jlong jMechanismType; CK_BYTE_PTR iv; jobject jSSL3KeyMatParam; jobject jSSL3KeyMatOut; jobject jIV; jint jLength; jbyte* jBytes; int i; /* get mechanism */ jMechanismClass= (*env)->FindClass(env, CLASS_MECHANISM); if (jMechanismClass == NULL) { return; } fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); if (fieldID == NULL) { return; } jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); ckMechanismType = jLongToCKULong(jMechanismType); if (ckMechanismType != ckMechanism->mechanism) { /* we do not have maching types, this should not occur */ return; } /* get the native CK_SSL3_KEY_MAT_PARAMS */ ckSSL3KeyMatParam = (CK_SSL3_KEY_MAT_PARAMS *) ckMechanism->pParameter; if (ckSSL3KeyMatParam != NULL_PTR) { // free malloc'd data if (ckSSL3KeyMatParam->RandomInfo.pClientRandom != NULL) { free(ckSSL3KeyMatParam->RandomInfo.pClientRandom); } if (ckSSL3KeyMatParam->RandomInfo.pServerRandom != NULL) { free(ckSSL3KeyMatParam->RandomInfo.pServerRandom); } /* get the native CK_SSL3_KEY_MAT_OUT */ ckSSL3KeyMatOut = ckSSL3KeyMatParam->pReturnedKeyMaterial; if (ckSSL3KeyMatOut != NULL_PTR) { /* get the Java CK_SSL3_KEY_MAT_PARAMS (pParameter) */ fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); if (fieldID == NULL) { return; } jSSL3KeyMatParam = (*env)->GetObjectField(env, jMechanism, fieldID); /* get the Java CK_SSL3_KEY_MAT_OUT */ jSSL3KeyMatParamsClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_PARAMS); if (jSSL3KeyMatParamsClass == NULL) { return; } fieldID = (*env)->GetFieldID(env, jSSL3KeyMatParamsClass, "pReturnedKeyMaterial", "L"CLASS_SSL3_KEY_MAT_OUT";"); if (fieldID == NULL) { return; } jSSL3KeyMatOut = (*env)->GetObjectField(env, jSSL3KeyMatParam, fieldID); /* now copy back all the key handles and the initialization vectors */ /* copy back client MAC secret handle */ jSSL3KeyMatOutClass = (*env)->FindClass(env, CLASS_SSL3_KEY_MAT_OUT); if (jSSL3KeyMatOutClass == NULL) { return; } fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientMacSecret", "J"); if (fieldID == NULL) { return; } (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientMacSecret)); /* copy back server MAC secret handle */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerMacSecret", "J"); if (fieldID == NULL) { return; } (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerMacSecret)); /* copy back client secret key handle */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hClientKey", "J"); if (fieldID == NULL) { return; } (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hClientKey)); /* copy back server secret key handle */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "hServerKey", "J"); if (fieldID == NULL) { return; } (*env)->SetLongField(env, jSSL3KeyMatOut, fieldID, ckULongToJLong(ckSSL3KeyMatOut->hServerKey)); /* copy back the client IV */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVClient", "[B"); if (fieldID == NULL) { return; } jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID); iv = ckSSL3KeyMatOut->pIVClient; if (jIV != NULL) { jLength = (*env)->GetArrayLength(env, jIV); jBytes = (*env)->GetByteArrayElements(env, jIV, NULL); if (jBytes == NULL) { return; } /* copy the bytes to the Java buffer */ for (i=0; i < jLength; i++) { jBytes[i] = ckByteToJByte(iv[i]); } /* copy back the Java buffer to the object */ (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0); } // free malloc'd data free(ckSSL3KeyMatOut->pIVClient); /* copy back the server IV */ fieldID = (*env)->GetFieldID(env, jSSL3KeyMatOutClass, "pIVServer", "[B"); if (fieldID == NULL) { return; } jIV = (*env)->GetObjectField(env, jSSL3KeyMatOut, fieldID); iv = ckSSL3KeyMatOut->pIVServer; if (jIV != NULL) { jLength = (*env)->GetArrayLength(env, jIV); jBytes = (*env)->GetByteArrayElements(env, jIV, NULL); if (jBytes == NULL) { return; } /* copy the bytes to the Java buffer */ for (i=0; i < jLength; i++) { jBytes[i] = ckByteToJByte(iv[i]); } /* copy back the Java buffer to the object */ (*env)->ReleaseByteArrayElements(env, jIV, jBytes, 0); } // free malloc'd data free(ckSSL3KeyMatOut->pIVServer); free(ckSSL3KeyMatOut); } } }
/* * The function handling notify callbacks. It casts the pApplication paramter * 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; JavaVM *jvm; JNIEnv *env; jsize actualNumberVMs; 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 */ 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; } 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 ; }
/* * 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) { JNU_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 ; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_GetAttributeValue * Signature: (JJ[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE; * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jlong jObjectHandle CK_OBJECT_HANDLE hObject * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate * CK_ULONG ulCount */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1GetAttributeValue (JNIEnv *env, jobject obj, jlong jSessionHandle, jlong jObjectHandle, jobjectArray jTemplate) { CK_SESSION_HANDLE ckSessionHandle; CK_OBJECT_HANDLE ckObjectHandle; CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; CK_ULONG ckAttributesLength; CK_ULONG ckBufferLength; CK_ULONG i; jobject jAttribute; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } TRACE0("DEBUG: C_GetAttributeValue"); TRACE1(", hSession=%u", jSessionHandle); TRACE1(", hObject=%u", jObjectHandle); TRACE1(", pTemplate=%p", jTemplate); TRACE0(" ... "); ckSessionHandle = jLongToCKULong(jSessionHandle); ckObjectHandle = jLongToCKULong(jObjectHandle); TRACE1("jAttributeArrayToCKAttributeArray now with jTemplate = %d", jTemplate); jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); if ((*env)->ExceptionCheck(env)) { return; } TRACE2("DEBUG: jAttributeArrayToCKAttributeArray finished with ckpAttribute = %d, Length = %d\n", ckpAttributes, ckAttributesLength); /* first set all pValue to NULL, to get the needed buffer length */ for(i = 0; i < ckAttributesLength; i++) { if (ckpAttributes[i].pValue != NULL_PTR) { free(ckpAttributes[i].pValue); ckpAttributes[i].pValue = NULL_PTR; } } rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { free(ckpAttributes); return ; } /* now, the ulValueLength field of each attribute should hold the exact buffer length needed * allocate the needed buffers accordingly */ for (i = 0; i < ckAttributesLength; i++) { ckBufferLength = sizeof(CK_BYTE) * ckpAttributes[i].ulValueLen; ckpAttributes[i].pValue = (void *) malloc(ckBufferLength); if (ckpAttributes[i].pValue == NULL) { freeCKAttributeArray(ckpAttributes, i); throwOutOfMemoryError(env, 0); return; } ckpAttributes[i].ulValueLen = ckBufferLength; } /* now get the attributes with all values */ rv = (*ckpFunctions->C_GetAttributeValue)(ckSessionHandle, ckObjectHandle, ckpAttributes, ckAttributesLength); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { /* copy back the values to the Java attributes */ for (i = 0; i < ckAttributesLength; i++) { jAttribute = ckAttributePtrToJAttribute(env, &(ckpAttributes[i])); if (jAttribute == NULL) { freeCKAttributeArray(ckpAttributes, ckAttributesLength); return; } (*env)->SetObjectArrayElement(env, jTemplate, i, jAttribute); if ((*env)->ExceptionCheck(env)) { freeCKAttributeArray(ckpAttributes, ckAttributesLength); return; } } } freeCKAttributeArray(ckpAttributes, ckAttributesLength); TRACE0("FINISHED\n"); }
/* * 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 = (*env)->FindClass(env, CLASS_C_INITIALIZE_ARGS); 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)); /* Set the mutex functions that will call the Java mutex functions, but * only set it, if the field is not 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;"); assert(fieldID != 0); 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;"); assert(fieldID != 0); 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;"); assert(fieldID != 0); 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;"); assert(fieldID != 0); 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)); memcpy(ckpGlobalInitArgs, ckpInitArgs, sizeof(CK_C_INITIALIZE_ARGS)); } #endif /* NO_CALLBACKS */ /* convert and set the flags field */ fieldID = (*env)->GetFieldID(env, jInitArgsClass, "flags", "J"); assert(fieldID != 0); 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;"); assert(fieldID != 0); jReserved = (*env)->GetObjectField(env, jInitArgs, fieldID); /* we try to convert the reserved parameter also */ jObjectToPrimitiveCKObjectPtrPtr(env, jReserved, &(ckpInitArgs->pReserved), &ckReservedLength); return ckpInitArgs ; }
/* * 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 ; }
/* * Copy back the PRF output to Java. */ void copyBackTLSPrfParams(JNIEnv *env, CK_MECHANISM *ckMechanism, jobject jMechanism) { jclass jMechanismClass, jTLSPrfParamsClass; CK_TLS_PRF_PARAMS *ckTLSPrfParams; jobject jTLSPrfParams; jfieldID fieldID; CK_MECHANISM_TYPE ckMechanismType; jlong jMechanismType; CK_BYTE_PTR output; jobject jOutput; jint jLength; jbyte* jBytes; int i; /* get mechanism */ jMechanismClass = (*env)->FindClass(env, CLASS_MECHANISM); if (jMechanismClass == NULL) { return; } fieldID = (*env)->GetFieldID(env, jMechanismClass, "mechanism", "J"); if (fieldID == NULL) { return; } jMechanismType = (*env)->GetLongField(env, jMechanism, fieldID); ckMechanismType = jLongToCKULong(jMechanismType); if (ckMechanismType != ckMechanism->mechanism) { /* we do not have maching types, this should not occur */ return; } /* get the native CK_TLS_PRF_PARAMS */ ckTLSPrfParams = (CK_TLS_PRF_PARAMS *) ckMechanism->pParameter; if (ckTLSPrfParams != NULL_PTR) { /* get the Java CK_TLS_PRF_PARAMS object (pParameter) */ fieldID = (*env)->GetFieldID(env, jMechanismClass, "pParameter", "Ljava/lang/Object;"); if (fieldID == NULL) { return; } jTLSPrfParams = (*env)->GetObjectField(env, jMechanism, fieldID); /* copy back the client IV */ jTLSPrfParamsClass = (*env)->FindClass(env, CLASS_TLS_PRF_PARAMS); if (jTLSPrfParamsClass == NULL) { return; } fieldID = (*env)->GetFieldID(env, jTLSPrfParamsClass, "pOutput", "[B"); if (fieldID == NULL) { return; } jOutput = (*env)->GetObjectField(env, jTLSPrfParams, fieldID); output = ckTLSPrfParams->pOutput; // Note: we assume that the token returned exactly as many bytes as we // requested. Anything else would not make sense. if (jOutput != NULL) { jLength = (*env)->GetArrayLength(env, jOutput); jBytes = (*env)->GetByteArrayElements(env, jOutput, NULL); if (jBytes == NULL) { return; } /* copy the bytes to the Java buffer */ for (i=0; i < jLength; i++) { jBytes[i] = ckByteToJByte(output[i]); } /* copy back the Java buffer to the object */ (*env)->ReleaseByteArrayElements(env, jOutput, jBytes, 0); } // free malloc'd data free(ckTLSPrfParams->pSeed); free(ckTLSPrfParams->pLabel); free(ckTLSPrfParams->pulOutputLen); free(ckTLSPrfParams->pOutput); } }
/* * 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 ; }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_UnwrapKey * Signature: (JLsun/security/pkcs11/wrapper/CK_MECHANISM;J[B[Lsun/security/pkcs11/wrapper/CK_ATTRIBUTE;)J * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jobject jMechanism CK_MECHANISM_PTR pMechanism * @param jlong jUnwrappingKeyHandle CK_OBJECT_HANDLE hUnwrappingKey * @param jbyteArray jWrappedKey CK_BYTE_PTR pWrappedKey * CK_ULONG_PTR pulWrappedKeyLen * @param jobjectArray jTemplate CK_ATTRIBUTE_PTR pTemplate * CK_ULONG ulCount * @return jlong jKeyHandle CK_OBJECT_HANDLE_PTR phKey */ JNIEXPORT jlong JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1UnwrapKey (JNIEnv *env, jobject obj, jlong jSessionHandle, jobject jMechanism, jlong jUnwrappingKeyHandle, jbyteArray jWrappedKey, jobjectArray jTemplate) { CK_SESSION_HANDLE ckSessionHandle; CK_MECHANISM ckMechanism; CK_OBJECT_HANDLE ckUnwrappingKeyHandle; CK_BYTE_PTR ckpWrappedKey = NULL_PTR; CK_ULONG ckWrappedKeyLength; CK_ATTRIBUTE_PTR ckpAttributes = NULL_PTR; CK_ULONG ckAttributesLength; CK_OBJECT_HANDLE ckKeyHandle = 0; jlong jKeyHandle = 0L; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return 0L; } ckSessionHandle = jLongToCKULong(jSessionHandle); jMechanismToCKMechanism(env, jMechanism, &ckMechanism); if ((*env)->ExceptionCheck(env)) { return 0L; } ckUnwrappingKeyHandle = jLongToCKULong(jUnwrappingKeyHandle); jByteArrayToCKByteArray(env, jWrappedKey, &ckpWrappedKey, &ckWrappedKeyLength); if ((*env)->ExceptionCheck(env)) { if (ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } return 0L; } jAttributeArrayToCKAttributeArray(env, jTemplate, &ckpAttributes, &ckAttributesLength); if ((*env)->ExceptionCheck(env)) { if (ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } free(ckpWrappedKey); return 0L; } rv = (*ckpFunctions->C_UnwrapKey)(ckSessionHandle, &ckMechanism, ckUnwrappingKeyHandle, ckpWrappedKey, ckWrappedKeyLength, ckpAttributes, ckAttributesLength, &ckKeyHandle); if (ckAssertReturnValueOK(env, rv) == CK_ASSERT_OK) { jKeyHandle = ckLongToJLong(ckKeyHandle); #if 0 /* cheack, if we must give a initialization vector back to Java */ if (ckMechanism.mechanism == CKM_KEY_WRAP_SET_OAEP) { /* we must copy back the unwrapped key info to the jMechanism object */ copyBackSetUnwrappedKey(env, &ckMechanism, jMechanism); } #endif } if (ckMechanism.pParameter != NULL_PTR) { free(ckMechanism.pParameter); } freeCKAttributeArray(ckpAttributes, ckAttributesLength); free(ckpWrappedKey); return jKeyHandle ; }