/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_Verify * Signature: (J[B[B)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jData CK_BYTE_PTR pData * CK_ULONG ulDataLen * @param jbyteArray jSignature CK_BYTE_PTR pSignature * CK_ULONG_PTR pulSignatureLen */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1Verify (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jData, jbyteArray jSignature) { CK_SESSION_HANDLE ckSessionHandle; CK_BYTE_PTR ckpData = NULL_PTR; CK_BYTE_PTR ckpSignature = NULL_PTR; CK_ULONG ckDataLength; CK_ULONG ckSignatureLength; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); jByteArrayToCKByteArray(env, jData, &ckpData, &ckDataLength); if ((*env)->ExceptionCheck(env)) { return; } jByteArrayToCKByteArray(env, jSignature, &ckpSignature, &ckSignatureLength); if ((*env)->ExceptionCheck(env)) { free(ckpData); return; } /* verify the signature */ rv = (*ckpFunctions->C_Verify)(ckSessionHandle, ckpData, ckDataLength, ckpSignature, ckSignatureLength); free(ckpData); free(ckpSignature); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * Class: sun_security_pkcs11_wrapper_PKCS11 * Method: C_SetOperationState * Signature: (J[BJJ)V * Parametermapping: *PKCS11* * @param jlong jSessionHandle CK_SESSION_HANDLE hSession * @param jbyteArray jOperationState CK_BYTE_PTR pOperationState * CK_ULONG ulOperationStateLen * @param jlong jEncryptionKeyHandle CK_OBJECT_HANDLE hEncryptionKey * @param jlong jAuthenticationKeyHandle CK_OBJECT_HANDLE hAuthenticationKey */ JNIEXPORT void JNICALL Java_sun_security_pkcs11_wrapper_PKCS11_C_1SetOperationState (JNIEnv *env, jobject obj, jlong jSessionHandle, jbyteArray jOperationState, jlong jEncryptionKeyHandle, jlong jAuthenticationKeyHandle) { CK_SESSION_HANDLE ckSessionHandle; CK_BYTE_PTR ckpState = NULL_PTR; CK_ULONG ckStateLength; CK_OBJECT_HANDLE ckEncryptionKeyHandle; CK_OBJECT_HANDLE ckAuthenticationKeyHandle; CK_RV rv; CK_FUNCTION_LIST_PTR ckpFunctions = getFunctionList(env, obj); if (ckpFunctions == NULL) { return; } ckSessionHandle = jLongToCKULong(jSessionHandle); jByteArrayToCKByteArray(env, jOperationState, &ckpState, &ckStateLength); if ((*env)->ExceptionCheck(env)) { return; } ckEncryptionKeyHandle = jLongToCKULong(jEncryptionKeyHandle); ckAuthenticationKeyHandle = jLongToCKULong(jAuthenticationKeyHandle); rv = (*ckpFunctions->C_SetOperationState)(ckSessionHandle, ckpState, ckStateLength, ckEncryptionKeyHandle, ckAuthenticationKeyHandle); free(ckpState); if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; } }
/* * 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_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; } }
/* * 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 Java object into a pointer to CK-type or a CK-structure with the length in Bytes. * The memory of *ckpObjectPtr to be freed after use! This function is only used by * jAttributeToCKAttribute by now. * * @param env - used to call JNI funktions to get the Java classes and objects * @param jObject - the Java object to convert * @param ckpObjectPtr - the reference of the new pointer to the new CK-value or CK-structure * @param ckpLength - the reference of the length in bytes of the new CK-value or CK-structure */ void jObjectToPrimitiveCKObjectPtrPtr(JNIEnv *env, jobject jObject, CK_VOID_PTR *ckpObjectPtr, CK_ULONG *ckpLength) { jclass jLongClass, jBooleanClass, jByteArrayClass, jCharArrayClass; jclass jByteClass, jDateClass, jCharacterClass, jIntegerClass; jclass jBooleanArrayClass, jIntArrayClass, jLongArrayClass; jclass jStringClass; jclass jObjectClass, jClassClass; CK_VOID_PTR ckpVoid = *ckpObjectPtr; jmethodID jMethod; jobject jClassObject; jstring jClassNameString; char *classNameString, *exceptionMsgPrefix, *exceptionMsg; TRACE0("\nDEBUG: jObjectToPrimitiveCKObjectPtrPtr"); if (jObject == NULL) { *ckpObjectPtr = NULL; *ckpLength = 0; return; } jLongClass = (*env)->FindClass(env, "java/lang/Long"); if (jLongClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jLongClass)) { *ckpObjectPtr = jLongObjectToCKULongPtr(env, jObject); *ckpLength = sizeof(CK_ULONG); TRACE1("<converted long value %X>", *((CK_ULONG *) *ckpObjectPtr)); return; } jBooleanClass = (*env)->FindClass(env, "java/lang/Boolean"); if (jBooleanClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jBooleanClass)) { *ckpObjectPtr = jBooleanObjectToCKBBoolPtr(env, jObject); *ckpLength = sizeof(CK_BBOOL); TRACE0(" <converted boolean value "); TRACE0((*((CK_BBOOL *) *ckpObjectPtr) == TRUE) ? "TRUE>" : "FALSE>"); return; } jByteArrayClass = (*env)->FindClass(env, "[B"); if (jByteArrayClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jByteArrayClass)) { jByteArrayToCKByteArray(env, jObject, (CK_BYTE_PTR*)ckpObjectPtr, ckpLength); return; } jCharArrayClass = (*env)->FindClass(env, "[C"); if (jCharArrayClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jCharArrayClass)) { jCharArrayToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength); return; } jByteClass = (*env)->FindClass(env, "java/lang/Byte"); if (jByteClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jByteClass)) { *ckpObjectPtr = jByteObjectToCKBytePtr(env, jObject); *ckpLength = sizeof(CK_BYTE); TRACE1("<converted byte value %X>", *((CK_BYTE *) *ckpObjectPtr)); return; } jDateClass = (*env)->FindClass(env, CLASS_DATE); if (jDateClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jDateClass)) { *ckpObjectPtr = jDateObjectPtrToCKDatePtr(env, jObject); *ckpLength = sizeof(CK_DATE); TRACE3("<converted date value %.4s-%.2s-%.2s>", (*((CK_DATE *) *ckpObjectPtr)).year, (*((CK_DATE *) *ckpObjectPtr)).month, (*((CK_DATE *) *ckpObjectPtr)).day); return; } jCharacterClass = (*env)->FindClass(env, "java/lang/Character"); if (jCharacterClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jCharacterClass)) { *ckpObjectPtr = jCharObjectToCKCharPtr(env, jObject); *ckpLength = sizeof(CK_UTF8CHAR); TRACE1("<converted char value %c>", *((CK_CHAR *) *ckpObjectPtr)); return; } jIntegerClass = (*env)->FindClass(env, "java/lang/Integer"); if (jIntegerClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jIntegerClass)) { *ckpObjectPtr = jIntegerObjectToCKULongPtr(env, jObject); *ckpLength = sizeof(CK_ULONG); TRACE1("<converted integer value %X>", *((CK_ULONG *) *ckpObjectPtr)); return; } jBooleanArrayClass = (*env)->FindClass(env, "[Z"); if (jBooleanArrayClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jBooleanArrayClass)) { jBooleanArrayToCKBBoolArray(env, jObject, (CK_BBOOL**)ckpObjectPtr, ckpLength); return; } jIntArrayClass = (*env)->FindClass(env, "[I"); if (jIntArrayClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jIntArrayClass)) { jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength); return; } jLongArrayClass = (*env)->FindClass(env, "[J"); if (jLongArrayClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jLongArrayClass)) { jLongArrayToCKULongArray(env, jObject, (CK_ULONG_PTR*)ckpObjectPtr, ckpLength); return; } jStringClass = (*env)->FindClass(env, "java/lang/String"); if (jStringClass == NULL) { return; } if ((*env)->IsInstanceOf(env, jObject, jStringClass)) { jStringToCKUTF8CharArray(env, jObject, (CK_UTF8CHAR_PTR*)ckpObjectPtr, ckpLength); return; } /* type of jObject unknown, throw PKCS11RuntimeException */ jObjectClass = (*env)->FindClass(env, "java/lang/Object"); if (jObjectClass == NULL) { return; } jMethod = (*env)->GetMethodID(env, jObjectClass, "getClass", "()Ljava/lang/Class;"); if (jMethod == NULL) { return; } jClassObject = (*env)->CallObjectMethod(env, jObject, jMethod); assert(jClassObject != 0); jClassClass = (*env)->FindClass(env, "java/lang/Class"); if (jClassClass == NULL) { return; } jMethod = (*env)->GetMethodID(env, jClassClass, "getName", "()Ljava/lang/String;"); if (jMethod == NULL) { return; } jClassNameString = (jstring) (*env)->CallObjectMethod(env, jClassObject, jMethod); assert(jClassNameString != 0); classNameString = (char*) (*env)->GetStringUTFChars(env, jClassNameString, NULL); if (classNameString == NULL) { return; } exceptionMsgPrefix = "Java object of this class cannot be converted to native PKCS#11 type: "; exceptionMsg = (char *) malloc((strlen(exceptionMsgPrefix) + strlen(classNameString) + 1)); if (exceptionMsg == NULL) { (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString); throwOutOfMemoryError(env, 0); return; } strcpy(exceptionMsg, exceptionMsgPrefix); strcat(exceptionMsg, classNameString); (*env)->ReleaseStringUTFChars(env, jClassNameString, classNameString); throwPKCS11RuntimeException(env, exceptionMsg); free(exceptionMsg); *ckpObjectPtr = NULL; *ckpLength = 0; TRACE0("FINISHED\n"); }
/* * 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 ; }