JSSE: cache jmethodIDs used in native I/O callbacks globally, improves performance
parent
d95297f12c
commit
767a289113
|
@ -53,6 +53,16 @@ JavaVM* g_vm;
|
||||||
/* global object refs for logging callbacks */
|
/* global object refs for logging callbacks */
|
||||||
static jobject g_loggingCbIfaceObj;
|
static jobject g_loggingCbIfaceObj;
|
||||||
|
|
||||||
|
/* global method IDs we can cache for performance */
|
||||||
|
jmethodID g_sslIORecvMethodId = NULL;
|
||||||
|
jmethodID g_sslIOSendMethodId = NULL;
|
||||||
|
jmethodID g_bufferPositionMethodId = NULL;
|
||||||
|
jmethodID g_bufferLimitMethodId = NULL;
|
||||||
|
jmethodID g_bufferHasArrayMethodId = NULL;
|
||||||
|
jmethodID g_bufferArrayMethodId = NULL;
|
||||||
|
jmethodID g_bufferSetPositionMethodId = NULL;
|
||||||
|
jmethodID g_verifyCallbackMethodId = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_FIPS
|
#ifdef HAVE_FIPS
|
||||||
/* global object ref for FIPS error callback */
|
/* global object ref for FIPS error callback */
|
||||||
static jobject g_fipsCbIfaceObj;
|
static jobject g_fipsCbIfaceObj;
|
||||||
|
@ -61,16 +71,116 @@ static jobject g_fipsCbIfaceObj;
|
||||||
/* custom native fn prototypes */
|
/* custom native fn prototypes */
|
||||||
void NativeLoggingCallback(const int logLevel, const char *const logMessage);
|
void NativeLoggingCallback(const int logLevel, const char *const logMessage);
|
||||||
|
|
||||||
/* called when native library is loaded */
|
/* Called when native library is loaded.
|
||||||
|
* We also cache global jmethodIDs here for performance. */
|
||||||
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
|
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||||
{
|
{
|
||||||
|
JNIEnv* env = NULL;
|
||||||
|
jclass sslClass = NULL;
|
||||||
|
jclass byteBufferClass = NULL;
|
||||||
|
jclass verifyClass = NULL;
|
||||||
(void)reserved;
|
(void)reserved;
|
||||||
|
|
||||||
/* store JavaVM */
|
/* store JavaVM */
|
||||||
g_vm = vm;
|
g_vm = vm;
|
||||||
|
|
||||||
|
/* get JNIEnv from JavaVM */
|
||||||
|
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) {
|
||||||
|
printf("Unable to get JNIEnv from JavaVM in JNI_OnLoad()\n");
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cache the method ID for IO send and recv callbacks */
|
||||||
|
sslClass = (*env)->FindClass(env, "com/wolfssl/WolfSSLSession");
|
||||||
|
if (sslClass == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_sslIORecvMethodId = (*env)->GetMethodID(env, sslClass,
|
||||||
|
"internalIOSSLRecvCallback",
|
||||||
|
"(Lcom/wolfssl/WolfSSLSession;[BI)I");
|
||||||
|
|
||||||
|
g_sslIOSendMethodId = (*env)->GetMethodID(env, sslClass,
|
||||||
|
"internalIOSSLSendCallback",
|
||||||
|
"(Lcom/wolfssl/WolfSSLSession;[BI)I");
|
||||||
|
|
||||||
|
/* Cache ByteBuffer method IDs */
|
||||||
|
byteBufferClass = (*env)->FindClass(env, "java/nio/ByteBuffer");
|
||||||
|
if (byteBufferClass == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bufferPositionMethodId = (*env)->GetMethodID(env, byteBufferClass,
|
||||||
|
"position", "()I");
|
||||||
|
if (g_bufferPositionMethodId == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bufferLimitMethodId = (*env)->GetMethodID(env, byteBufferClass,
|
||||||
|
"limit", "()I");
|
||||||
|
if (g_bufferLimitMethodId == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bufferHasArrayMethodId = (*env)->GetMethodID(env, byteBufferClass,
|
||||||
|
"hasArray", "()Z");
|
||||||
|
if (g_bufferHasArrayMethodId == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bufferArrayMethodId = (*env)->GetMethodID(env, byteBufferClass,
|
||||||
|
"array", "()[B");
|
||||||
|
if (g_bufferArrayMethodId == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_bufferSetPositionMethodId = (*env)->GetMethodID(env, byteBufferClass,
|
||||||
|
"position", "(I)Ljava/nio/Buffer;");
|
||||||
|
if (g_bufferSetPositionMethodId == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cache verify callback method ID */
|
||||||
|
verifyClass = (*env)->FindClass(env, "com/wolfssl/WolfSSLVerifyCallback");
|
||||||
|
if (verifyClass == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_verifyCallbackMethodId = (*env)->GetMethodID(env, verifyClass,
|
||||||
|
"verifyCallback", "(IJ)I");
|
||||||
|
if (g_verifyCallbackMethodId == NULL) {
|
||||||
|
return JNI_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clean up local reference to class, not needed */
|
||||||
|
(*env)->DeleteLocalRef(env, sslClass);
|
||||||
|
(*env)->DeleteLocalRef(env, byteBufferClass);
|
||||||
|
(*env)->DeleteLocalRef(env, verifyClass);
|
||||||
|
|
||||||
return JNI_VERSION_1_6;
|
return JNI_VERSION_1_6;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called when native library is unloaded.
|
||||||
|
* We clear cached method IDs here. */
|
||||||
|
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM* vm, void* reserved)
|
||||||
|
{
|
||||||
|
JNIEnv* env;
|
||||||
|
|
||||||
|
if ((*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_6) != JNI_OK) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear cached method ID */
|
||||||
|
g_sslIORecvMethodId = NULL;
|
||||||
|
g_sslIOSendMethodId = NULL;
|
||||||
|
g_bufferPositionMethodId = NULL;
|
||||||
|
g_bufferLimitMethodId = NULL;
|
||||||
|
g_bufferHasArrayMethodId = NULL;
|
||||||
|
g_bufferArrayMethodId = NULL;
|
||||||
|
g_bufferSetPositionMethodId = NULL;
|
||||||
|
g_verifyCallbackMethodId = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_init
|
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSL_init
|
||||||
(JNIEnv* jenv, jobject jcl)
|
(JNIEnv* jenv, jobject jcl)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1028,7 +1028,6 @@ int NativeIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
|
|
||||||
jobject ctxRef; /* WolfSSLContext object */
|
jobject ctxRef; /* WolfSSLContext object */
|
||||||
jclass innerCtxClass; /* WolfSSLContext class */
|
jclass innerCtxClass; /* WolfSSLContext class */
|
||||||
jmethodID recvCbMethodId; /* internalIORecvCallback ID */
|
|
||||||
jbyteArray inData;
|
jbyteArray inData;
|
||||||
|
|
||||||
if (!g_vm || !ssl || !buf || !ctx) {
|
if (!g_vm || !ssl || !buf || !ctx) {
|
||||||
|
@ -1140,18 +1139,10 @@ int NativeIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* call internal I/O recv callback */
|
/* make sure cached recv callback method ID is not null */
|
||||||
recvCbMethodId = (*jenv)->GetMethodID(jenv, innerCtxClass,
|
if (!g_sslIORecvMethodId) {
|
||||||
"internalIORecvCallback",
|
|
||||||
"(Lcom/wolfssl/WolfSSLSession;[BI)I");
|
|
||||||
if (!recvCbMethodId) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Error getting internalIORecvCallback method from JNI");
|
"Cached recv callback method ID is null in NativeIORecvCb");
|
||||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
|
||||||
if (needsDetach)
|
if (needsDetach)
|
||||||
(*g_vm)->DetachCurrentThread(g_vm);
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||||
|
@ -1161,7 +1152,7 @@ int NativeIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
inData = (*jenv)->NewByteArray(jenv, sz);
|
inData = (*jenv)->NewByteArray(jenv, sz);
|
||||||
if (!inData) {
|
if (!inData) {
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Error getting internalIORecvCallback method from JNI");
|
"Error creating jbyteArray in NativeIORecvCb");
|
||||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||||
if (needsDetach)
|
if (needsDetach)
|
||||||
(*g_vm)->DetachCurrentThread(g_vm);
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
@ -1170,7 +1161,7 @@ int NativeIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
|
|
||||||
/* call Java send callback, ignore native ctx since Java
|
/* call Java send callback, ignore native ctx since Java
|
||||||
* handles it */
|
* handles it */
|
||||||
retval = (*jenv)->CallIntMethod(jenv, ctxRef, recvCbMethodId,
|
retval = (*jenv)->CallIntMethod(jenv, ctxRef, g_sslIORecvMethodId,
|
||||||
(jobject)(*g_cachedSSLObj),
|
(jobject)(*g_cachedSSLObj),
|
||||||
inData, (jint)sz);
|
inData, (jint)sz);
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,6 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store)
|
||||||
jint vmret = 0;
|
jint vmret = 0;
|
||||||
jint retval = -1;
|
jint retval = -1;
|
||||||
jclass excClass;
|
jclass excClass;
|
||||||
jclass verifyClass = NULL;
|
|
||||||
jmethodID verifyMethod;
|
|
||||||
jobjectRefType refcheck;
|
jobjectRefType refcheck;
|
||||||
SSLAppData* appData; /* WOLFSSL app data, stored verify cb obj */
|
SSLAppData* appData; /* WOLFSSL app data, stored verify cb obj */
|
||||||
jobject* g_verifySSLCbIfaceObj; /* Global jobject, stored in app data */
|
jobject* g_verifySSLCbIfaceObj; /* Global jobject, stored in app data */
|
||||||
|
@ -156,34 +154,20 @@ int NativeSSLVerifyCallback(int preverify_ok, WOLFSSL_X509_STORE_CTX* store)
|
||||||
refcheck = (*jenv)->GetObjectRefType(jenv, *g_verifySSLCbIfaceObj);
|
refcheck = (*jenv)->GetObjectRefType(jenv, *g_verifySSLCbIfaceObj);
|
||||||
if (refcheck == 2) {
|
if (refcheck == 2) {
|
||||||
|
|
||||||
/* lookup WolfSSLVerifyCallback class from global object ref */
|
if (!g_verifyCallbackMethodId) {
|
||||||
verifyClass = (*jenv)->GetObjectClass(jenv, *g_verifySSLCbIfaceObj);
|
|
||||||
if (!verifyClass) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
(*jenv)->ExceptionClear(jenv);
|
(*jenv)->ExceptionClear(jenv);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Can't get native WolfSSLVerifyCallback class reference");
|
"verifyCallback method ID is null in NativeSSLVerifyCallback");
|
||||||
return -107;
|
return -107;
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyMethod = (*jenv)->GetMethodID(jenv, verifyClass,
|
|
||||||
"verifyCallback", "(IJ)I");
|
|
||||||
if (verifyMethod == 0) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Error getting verifyCallback method from JNI");
|
|
||||||
return -108;
|
|
||||||
}
|
|
||||||
|
|
||||||
retval = (*jenv)->CallIntMethod(jenv, *g_verifySSLCbIfaceObj,
|
retval = (*jenv)->CallIntMethod(jenv, *g_verifySSLCbIfaceObj,
|
||||||
verifyMethod, preverify_ok, (jlong)(uintptr_t)store);
|
g_verifyCallbackMethodId, preverify_ok,
|
||||||
|
(jlong)(uintptr_t)store);
|
||||||
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
/* exception occurred on the Java side during method call */
|
/* exception occurred on the Java side during method call */
|
||||||
|
@ -1415,14 +1399,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
int outSz = length;
|
int outSz = length;
|
||||||
byte* data = NULL;
|
byte* data = NULL;
|
||||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||||
|
|
||||||
jclass excClass;
|
jclass excClass;
|
||||||
jclass buffClass;
|
|
||||||
jmethodID positionMeth;
|
|
||||||
jmethodID limitMeth;
|
|
||||||
jmethodID hasArrayMeth;
|
|
||||||
jmethodID arrayMeth;
|
|
||||||
jmethodID setPositionMeth;
|
|
||||||
|
|
||||||
jint position;
|
jint position;
|
||||||
jint limit;
|
jint limit;
|
||||||
|
@ -1444,51 +1421,15 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get ByteBuffer class */
|
|
||||||
buffClass = (*jenv)->GetObjectClass(jenv, buf);
|
|
||||||
if (buffClass == NULL) {
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to find ByteBuffer class in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get ByteBuffer position */
|
/* Get ByteBuffer position */
|
||||||
positionMeth = (*jenv)->GetMethodID(jenv, buffClass, "position", "()I");
|
position = (*jenv)->CallIntMethod(jenv, buf, g_bufferPositionMethodId);
|
||||||
if (positionMeth == NULL) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to find ByteBuffer position() method in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
position = (*jenv)->CallIntMethod(jenv, buf, positionMeth);
|
|
||||||
|
|
||||||
/* Get ByteBuffer limit */
|
/* Get ByteBuffer limit */
|
||||||
limitMeth = (*jenv)->GetMethodID(jenv, buffClass, "limit", "()I");
|
limit = (*jenv)->CallIntMethod(jenv, buf, g_bufferLimitMethodId);
|
||||||
if (limitMeth == NULL) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to find ByteBuffer limit() method in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
limit = (*jenv)->CallIntMethod(jenv, buf, limitMeth);
|
|
||||||
|
|
||||||
/* Get and call ByteBuffer.hasArray() before calling array() */
|
/* Get and call ByteBuffer.hasArray() before calling array() */
|
||||||
hasArrayMeth = (*jenv)->GetMethodID(jenv, buffClass, "hasArray", "()Z");
|
hasArray = (*jenv)->CallBooleanMethod(jenv, buf,
|
||||||
if (hasArrayMeth == NULL) {
|
g_bufferHasArrayMethodId);
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to find ByteBuffer hasArray() method in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Only read up to maximum space we have in this ByteBuffer */
|
/* Only read up to maximum space we have in this ByteBuffer */
|
||||||
maxOutputSz = (limit - position);
|
maxOutputSz = (limit - position);
|
||||||
|
@ -1496,21 +1437,10 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
outSz = maxOutputSz;
|
outSz = maxOutputSz;
|
||||||
}
|
}
|
||||||
|
|
||||||
hasArray = (*jenv)->CallBooleanMethod(jenv, buf, hasArrayMeth);
|
|
||||||
|
|
||||||
if (hasArray) {
|
if (hasArray) {
|
||||||
/* Get reference to underlying byte[] from ByteBuffer */
|
/* Get reference to underlying byte[] from ByteBuffer */
|
||||||
arrayMeth = (*jenv)->GetMethodID(jenv, buffClass, "array", "()[B");
|
bufArr = (jbyteArray)(*jenv)->CallObjectMethod(jenv, buf,
|
||||||
if (arrayMeth == NULL) {
|
g_bufferArrayMethodId);
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to find ByteBuffer array() method in native read()");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
bufArr = (jbyteArray)(*jenv)->CallObjectMethod(jenv, buf, arrayMeth);
|
|
||||||
|
|
||||||
/* Get array elements */
|
/* Get array elements */
|
||||||
data = (byte *)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL);
|
data = (byte *)(*jenv)->GetByteArrayElements(jenv, bufArr, NULL);
|
||||||
|
@ -1518,7 +1448,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
(*jenv)->ExceptionClear(jenv);
|
(*jenv)->ExceptionClear(jenv);
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Exception when calling ByteBuffer.array() in native read()");
|
"Exception when calling ByteBuffer.array() in native read()");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1526,24 +1456,24 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
data = (byte *)(*jenv)->GetDirectBufferAddress(jenv, buf);
|
data = (byte *)(*jenv)->GetDirectBufferAddress(jenv, buf);
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Failed to get DirectBuffer address in native read()");
|
"Failed to get DirectBuffer address in native read()");
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
size = SSLReadNonblockingWithSelectPoll(ssl, data + position,
|
size = SSLReadNonblockingWithSelectPoll(ssl, data + position,
|
||||||
maxOutputSz, (int)timeout);
|
maxOutputSz, (int)timeout);
|
||||||
|
|
||||||
/* Relase array elements */
|
/* Relase array elements */
|
||||||
if (hasArray) {
|
if (hasArray) {
|
||||||
if (size < 0) {
|
if (size < 0) {
|
||||||
(*jenv)->ReleaseByteArrayElements(jenv, bufArr, (jbyte *)data,
|
(*jenv)->ReleaseByteArrayElements(jenv, bufArr,
|
||||||
JNI_ABORT);
|
(jbyte *)data, JNI_ABORT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(*jenv)->ReleaseByteArrayElements(jenv, bufArr,
|
(*jenv)->ReleaseByteArrayElements(jenv, bufArr,
|
||||||
(jbyte *)data, 0);
|
(jbyte *)data, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,22 +1481,8 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
||||||
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
/* Update ByteBuffer position() based on bytes written */
|
/* Update ByteBuffer position() based on bytes written */
|
||||||
setPositionMeth = (*jenv)->GetMethodID(jenv, buffClass,
|
(*jenv)->CallVoidMethod(jenv, buf, g_bufferSetPositionMethodId,
|
||||||
"position", "(I)Ljava/nio/Buffer;");
|
position + size);
|
||||||
if (setPositionMeth == NULL) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Failed to set ByteBuffer position() from "
|
|
||||||
"native read()");
|
|
||||||
size = -1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(*jenv)->CallVoidMethod(jenv, buf, setPositionMeth,
|
|
||||||
position + size);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6143,8 +6059,6 @@ int NativeSSLIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
int needsDetach = 0; /* Should we explicitly detach? */
|
int needsDetach = 0; /* Should we explicitly detach? */
|
||||||
|
|
||||||
jobject* g_cachedSSLObj; /* WolfSSLSession cached object */
|
jobject* g_cachedSSLObj; /* WolfSSLSession cached object */
|
||||||
jclass sslClass; /* WolfSSLSession class */
|
|
||||||
jmethodID recvCbMethodId; /* internalIORecvCallback ID */
|
|
||||||
jbyteArray inData;
|
jbyteArray inData;
|
||||||
|
|
||||||
if (!g_vm || !ssl || !buf || !ctx) {
|
if (!g_vm || !ssl || !buf || !ctx) {
|
||||||
|
@ -6189,28 +6103,9 @@ int NativeSSLIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup WolfSSLSession class from object */
|
if (!g_sslIORecvMethodId) {
|
||||||
sslClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
|
|
||||||
if (!sslClass) {
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Can't get native WolfSSLSession class reference in "
|
"Cached recv callback method ID is null in internalIORecvCallback");
|
||||||
"NativeSSLIORecvCb");
|
|
||||||
if (needsDetach)
|
|
||||||
(*g_vm)->DetachCurrentThread(g_vm);
|
|
||||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* call internal I/O recv callback */
|
|
||||||
recvCbMethodId = (*jenv)->GetMethodID(jenv, sslClass,
|
|
||||||
"internalIOSSLRecvCallback",
|
|
||||||
"(Lcom/wolfssl/WolfSSLSession;[BI)I");
|
|
||||||
if (!recvCbMethodId) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
|
||||||
(*jenv)->ExceptionClear(jenv);
|
|
||||||
}
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Error getting internalIORecvCallback method from JNI");
|
|
||||||
if (needsDetach)
|
if (needsDetach)
|
||||||
(*g_vm)->DetachCurrentThread(g_vm);
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||||
|
@ -6229,7 +6124,7 @@ int NativeSSLIORecvCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
/* call Java send callback, ignore native ctx since Java
|
/* call Java send callback, ignore native ctx since Java
|
||||||
* handles it */
|
* handles it */
|
||||||
retval = (*jenv)->CallIntMethod(jenv, (jobject)(*g_cachedSSLObj),
|
retval = (*jenv)->CallIntMethod(jenv, (jobject)(*g_cachedSSLObj),
|
||||||
recvCbMethodId, (jobject)(*g_cachedSSLObj), inData, (jint)sz);
|
g_sslIORecvMethodId, (jobject)(*g_cachedSSLObj), inData, (jint)sz);
|
||||||
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
@ -6285,8 +6180,6 @@ int NativeSSLIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
int needsDetach = 0; /* Should we explicitly detach? */
|
int needsDetach = 0; /* Should we explicitly detach? */
|
||||||
|
|
||||||
jobject* g_cachedSSLObj; /* WolfSSLSession cached object */
|
jobject* g_cachedSSLObj; /* WolfSSLSession cached object */
|
||||||
jclass sslClass; /* WolfSSLSession class */
|
|
||||||
jmethodID sendCbMethodId; /* internalIOSendCallback ID */
|
|
||||||
jbyteArray outData; /* jbyteArray for data to send */
|
jbyteArray outData; /* jbyteArray for data to send */
|
||||||
|
|
||||||
if (!g_vm || !ssl || !buf || !ctx) {
|
if (!g_vm || !ssl || !buf || !ctx) {
|
||||||
|
@ -6331,27 +6224,14 @@ int NativeSSLIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* lookup WolfSSLSession class from object */
|
|
||||||
sslClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
|
|
||||||
if (!sslClass) {
|
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
|
||||||
"Can't get native WolfSSLSession class reference");
|
|
||||||
if (needsDetach)
|
|
||||||
(*g_vm)->DetachCurrentThread(g_vm);
|
|
||||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* call internal I/O send callback */
|
/* call internal I/O send callback */
|
||||||
sendCbMethodId = (*jenv)->GetMethodID(jenv, sslClass,
|
if (!g_sslIOSendMethodId) {
|
||||||
"internalIOSSLSendCallback",
|
|
||||||
"(Lcom/wolfssl/WolfSSLSession;[BI)I");
|
|
||||||
if (!sendCbMethodId) {
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
(*jenv)->ExceptionClear(jenv);
|
(*jenv)->ExceptionClear(jenv);
|
||||||
}
|
}
|
||||||
(*jenv)->ThrowNew(jenv, excClass,
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
"Error getting internalIOSendCallback method from JNI");
|
"internalIOSendCallback method ID is null in internalIOSendCb");
|
||||||
if (needsDetach)
|
if (needsDetach)
|
||||||
(*g_vm)->DetachCurrentThread(g_vm);
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
return WOLFSSL_CBIO_ERR_GENERAL;
|
return WOLFSSL_CBIO_ERR_GENERAL;
|
||||||
|
@ -6382,7 +6262,7 @@ int NativeSSLIOSendCb(WOLFSSL *ssl, char *buf, int sz, void *ctx)
|
||||||
/* call Java send callback, ignore native ctx since Java
|
/* call Java send callback, ignore native ctx since Java
|
||||||
* handles it */
|
* handles it */
|
||||||
retval = (*jenv)->CallIntMethod(jenv, (jobject)(*g_cachedSSLObj),
|
retval = (*jenv)->CallIntMethod(jenv, (jobject)(*g_cachedSSLObj),
|
||||||
sendCbMethodId, (jobject)(*g_cachedSSLObj), outData, (jint)sz);
|
g_sslIOSendMethodId, (jobject)(*g_cachedSSLObj), outData, (jint)sz);
|
||||||
|
|
||||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
(*jenv)->ExceptionDescribe(jenv);
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
|
|
@ -25,7 +25,19 @@
|
||||||
#define _Included_com_wolfssl_globals
|
#define _Included_com_wolfssl_globals
|
||||||
|
|
||||||
/* global JavaVM reference for JNIEnv lookup */
|
/* global JavaVM reference for JNIEnv lookup */
|
||||||
extern JavaVM* g_vm;
|
extern JavaVM* g_vm;
|
||||||
|
|
||||||
|
/* Cache static jmethodIDs for performance, since they are guaranteed to be the
|
||||||
|
* same across all threads once cached. Initialized in JNI_OnLoad() and freed in
|
||||||
|
* JNI_OnUnload(). */
|
||||||
|
extern jmethodID g_sslIORecvMethodId; /* WolfSSLSession.internalIOSSLRecvCallback */
|
||||||
|
extern jmethodID g_sslIOSendMethodId; /* WolfSSLSession.internalIOSSLSendCallback */
|
||||||
|
extern jmethodID g_bufferPositionMethodId; /* ByteBuffer.position() */
|
||||||
|
extern jmethodID g_bufferLimitMethodId; /* ByteBuffer.limit() */
|
||||||
|
extern jmethodID g_bufferHasArrayMethodId; /* ByteBuffer.hasArray() */
|
||||||
|
extern jmethodID g_bufferArrayMethodId; /* ByteBuffer.array() */
|
||||||
|
extern jmethodID g_bufferSetPositionMethodId; /* ByteBuffer.position(int) */
|
||||||
|
extern jmethodID g_verifyCallbackMethodId; /* WolfSSLVerifyCallback.verifyCallback */
|
||||||
|
|
||||||
/* struct to hold I/O class, object refs */
|
/* struct to hold I/O class, object refs */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -39,4 +51,3 @@ unsigned int NativePskServerCb(WOLFSSL* ssl, const char* identity,
|
||||||
unsigned char* key, unsigned int max_key_len);
|
unsigned char* key, unsigned int max_key_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue