switch EccVerify callback to use WOLFSSL cached jobject

pull/6/head
Chris Conlon 2015-10-28 15:49:27 -06:00
parent 2d55d1d4f6
commit 2e56f9807b
1 changed files with 209 additions and 165 deletions

View File

@ -2346,20 +2346,25 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
const unsigned char* keyDer, unsigned int keySz, int* result, const unsigned char* keyDer, unsigned int keySz, int* result,
void* ctx) void* ctx)
{ {
JNIEnv* jenv;
jint retval = 0; jint retval = 0;
jint vmret = 0; jint vmret = 0;
jmethodID eccVerifyMethodId;
jclass excClass;
jobjectRefType refcheck; JNIEnv* jenv; /* JNI Environment */
internCtx* myCtx = ctx; jclass excClass; /* WolfSSLJNIException class */
int needsDetach = 0; /* Should we explicitly detach? */
static jobject* g_cachedSSLObj; /* WolfSSLSession cached object */
jclass sessClass; /* WolfSSLSession class */
jfieldID ctxFid; /* WolfSSLSession->ctx FieldID */
jmethodID getCtxMethodId; /* WolfSSLSession->getAssCtxPtr() ID */
jobject ctxRef; /* WolfSSLContext object */
jclass innerCtxClass; /* WolfSSLContext class */
jmethodID eccVerifyMethodId;
jintArray j_result; jintArray j_result;
if (!g_vm) { if (!g_vm || !ssl || !sig || !hash || !keyDer || !result)
printf("Global JavaVM reference is null!\n");
return -1; return -1;
}
/* get JavaEnv from JavaVM */ /* get JavaEnv from JavaVM */
vmret = (int)((*g_vm)->GetEnv(g_vm, (void**) &jenv, JNI_VERSION_1_6)); vmret = (int)((*g_vm)->GetEnv(g_vm, (void**) &jenv, JNI_VERSION_1_6));
@ -2370,12 +2375,11 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL); vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL);
#endif #endif
if (vmret) { if (vmret) {
printf("Failed to attach JNIEnv to thread\n"); return -1;
} else {
printf("Attached JNIEnv to thread\n");
} }
needsDetach = 1;
} else if (vmret != JNI_OK) { } else if (vmret != JNI_OK) {
printf("Error getting JNIEnv from JavaVM, ret = %d\n", vmret); return -1;
} }
/* find exception class in case we need it */ /* find exception class in case we need it */
@ -2383,40 +2387,51 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
if ((*jenv)->ExceptionOccurred(jenv)) { if ((*jenv)->ExceptionOccurred(jenv)) {
(*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv); (*jenv)->ExceptionClear(jenv);
printf("can't find WolfSSLJNIException class, NativeEccVerifyCb\n"); if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* check if our stored object reference is valid */ /* get stored WolfSSLSession jobject */
refcheck = (*jenv)->GetObjectRefType(jenv, myCtx->obj); g_cachedSSLObj = (jobject*) wolfSSL_get_jobject((WOLFSSL*)ssl);
if (refcheck == 2) { if (!g_cachedSSLObj) {
(*jenv)->ThrowNew(jenv, excClass,
"Can't get native WolfSSLSession object reference in "
"NativeEccVerifyCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1;
}
/* lookup WolfSSLSession class from global object ref */ /* lookup WolfSSLSession class from object */
jclass sessClass = (*jenv)->GetObjectClass(jenv, myCtx->obj); sessClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
if (!sessClass) { if (!sessClass) {
(*jenv)->ThrowNew(jenv, excClass, (*jenv)->ThrowNew(jenv, excClass,
"Can't get native WolfSSLSession class reference " "Can't get native WolfSSLSession class reference in "
"in NativeEccVerifyCb"); "NativeEccVerifyCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* lookup WolfSSLContext private member fieldID */ /* lookup WolfSSLContext private member fieldID */
jfieldID ctxFid = (*jenv)->GetFieldID(jenv, sessClass, "ctx", ctxFid = (*jenv)->GetFieldID(jenv, sessClass, "ctx",
"Lcom/wolfssl/WolfSSLContext;"); "Lcom/wolfssl/WolfSSLContext;");
if (!ctxFid) { if (!ctxFid) {
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 WolfSSLContext field ID " "Can't get native WolfSSLContext field ID "
"in NativeEccVerifyCb"); "in NativeEccVerifyCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* find getContextPtr() method */ /* find getContextPtr() method */
jmethodID getCtxMethodId = (*jenv)->GetMethodID(jenv, sessClass, getCtxMethodId = (*jenv)->GetMethodID(jenv, sessClass,
"getAssociatedContextPtr", "getAssociatedContextPtr",
"()Lcom/wolfssl/WolfSSLContext;"); "()Lcom/wolfssl/WolfSSLContext;");
if (!getCtxMethodId) { if (!getCtxMethodId) {
@ -2424,33 +2439,38 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
(*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv); (*jenv)->ExceptionClear(jenv);
} }
(*jenv)->ThrowNew(jenv, excClass, (*jenv)->ThrowNew(jenv, excClass,
"Can't get getAssociatedContextPtr() method ID " "Can't get getAssociatedContextPtr() method ID "
"in NativeEccVerifyCb"); "in NativeEccVerifyCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* get WolfSSLContext ctx object from Java land */ /* get WolfSSLContext ctx object from Java land */
jobject ctxref = (*jenv)->CallObjectMethod(jenv, myCtx->obj, ctxRef = (*jenv)->CallObjectMethod(jenv, (jobject)(*g_cachedSSLObj),
getCtxMethodId); getCtxMethodId);
if (!ctxref) { if (!ctxRef) {
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 WolfSSLContext object in NativeEccVerifyCb"); "Can't get WolfSSLContext object in NativeEccVerifyCb");
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* get WolfSSLContext class reference from Java land */ /* get WolfSSLContext class reference from Java land */
jclass innerCtxClass = (*jenv)->GetObjectClass(jenv, ctxref); innerCtxClass = (*jenv)->GetObjectClass(jenv, ctxRef);
if (!innerCtxClass) { if (!innerCtxClass) {
(*jenv)->ThrowNew(jenv, excClass, (*jenv)->ThrowNew(jenv, excClass,
"Can't get native WolfSSLContext class reference " "Can't get native WolfSSLContext class reference "
"in NativeEccVerifyCb"); "in NativeEccVerifyCb");
(*jenv)->DeleteLocalRef(jenv, ctxRef);
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
@ -2465,27 +2485,34 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
(*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv); (*jenv)->ExceptionClear(jenv);
} }
(*jenv)->ThrowNew(jenv, excClass,
printf("Error getting internalEccVerifyCallback method " "Error getting internalEccVerifyCallback method from JNI");
"from JNI\n"); (*jenv)->DeleteLocalRef(jenv, ctxRef);
retval = -1; if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1;
} }
if (retval == 0)
{
/* create ByteBuffer to wrap 'sig' */ /* create ByteBuffer to wrap 'sig' */
jobject sigBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)sig, jobject sigBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)sig, sigSz);
sigSz);
if (!sigBB) { if (!sigBB) {
printf("failed to create eccVerify out ByteBuffer\n"); (*jenv)->ThrowNew(jenv, excClass,
"Failed to create eccVerify out ByteBuffer");
(*jenv)->DeleteLocalRef(jenv, ctxRef);
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* create ByteBuffer to wrap 'hash' */ /* create ByteBuffer to wrap 'hash' */
jobject hashBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)hash, jobject hashBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)hash, hashSz);
hashSz);
if (!hashBB) { if (!hashBB) {
printf("failed to create eccVerify hash ByteBuffer\n"); (*jenv)->ThrowNew(jenv, excClass,
"Failed to create eccVerify hash ByteBuffer");
(*jenv)->DeleteLocalRef(jenv, ctxRef);
(*jenv)->DeleteLocalRef(jenv, sigBB);
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
@ -2493,7 +2520,13 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
jobject keyDerBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)keyDer, jobject keyDerBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)keyDer,
keySz); keySz);
if (!keyDerBB) { if (!keyDerBB) {
printf("failed to create eccVerify keyDer ByteBuffer\n"); (*jenv)->ThrowNew(jenv, excClass,
"Failed to create eccVerify keyDer ByteBuffer");
(*jenv)->DeleteLocalRef(jenv, ctxRef);
(*jenv)->DeleteLocalRef(jenv, sigBB);
(*jenv)->DeleteLocalRef(jenv, hashBB);
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
@ -2501,52 +2534,63 @@ int NativeEccVerifyCb(WOLFSSL* ssl, const unsigned char* sig,
* an OUTPUT parameter from Java. Only needs to have 1 element */ * an OUTPUT parameter from Java. Only needs to have 1 element */
j_result = (*jenv)->NewIntArray(jenv, 1); j_result = (*jenv)->NewIntArray(jenv, 1);
if (!j_result) { if (!j_result) {
printf("failed to create result intArray\n"); (*jenv)->ThrowNew(jenv, excClass,
"Failed to create result intArray in EccVerifyCb");
(*jenv)->DeleteLocalRef(jenv, ctxRef);
(*jenv)->DeleteLocalRef(jenv, sigBB);
(*jenv)->DeleteLocalRef(jenv, hashBB);
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1; return -1;
} }
/* call Java ECC verify callback, java layer handles /* call Java ECC verify callback, java layer handles
* adding CTX reference */ * adding CTX reference */
retval = (*jenv)->CallIntMethod(jenv, ctxref, eccVerifyMethodId, retval = (*jenv)->CallIntMethod(jenv, ctxRef, eccVerifyMethodId,
myCtx->obj, sigBB, (jlong)sigSz, hashBB, (jlong)hashSz, (jobject)(*g_cachedSSLObj), sigBB, (jlong)sigSz, hashBB,
keyDerBB, (jlong)keySz, j_result); (jlong)hashSz, keyDerBB, (jlong)keySz, j_result);
if ((*jenv)->ExceptionOccurred(jenv)) { if ((*jenv)->ExceptionOccurred(jenv)) {
(*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv); (*jenv)->ExceptionClear(jenv);
printf("exception occurred in EccVerifyCb\n"); (*jenv)->DeleteLocalRef(jenv, ctxRef);
retval = -1; (*jenv)->DeleteLocalRef(jenv, sigBB);
(*jenv)->DeleteLocalRef(jenv, hashBB);
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
(*jenv)->DeleteLocalRef(jenv, j_result);
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return -1;
} }
if (retval == 0) {
/* copy j_result into result */ /* copy j_result into result */
jint tmpVal; jint tmpVal;
(*jenv)->GetIntArrayRegion(jenv, j_result, 0, 1, &tmpVal); (*jenv)->GetIntArrayRegion(jenv, j_result, 0, 1, &tmpVal);
if ((*jenv)->ExceptionOccurred(jenv)) { if ((*jenv)->ExceptionOccurred(jenv)) {
(*jenv)->ExceptionDescribe(jenv); (*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv); (*jenv)->ExceptionClear(jenv);
printf("failed during j_result copy, NativeEccVerifyCb\n"); (*jenv)->DeleteLocalRef(jenv, ctxRef);
retval = -1; (*jenv)->DeleteLocalRef(jenv, sigBB);
} (*jenv)->DeleteLocalRef(jenv, hashBB);
*result = tmpVal; (*jenv)->DeleteLocalRef(jenv, keyDerBB);
} (*jenv)->DeleteLocalRef(jenv, j_result);
} if (needsDetach)
/* detach JNIEnv from thread */
(*g_vm)->DetachCurrentThread(g_vm); (*g_vm)->DetachCurrentThread(g_vm);
} else {
/* clear any existing exception before we throw another */
if ((*jenv)->ExceptionOccurred(jenv)) {
(*jenv)->ExceptionDescribe(jenv);
(*jenv)->ExceptionClear(jenv);
}
(*jenv)->ThrowNew(jenv, excClass,
"Object reference invalid in NativeEccVerifyCb");
return -1; return -1;
} }
*result = tmpVal;
/* delete local refs */
(*jenv)->DeleteLocalRef(jenv, ctxRef);
(*jenv)->DeleteLocalRef(jenv, sigBB);
(*jenv)->DeleteLocalRef(jenv, hashBB);
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
(*jenv)->DeleteLocalRef(jenv, j_result);
/* detach JNIEnv from thread */
if (needsDetach)
(*g_vm)->DetachCurrentThread(g_vm);
return retval; return retval;
} }