JNI: add RSA-PSS sign/verify and RSA sign check PK callbacks
parent
b937eec507
commit
1aec153270
|
|
@ -26,6 +26,8 @@
|
|||
#include <wolfssl/options.h>
|
||||
#endif
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/hash.h>
|
||||
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||
|
||||
#include "com_wolfssl_WolfCryptRSA.h"
|
||||
|
||||
|
|
@ -214,6 +216,189 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doEnc
|
|||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doPssSign
|
||||
(JNIEnv* jenv, jobject jcl, jobject in, jlong inSz, jobject out, jintArray outSz, jint hash, jint mgf, jobject keyDer, jlong keySz)
|
||||
{
|
||||
#ifdef WC_RSA_PSS
|
||||
int ret;
|
||||
WC_RNG rng;
|
||||
RsaKey myKey;
|
||||
int rngInit = 0;
|
||||
int keyInit = 0;
|
||||
unsigned int idx = 0;
|
||||
unsigned int tmpOut;
|
||||
unsigned char* inBuf = NULL;
|
||||
unsigned char* outBuf = NULL;
|
||||
unsigned char* keyBuf = NULL;
|
||||
enum wc_HashType hashType;
|
||||
(void)jcl;
|
||||
|
||||
if ((inSz < 0) || (keySz < 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
inBuf = (*jenv)->GetDirectBufferAddress(jenv, in);
|
||||
if (inBuf == NULL) {
|
||||
printf("problem getting in buffer address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
outBuf = (*jenv)->GetDirectBufferAddress(jenv, out);
|
||||
if (outBuf == NULL) {
|
||||
printf("problem getting out buffer address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
keyBuf = (*jenv)->GetDirectBufferAddress(jenv, keyDer);
|
||||
if (keyBuf == NULL) {
|
||||
printf("problem getting key buffer address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hashType = wc_OidGetHash(hash);
|
||||
if (hashType == WC_HASH_TYPE_NONE) {
|
||||
printf("doPssSign: unsupported hash OID %d\n", hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get output buffer size */
|
||||
(*jenv)->GetIntArrayRegion(jenv, outSz, 0, 1, (jint*)&tmpOut);
|
||||
|
||||
ret = wc_InitRng(&rng);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitRng failed, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
rngInit = 1;
|
||||
|
||||
ret = wc_InitRsaKey(&myKey, NULL);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitRsaKey failed, ret = %d\n", ret);
|
||||
wc_FreeRng(&rng);
|
||||
return ret;
|
||||
}
|
||||
keyInit = 1;
|
||||
|
||||
ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, (unsigned int)keySz);
|
||||
if (ret == 0) {
|
||||
|
||||
ret = wc_RsaPSS_Sign(inBuf, (unsigned int)inSz, outBuf, tmpOut,
|
||||
hashType, mgf, &myKey, &rng);
|
||||
if (ret > 0) {
|
||||
tmpOut = ret;
|
||||
(*jenv)->SetIntArrayRegion(jenv, outSz, 0, 1, (jint*)&tmpOut);
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
printf("wc_RsaPrivateKeyDecode failed, ret = %d\n", ret);
|
||||
}
|
||||
|
||||
if (keyInit) {
|
||||
wc_FreeRsaKey(&myKey);
|
||||
}
|
||||
if (rngInit) {
|
||||
wc_FreeRng(&rng);
|
||||
}
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)in;
|
||||
(void)inSz;
|
||||
(void)out;
|
||||
(void)outSz;
|
||||
(void)hash;
|
||||
(void)mgf;
|
||||
(void)keyDer;
|
||||
(void)keySz;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif /* WC_RSA_PSS */
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doPssVerify
|
||||
(JNIEnv* jenv, jobject jcl, jobject sig, jlong sigSz, jobject out, jlong outSz, jint hash, jint mgf, jobject keyDer, jlong keySz)
|
||||
{
|
||||
#ifdef WC_RSA_PSS
|
||||
int ret;
|
||||
RsaKey myKey;
|
||||
unsigned int idx = 0;
|
||||
unsigned char* sigBuf = NULL;
|
||||
unsigned char* outBuf = NULL;
|
||||
unsigned char* keyBuf = NULL;
|
||||
enum wc_HashType hashType;
|
||||
(void)jcl;
|
||||
|
||||
if ((sigSz < 0) || (keySz < 0) || (outSz < 0)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
sigBuf = (*jenv)->GetDirectBufferAddress(jenv, sig);
|
||||
if (sigBuf == NULL) {
|
||||
printf("problem getting sig buffer address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
outBuf = (*jenv)->GetDirectBufferAddress(jenv, out);
|
||||
if (outBuf == NULL) {
|
||||
printf("problem getting out buffer address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
keyBuf = (*jenv)->GetDirectBufferAddress(jenv, keyDer);
|
||||
if (keyBuf == NULL) {
|
||||
printf("problem getting key buffer address\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
hashType = wc_OidGetHash(hash);
|
||||
if (hashType == WC_HASH_TYPE_NONE) {
|
||||
printf("doPssVerify: unsupported hash OID %d\n", hash);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = wc_InitRsaKey(&myKey, NULL);
|
||||
if (ret != 0) {
|
||||
printf("wc_InitRsaKey failed, ret = %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Try private key decode first (sign check receives the server private),
|
||||
* fall back to public key decode (verify receives the peer public) */
|
||||
ret = wc_RsaPrivateKeyDecode(keyBuf, &idx, &myKey, (unsigned int)keySz);
|
||||
if (ret != 0) {
|
||||
idx = 0;
|
||||
ret = wc_RsaPublicKeyDecode(keyBuf, &idx, &myKey, (unsigned int)keySz);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
ret = wc_RsaPSS_Verify(sigBuf, (unsigned int)sigSz, outBuf,
|
||||
(unsigned int)outSz, hashType, mgf, &myKey);
|
||||
if (ret < 0) {
|
||||
printf("wc_RsaPSS_Verify failed, ret = %d\n", ret);
|
||||
}
|
||||
} else {
|
||||
printf("RSA key decode failed, ret = %d\n", ret);
|
||||
}
|
||||
|
||||
wc_FreeRsaKey(&myKey);
|
||||
|
||||
return ret;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)sig;
|
||||
(void)sigSz;
|
||||
(void)out;
|
||||
(void)outSz;
|
||||
(void)hash;
|
||||
(void)mgf;
|
||||
(void)keyDer;
|
||||
(void)keySz;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif /* WC_RSA_PSS */
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doDec
|
||||
(JNIEnv* jenv, jobject jcl, jobject in, jlong inSz, jobject out,
|
||||
jlong outSz, jobject keyDer, jlong keySz)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,22 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doEnc
|
|||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doDec
|
||||
(JNIEnv *, jobject, jobject, jlong, jobject, jlong, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfCryptRSA
|
||||
* Method: doPssSign
|
||||
* Signature: (Ljava/nio/ByteBuffer;JLjava/nio/ByteBuffer;[IIILjava/nio/ByteBuffer;J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doPssSign
|
||||
(JNIEnv *, jobject, jobject, jlong, jobject, jintArray, jint, jint, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfCryptRSA
|
||||
* Method: doPssVerify
|
||||
* Signature: (Ljava/nio/ByteBuffer;JLjava/nio/ByteBuffer;JIILjava/nio/ByteBuffer;J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfCryptRSA_doPssVerify
|
||||
(JNIEnv *, jobject, jobject, jlong, jobject, jlong, jint, jint, jobject, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -70,9 +70,19 @@ int NativeEccSharedSecretCb(WOLFSSL* ssl, ecc_key* otherKey,
|
|||
int NativeRsaSignCb(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz,
|
||||
unsigned char* out, unsigned int* outSz, const unsigned char* keyDer,
|
||||
unsigned int keySz, void* ctx);
|
||||
int NativeRsaPssSignCb(WOLFSSL* ssl,
|
||||
const unsigned char* in, unsigned int inSz, unsigned char* out,
|
||||
unsigned int* outSz, int hash, int mgf, const unsigned char* keyDer,
|
||||
unsigned int keySz, void* ctx);
|
||||
int NativeRsaVerifyCb(WOLFSSL* ssl, unsigned char* sig, unsigned int sigSz,
|
||||
unsigned char** out, const unsigned char* keyDer, unsigned int keySz,
|
||||
void* ctx);
|
||||
int NativeRsaSignCheckCb(WOLFSSL* ssl, unsigned char* sig, unsigned int sigSz,
|
||||
unsigned char** out, const unsigned char* keyDer, unsigned int keySz,
|
||||
void* ctx);
|
||||
int NativeRsaPssSignCheckCb(WOLFSSL* ssl, unsigned char* sig,
|
||||
unsigned int sigSz, unsigned char** out, int hash, int mgf,
|
||||
const unsigned char* keyDer, unsigned int keySz, void* ctx);
|
||||
int NativeRsaEncCb(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz,
|
||||
unsigned char* out, unsigned int* outSz, const unsigned char* keyDer,
|
||||
unsigned int keySz, void* ctx);
|
||||
|
|
@ -4152,6 +4162,324 @@ int NativeRsaSignCb(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz,
|
|||
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaPssSignCb
|
||||
(JNIEnv* jenv, jobject jcl, jlong ctxPtr)
|
||||
{
|
||||
WOLFSSL_CTX* ctx = (WOLFSSL_CTX*)(uintptr_t)ctxPtr;
|
||||
jclass excClass = NULL;
|
||||
(void)jcl;
|
||||
|
||||
/* find exception class */
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && defined(WC_RSA_PSS) && !defined(NO_RSA)
|
||||
if (ctx != NULL) {
|
||||
wolfSSL_CTX_SetRsaPssSignCb(ctx, NativeRsaPssSignCb);
|
||||
|
||||
} else {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Input WolfSSLContext object was null when setting RsaPssSignCb");
|
||||
}
|
||||
#else
|
||||
(void)ctx;
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"wolfSSL not compiled with PK Callback support and/or RSA-PSS support");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && defined(WC_RSA_PSS) && !defined(NO_RSA)
|
||||
|
||||
int NativeRsaPssSignCb(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz,
|
||||
unsigned char* out, unsigned int* outSz, int hash, int mgf,
|
||||
const unsigned char* keyDer, unsigned int keySz, void* ctx)
|
||||
{
|
||||
jint retval = 0;
|
||||
jint vmret = 0;
|
||||
|
||||
JNIEnv* jenv;
|
||||
jclass excClass;
|
||||
int needsDetach = 0;
|
||||
|
||||
static jobject* g_cachedSSLObj;
|
||||
jclass sessClass;
|
||||
jfieldID ctxFid;
|
||||
jmethodID getCtxMethodId;
|
||||
|
||||
jobject ctxRef;
|
||||
jclass innerCtxClass;
|
||||
jmethodID rsaPssSignMethodId;
|
||||
jintArray j_outSz;
|
||||
|
||||
jobject inBB = NULL;
|
||||
jobject outBB = NULL;
|
||||
jobject keyDerBB = NULL;
|
||||
jint tmpVal = 0;
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (!g_vm || !ssl || !in || !out || !outSz || !keyDer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get JavaEnv from JavaVM */
|
||||
vmret = (int)((*g_vm)->GetEnv(g_vm, (void**) &jenv, JNI_VERSION_1_6));
|
||||
if (vmret == JNI_EDETACHED) {
|
||||
#ifdef __ANDROID__
|
||||
vmret = (*g_vm)->AttachCurrentThread(g_vm, &jenv, NULL);
|
||||
#else
|
||||
vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL);
|
||||
#endif
|
||||
if (vmret) {
|
||||
return -1;
|
||||
}
|
||||
needsDetach = 1;
|
||||
} else if (vmret != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find exception class in case we need it */
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get stored WolfSSLSession jobject */
|
||||
g_cachedSSLObj = (jobject*) wolfSSL_get_jobject((WOLFSSL*)ssl);
|
||||
if (!g_cachedSSLObj) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLSession "
|
||||
"object reference in NativeRsaPssSignCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lookup WolfSSLSession class from object */
|
||||
sessClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
|
||||
if (!sessClass) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLSession "
|
||||
"class reference in NativeRsaPssSignCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lookup WolfSSLContext private member fieldID */
|
||||
ctxFid = (*jenv)->GetFieldID(jenv, sessClass, "ctx",
|
||||
"Lcom/wolfssl/WolfSSLContext;");
|
||||
if (!ctxFid) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Can't get native WolfSSLContext field ID in NativeRsaPssSignCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find getContextPtr() method */
|
||||
getCtxMethodId = (*jenv)->GetMethodID(jenv, sessClass,
|
||||
"getAssociatedContextPtr", "()Lcom/wolfssl/WolfSSLContext;");
|
||||
if (!getCtxMethodId) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get getAssociatedContextPtr() "
|
||||
"method ID in NativeRsaPssSignCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get WolfSSLContext ctx object from Java land */
|
||||
ctxRef = (*jenv)->CallObjectMethod(jenv, (jobject)(*g_cachedSSLObj),
|
||||
getCtxMethodId);
|
||||
CheckException(jenv);
|
||||
if (!ctxRef) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Can't get WolfSSLContext object in NativeRsaPssSignCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get WolfSSLContext class reference from Java land */
|
||||
innerCtxClass = (*jenv)->GetObjectClass(jenv, ctxRef);
|
||||
if (!innerCtxClass) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLContext "
|
||||
"class reference in NativeRsaPssSignCb");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* call internal RSA-PSS sign callback */
|
||||
rsaPssSignMethodId = (*jenv)->GetMethodID(jenv, innerCtxClass,
|
||||
"internalRsaPssSignCallback", "(Lcom/wolfssl/WolfSSLSession;"
|
||||
"Ljava/nio/ByteBuffer;J" "Ljava/nio/ByteBuffer;[III"
|
||||
"Ljava/nio/ByteBuffer;J)I");
|
||||
|
||||
if (!rsaPssSignMethodId) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Error getting internalRsaPssSignCallback method from JNI");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'in' */
|
||||
inBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)in, inSz);
|
||||
if (!inBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaPssSign in ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'out' */
|
||||
outBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)out, *outSz);
|
||||
if (!outBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaPssSign out ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'keyDer' */
|
||||
keyDerBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)keyDer, keySz);
|
||||
if (!keyDerBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaPssSign keyDer ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create jintArray to hold outSz, used as an output parameter from Java,
|
||||
* only needs to have 1 element */
|
||||
j_outSz = (*jenv)->NewIntArray(jenv, 1);
|
||||
if (!j_outSz) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create result intArray in RsaPssSignCb");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* copy outSz into j_outSz */
|
||||
(*jenv)->SetIntArrayRegion(jenv, j_outSz, 0, 1, (jint*)outSz);
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to set j_outSz intArray in RsaPssSignCb");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, j_outSz);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* call Java callback, java layer handles adding CTX ref */
|
||||
retval = (*jenv)->CallIntMethod(jenv, ctxRef, rsaPssSignMethodId,
|
||||
(jobject)(*g_cachedSSLObj), inBB, (jlong)inSz, outBB, j_outSz, hash,
|
||||
mgf, keyDerBB, (jlong)keySz);
|
||||
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, j_outSz);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (retval == 0) {
|
||||
/* copy j_outSz into outSz */
|
||||
(*jenv)->GetIntArrayRegion(jenv, j_outSz, 0, 1, &tmpVal);
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, j_outSz);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
*outSz = tmpVal;
|
||||
}
|
||||
|
||||
/* delete local refs */
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, inBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, j_outSz);
|
||||
|
||||
/* detach JNIEnv from thread */
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS && WC_RSA_PSS && !NO_RSA */
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaVerifyCb
|
||||
(JNIEnv* jenv, jobject jcl, jlong ctxPtr)
|
||||
{
|
||||
|
|
@ -4399,13 +4727,533 @@ int NativeRsaVerifyCb(WOLFSSL* ssl, unsigned char* sig, unsigned int sigSz,
|
|||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
|
||||
/* detach JNIEnv from thread */
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS */
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaSignCheckCb
|
||||
(JNIEnv* jenv, jobject jcl, jlong ctxPtr)
|
||||
{
|
||||
WOLFSSL_CTX* ctx = (WOLFSSL_CTX*)(uintptr_t)ctxPtr;
|
||||
jclass excClass = NULL;
|
||||
(void)jcl;
|
||||
|
||||
/* find exception class */
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_RSA)
|
||||
if (ctx != NULL) {
|
||||
/* set RSA sign check callback */
|
||||
wolfSSL_CTX_SetRsaSignCheckCb(ctx, NativeRsaSignCheckCb);
|
||||
} else {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Input WolfSSLContext object was null when setting RsaSignCheckCb");
|
||||
}
|
||||
#else
|
||||
(void)ctx;
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"wolfSSL not compiled with PK Callback and/or RSA support");
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaPssSignCheckCb
|
||||
(JNIEnv* jenv, jobject jcl, jlong ctxPtr)
|
||||
{
|
||||
WOLFSSL_CTX* ctx = (WOLFSSL_CTX*)(uintptr_t)ctxPtr;
|
||||
jclass excClass = NULL;
|
||||
(void)jcl;
|
||||
|
||||
/* find exception class */
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && defined(WC_RSA_PSS) && !defined(NO_RSA)
|
||||
if (ctx != NULL) {
|
||||
/* set RSA-PSS sign check callback */
|
||||
wolfSSL_CTX_SetRsaPssSignCheckCb(ctx, NativeRsaPssSignCheckCb);
|
||||
} else {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Input WolfSSLContext object was "
|
||||
"null when setting RsaPssSignCheckCb");
|
||||
}
|
||||
#else
|
||||
(void)ctx;
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"wolfSSL not compiled with PK Callback and/or RSA-PSS support");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && !defined(NO_RSA)
|
||||
|
||||
int NativeRsaSignCheckCb(WOLFSSL* ssl, unsigned char* sig, unsigned int sigSz,
|
||||
unsigned char** out, const unsigned char* keyDer, unsigned int keySz,
|
||||
void* ctx)
|
||||
{
|
||||
jint retval = 0;
|
||||
jint vmret = 0;
|
||||
|
||||
JNIEnv* jenv;
|
||||
jclass excClass;
|
||||
int needsDetach = 0;
|
||||
|
||||
static jobject* g_cachedSSLObj;
|
||||
jclass sessClass;
|
||||
jfieldID ctxFid;
|
||||
jmethodID getCtxMethodId;
|
||||
|
||||
jobject ctxRef;
|
||||
jclass innerCtxClass;
|
||||
jmethodID rsaSignCheckMethodId;
|
||||
|
||||
jobject sigBB = NULL;
|
||||
jobject outBB = NULL;
|
||||
jobject keyDerBB = NULL;
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (!g_vm || !ssl || !sig || !out || !keyDer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get JavaEnv from JavaVM */
|
||||
vmret = (int)((*g_vm)->GetEnv(g_vm, (void**) &jenv, JNI_VERSION_1_6));
|
||||
if (vmret == JNI_EDETACHED) {
|
||||
#ifdef __ANDROID__
|
||||
vmret = (*g_vm)->AttachCurrentThread(g_vm, &jenv, NULL);
|
||||
#else
|
||||
vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL);
|
||||
#endif
|
||||
if (vmret) {
|
||||
return -1;
|
||||
}
|
||||
needsDetach = 1;
|
||||
} else if (vmret != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find exception class in case we need it */
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get stored WolfSSLSession jobject */
|
||||
g_cachedSSLObj = (jobject*) wolfSSL_get_jobject((WOLFSSL*)ssl);
|
||||
if (!g_cachedSSLObj) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLSession "
|
||||
"object reference in NativeRsaSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lookup WolfSSLSession class from object */
|
||||
sessClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
|
||||
if (!sessClass) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLSession "
|
||||
"class reference in NativeRsaSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lookup WolfSSLContext private member fieldID */
|
||||
ctxFid = (*jenv)->GetFieldID(jenv, sessClass, "ctx",
|
||||
"Lcom/wolfssl/WolfSSLContext;");
|
||||
if (!ctxFid) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLContext "
|
||||
"field ID in NativeRsaSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find getContextPtr() method */
|
||||
getCtxMethodId = (*jenv)->GetMethodID(jenv, sessClass,
|
||||
"getAssociatedContextPtr", "()Lcom/wolfssl/WolfSSLContext;");
|
||||
if (!getCtxMethodId) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get getAssociatedContextPtr() "
|
||||
"method ID in NativeRsaSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get WolfSSLContext ctx object from Java land */
|
||||
ctxRef = (*jenv)->CallObjectMethod(jenv, (jobject)(*g_cachedSSLObj),
|
||||
getCtxMethodId);
|
||||
CheckException(jenv);
|
||||
if (!ctxRef) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Can't get WolfSSLContext object in NativeRsaSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get WolfSSLContext class reference */
|
||||
innerCtxClass = (*jenv)->GetObjectClass(jenv, ctxRef);
|
||||
if (!innerCtxClass) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLContext "
|
||||
"class reference in NativeRsaSignCheckCb");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* call internal RSA sign check callback */
|
||||
rsaSignCheckMethodId = (*jenv)->GetMethodID(jenv, innerCtxClass,
|
||||
"internalRsaSignCheckCallback", "(Lcom/wolfssl/WolfSSLSession;"
|
||||
"Ljava/nio/ByteBuffer;JLjava/nio/ByteBuffer;J"
|
||||
"Ljava/nio/ByteBuffer;J)I");
|
||||
|
||||
if (!rsaSignCheckMethodId) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Error getting internalRsaSignCheckCallback method from JNI");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'sig' */
|
||||
sigBB = (*jenv)->NewDirectByteBuffer(jenv, sig, sigSz);
|
||||
if (!sigBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaSignCheck sig ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'out', since doing this inline, outBB points
|
||||
* to the same address as sigBB */
|
||||
outBB = (*jenv)->NewDirectByteBuffer(jenv, sig, sigSz);
|
||||
if (!outBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaSignCheck out ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, sigBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'keyDer' */
|
||||
keyDerBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)keyDer, keySz);
|
||||
if (!keyDerBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaSignCheck keyDer ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, sigBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* call Java callback, java layer handles adding CTX ref */
|
||||
retval = (*jenv)->CallIntMethod(jenv, ctxRef, rsaSignCheckMethodId,
|
||||
(jobject)(*g_cachedSSLObj), sigBB, (jlong)sigSz, outBB, (jlong)sigSz,
|
||||
keyDerBB, (jlong)keySz);
|
||||
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
|
||||
/* point out* to the beginning of decrypted buffer */
|
||||
if (retval > 0) {
|
||||
*out = sig;
|
||||
}
|
||||
|
||||
/* delete local refs */
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, sigBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
|
||||
/* detach JNIEnv from thread */
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS && !NO_RSA */
|
||||
|
||||
#if defined(HAVE_PK_CALLBACKS) && defined(WC_RSA_PSS) && !defined(NO_RSA)
|
||||
|
||||
int NativeRsaPssSignCheckCb(WOLFSSL* ssl, unsigned char* sig,
|
||||
unsigned int sigSz, unsigned char** out, int hash, int mgf,
|
||||
const unsigned char* keyDer, unsigned int keySz, void* ctx)
|
||||
{
|
||||
jint retval = 0;
|
||||
jint vmret = 0;
|
||||
|
||||
JNIEnv* jenv;
|
||||
jclass excClass;
|
||||
int needsDetach = 0;
|
||||
|
||||
static jobject* g_cachedSSLObj;
|
||||
jclass sessClass;
|
||||
jfieldID ctxFid;
|
||||
jmethodID getCtxMethodId;
|
||||
|
||||
jobject ctxRef;
|
||||
jclass innerCtxClass;
|
||||
jmethodID rsaPssSignCheckMethodId;
|
||||
|
||||
jobject sigBB = NULL;
|
||||
jobject outBB = NULL;
|
||||
jobject keyDerBB = NULL;
|
||||
|
||||
(void)ctx;
|
||||
|
||||
if (!g_vm || !ssl || !sig || !out || !keyDer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get JavaEnv from JavaVM */
|
||||
vmret = (int)((*g_vm)->GetEnv(g_vm, (void**) &jenv, JNI_VERSION_1_6));
|
||||
if (vmret == JNI_EDETACHED) {
|
||||
#ifdef __ANDROID__
|
||||
vmret = (*g_vm)->AttachCurrentThread(g_vm, &jenv, NULL);
|
||||
#else
|
||||
vmret = (*g_vm)->AttachCurrentThread(g_vm, (void**) &jenv, NULL);
|
||||
#endif
|
||||
if (vmret) {
|
||||
return -1;
|
||||
}
|
||||
needsDetach = 1;
|
||||
} else if (vmret != JNI_OK) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find exception class in case we need it */
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get stored WolfSSLSession jobject */
|
||||
g_cachedSSLObj = (jobject*) wolfSSL_get_jobject((WOLFSSL*)ssl);
|
||||
if (!g_cachedSSLObj) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLSession "
|
||||
"object reference in NativeRsaPssSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lookup WolfSSLSession class from object */
|
||||
sessClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
|
||||
if (!sessClass) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLSession "
|
||||
"class reference in NativeRsaPssSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* lookup WolfSSLContext private member fieldID */
|
||||
ctxFid = (*jenv)->GetFieldID(jenv, sessClass, "ctx",
|
||||
"Lcom/wolfssl/WolfSSLContext;");
|
||||
if (!ctxFid) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLContext "
|
||||
"field ID in NativeRsaPssSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* find getContextPtr() method */
|
||||
getCtxMethodId = (*jenv)->GetMethodID(jenv, sessClass,
|
||||
"getAssociatedContextPtr", "()Lcom/wolfssl/WolfSSLContext;");
|
||||
if (!getCtxMethodId) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get getAssociatedContextPtr() "
|
||||
"method ID in NativeRsaPssSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get WolfSSLContext ctx object from Java land */
|
||||
ctxRef = (*jenv)->CallObjectMethod(jenv, (jobject)(*g_cachedSSLObj),
|
||||
getCtxMethodId);
|
||||
CheckException(jenv);
|
||||
if (!ctxRef) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Can't get WolfSSLContext object in NativeRsaPssSignCheckCb");
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get WolfSSLContext class reference */
|
||||
innerCtxClass = (*jenv)->GetObjectClass(jenv, ctxRef);
|
||||
if (!innerCtxClass) {
|
||||
(*jenv)->ThrowNew(jenv, excClass, "Can't get native WolfSSLContext "
|
||||
"class reference in NativeRsaPssSignCheckCb");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* call internal RSA-PSS sign check callback */
|
||||
rsaPssSignCheckMethodId = (*jenv)->GetMethodID(jenv,
|
||||
innerCtxClass, "internalRsaPssSignCheckCallback",
|
||||
"(Lcom/wolfssl/WolfSSLSession;Ljava/nio/ByteBuffer;J"
|
||||
"Ljava/nio/ByteBuffer;JIILjava/nio/ByteBuffer;J)I");
|
||||
|
||||
if (!rsaPssSignCheckMethodId) {
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Error getting internalRsaPssSignCheckCallback method from JNI");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'sig' */
|
||||
sigBB = (*jenv)->NewDirectByteBuffer(jenv, sig, sigSz);
|
||||
if (!sigBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaPssSignCheck sig ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'out', since doing inline, outBB points to
|
||||
* the same address as sigBB */
|
||||
outBB = (*jenv)->NewDirectByteBuffer(jenv, sig, sigSz);
|
||||
if (!outBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaPssSignCheck out ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, sigBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create ByteBuffer to wrap 'keyDer' */
|
||||
keyDerBB = (*jenv)->NewDirectByteBuffer(jenv, (void*)keyDer, keySz);
|
||||
if (!keyDerBB) {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Failed to create rsaPssSignCheck keyDer ByteBuffer");
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, sigBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* call Java callback, java layer handles adding CTX ref */
|
||||
retval = (*jenv)->CallIntMethod(jenv, ctxRef, rsaPssSignCheckMethodId,
|
||||
(jobject)(*g_cachedSSLObj), sigBB, (jlong)sigSz, outBB, (jlong)sigSz,
|
||||
hash, mgf, keyDerBB, (jlong)keySz);
|
||||
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
}
|
||||
|
||||
/* point out* to the beginning of decrypted buffer */
|
||||
if (retval > 0) {
|
||||
*out = sig;
|
||||
}
|
||||
|
||||
/* delete local refs */
|
||||
(*jenv)->DeleteLocalRef(jenv, ctxRef);
|
||||
(*jenv)->DeleteLocalRef(jenv, sigBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, outBB);
|
||||
(*jenv)->DeleteLocalRef(jenv, keyDerBB);
|
||||
|
||||
/* detach JNIEnv from thread */
|
||||
if (needsDetach) {
|
||||
(*g_vm)->DetachCurrentThread(g_vm);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* HAVE_PK_CALLBACKS && WC_RSA_PSS && !NO_RSA */
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaEncCb
|
||||
(JNIEnv* jenv, jobject jcl, jlong ctxPtr)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -327,6 +327,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setEccSharedSecretCb
|
|||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaSignCb
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLContext
|
||||
* Method: setRsaPssSignCb
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaPssSignCb
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLContext
|
||||
* Method: setRsaVerifyCb
|
||||
|
|
@ -335,6 +343,22 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaSignCb
|
|||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaVerifyCb
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLContext
|
||||
* Method: setRsaSignCheckCb
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaSignCheckCb
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLContext
|
||||
* Method: setRsaPssSignCheckCb
|
||||
* Signature: (J)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLContext_setRsaPssSignCheckCb
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLContext
|
||||
* Method: setRsaEncCb
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ infer --fail-on-issue run -- javac \
|
|||
src/java/com/wolfssl/WolfSSLPskServerCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLRsaDecCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLRsaEncCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLRsaPssSignCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLRsaPssVerifyCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLRsaSignCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLRsaVerifyCallback.java \
|
||||
src/java/com/wolfssl/WolfSSLSession.java \
|
||||
|
|
|
|||
|
|
@ -102,5 +102,42 @@ public class WolfCryptRSA {
|
|||
*/
|
||||
public native int doDec(ByteBuffer in, long inSz, ByteBuffer out,
|
||||
long outSz, ByteBuffer keyDer, long keySz);
|
||||
|
||||
/**
|
||||
* RSA-PSS sign, wraps native wolfCrypt operation.
|
||||
*
|
||||
* @param in input buffer to be signed
|
||||
* @param inSz size of input buffer, bytes
|
||||
* @param out output for generated signature
|
||||
* @param outSz [IN/OUT] size of output buffer on input, size of
|
||||
* generated signature on output
|
||||
* @param hash hash algorithm type
|
||||
* @param mgf mask generation function identifier
|
||||
* @param key DER formatted RSA key to be used for signing
|
||||
* @param keySz size of key, bytes
|
||||
*
|
||||
* @return 0 on success, negative on error.
|
||||
*/
|
||||
public native int doPssSign(ByteBuffer in, long inSz,
|
||||
ByteBuffer out, int[] outSz, int hash, int mgf,
|
||||
ByteBuffer key, long keySz);
|
||||
|
||||
/**
|
||||
* RSA-PSS verify, wraps native wolfCrypt operation.
|
||||
*
|
||||
* @param sig input signature to verify
|
||||
* @param sigSz size of input signature, bytes
|
||||
* @param out output buffer to place verified data
|
||||
* @param outSz size of output buffer, bytes
|
||||
* @param hash hash algorithm type
|
||||
* @param mgf mask generation function identifier
|
||||
* @param keyDer public key used for verify, DER formatted
|
||||
* @param keySz size of public key, bytes
|
||||
*
|
||||
* @return size of returned data on success, negative on error.
|
||||
*/
|
||||
public native int doPssVerify(ByteBuffer sig, long sigSz,
|
||||
ByteBuffer out, long outSz, int hash, int mgf,
|
||||
ByteBuffer keyDer, long keySz);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,11 @@ public class WolfSSLContext {
|
|||
/* user-registered RSA sign/verify callbacks */
|
||||
private WolfSSLRsaSignCallback internRsaSignCb = null;
|
||||
private WolfSSLRsaVerifyCallback internRsaVerifyCb = null;
|
||||
private WolfSSLRsaVerifyCallback internRsaSignCheckCb = null;
|
||||
|
||||
/* user-registered RSA-PSS sign/verify callbacks */
|
||||
private WolfSSLRsaPssSignCallback internRsaPssSignCb = null;
|
||||
private WolfSSLRsaPssVerifyCallback internRsaPssSignCheckCb = null;
|
||||
|
||||
/* user-registered RSA enc/dec callbacks */
|
||||
private WolfSSLRsaEncCallback internRsaEncCb = null;
|
||||
|
|
@ -280,14 +285,53 @@ public class WolfSSLContext {
|
|||
}
|
||||
|
||||
private int internalRsaVerifyCallback(WolfSSLSession ssl, ByteBuffer sig,
|
||||
long sigSz, ByteBuffer out, long outSz, ByteBuffer keyDer,
|
||||
long keySz)
|
||||
long sigSz, ByteBuffer out, long outSz, ByteBuffer keyDer,
|
||||
long keySz)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* call user-registered rsa verify method */
|
||||
ret = internRsaVerifyCb.rsaVerifyCallback(ssl, sig, sigSz, out,
|
||||
outSz, keyDer, keySz, ssl.getRsaVerifyCtx());
|
||||
ret = internRsaVerifyCb.rsaVerifyCallback(ssl, sig, sigSz, out, outSz,
|
||||
keyDer, keySz, ssl.getRsaVerifyCtx());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int internalRsaSignCheckCallback(WolfSSLSession ssl, ByteBuffer sig,
|
||||
long sigSz, ByteBuffer out, long outSz, ByteBuffer keyDer,
|
||||
long keySz)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* call user-registered rsa sign check method */
|
||||
ret = internRsaSignCheckCb.rsaVerifyCallback(ssl, sig, sigSz, out,
|
||||
outSz, keyDer, keySz, ssl.getRsaVerifyCtx());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int internalRsaPssSignCallback(WolfSSLSession ssl, ByteBuffer in,
|
||||
long inSz, ByteBuffer out, int[] outSz, int hash, int mgf,
|
||||
ByteBuffer keyDer, long keySz)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* call user-registered rsa pss sign method */
|
||||
ret = internRsaPssSignCb.rsaPssSignCallback(ssl, in, inSz, out, outSz,
|
||||
hash, mgf, keyDer, keySz, ssl.getRsaSignCtx());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
private int internalRsaPssSignCheckCallback(WolfSSLSession ssl,
|
||||
ByteBuffer sig, long sigSz, ByteBuffer out, long outSz, int hash,
|
||||
int mgf, ByteBuffer keyDer, long keySz)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* call user-registered rsa pss verify method */
|
||||
ret = internRsaPssSignCheckCb.rsaPssVerifyCallback(ssl, sig, sigSz,
|
||||
out, outSz, hash, mgf, keyDer, keySz, ssl.getRsaVerifyCtx());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -406,7 +450,10 @@ public class WolfSSLContext {
|
|||
private native void setEccVerifyCb(long ctx);
|
||||
private native void setEccSharedSecretCb(long ctx);
|
||||
private native void setRsaSignCb(long ctx);
|
||||
private native void setRsaPssSignCb(long ctx);
|
||||
private native void setRsaVerifyCb(long ctx);
|
||||
private native void setRsaSignCheckCb(long ctx);
|
||||
private native void setRsaPssSignCheckCb(long ctx);
|
||||
private native void setRsaEncCb(long ctx);
|
||||
private native void setRsaDecCb(long ctx);
|
||||
private native void setPskClientCb(long ctx);
|
||||
|
|
@ -1933,23 +1980,128 @@ public class WolfSSLContext {
|
|||
}
|
||||
|
||||
/**
|
||||
* Allows caller to set the Public Key Callback for RSA Public Encrypt.
|
||||
* The callback should return 0 for success or negative value for an
|
||||
* error. The <b>ssl</b> and <b>ctx</b> objects are available for
|
||||
* the users convenience. <b>in</b> is the input buffer to encrypt while
|
||||
* <b>inSz</b> denotes the length of the input. <b>out</b> is the output
|
||||
* buffer where the result of the encryption should be stored. <b>outSz</b>
|
||||
* is an input/output variable that specifies the size of the output
|
||||
* buffer upon invocation and the actual size of the encryption should be
|
||||
* stored there before returning. <b>keyDer</b> is the RSA Public key in
|
||||
* ASN1 format and <b>keySz</b> is the length of the key in bytes. An
|
||||
* example callback can be found in examples/MyRsaEncCallback.java.
|
||||
* Allows caller to set the Public Key Callback for RSA Sign Check (verify
|
||||
* a signature that was just created). Uses the same callback signature as
|
||||
* RSA Verify. The callback should return the number of plaintext bytes
|
||||
* for success or a negative value for an error.
|
||||
*
|
||||
* @param callback object to be registered as the RSA public encrypt
|
||||
* callback for the WolfSSL context. The signature of
|
||||
* this object and corresponding method must match that
|
||||
* as shown in WolfSSLRsaEncCallback.java, inside
|
||||
* rsaEncCallback().
|
||||
* @param callback object to be registered as the RSA sign check callback
|
||||
* for the WolfSSL context. The signature of this object
|
||||
* and corresponding method must match that as shown in
|
||||
* WolfSSLRsaVerifyCallback.java, inside
|
||||
* rsaVerifyCallback().
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws WolfSSLJNIException Internal JNI error
|
||||
* @see WolfSSLSession#setRsaVerifyCtx(Object)
|
||||
*/
|
||||
public synchronized void setRsaSignCheckCb(
|
||||
WolfSSLRsaVerifyCallback callback) throws IllegalStateException,
|
||||
WolfSSLJNIException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (ctxLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, getContextPtr(),
|
||||
() -> "entered setRsaSignCheckCb(" + callback + ")");
|
||||
|
||||
/* set rsa sign check callback */
|
||||
internRsaSignCheckCb = callback;
|
||||
|
||||
/* register internal callback with native lib */
|
||||
setRsaSignCheckCb(getContextPtr());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows caller to set the Public Key Callback for RSA-PSS Signing. The
|
||||
* callback should return 0 for success or a negative value for an error.
|
||||
* <b>in</b> is the input buffer to sign and <b>inSz</b> denotes the length
|
||||
* of the input. <b>out</b> is the output buffer where the result of the
|
||||
* signature should be stored. <b>outSz</b> is an input/output variable that
|
||||
* specifies the size of the output buffer upon invocation. <b>hash</b> and
|
||||
* <b>mgf</b> specify the hash algorithm and mask generation function.
|
||||
* <b>keyDer</b> is the RSA Private key in ASN1 format and <b>keySz</b> is
|
||||
* the length of the key in bytes.
|
||||
*
|
||||
* @param callback object to be registered as the RSA-PSS sign callback for
|
||||
* the WolfSSL context. The signature of this object and
|
||||
* corresponding method must match that as shown in
|
||||
* WolfSSLRsaPssSignCallback.java.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws WolfSSLJNIException Internal JNI error
|
||||
* @see WolfSSLSession#setRsaSignCtx(Object)
|
||||
*/
|
||||
public synchronized void setRsaPssSignCb(WolfSSLRsaPssSignCallback callback)
|
||||
throws IllegalStateException, WolfSSLJNIException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (ctxLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, getContextPtr(),
|
||||
() -> "entered setRsaPssSignCb(" + callback + ")");
|
||||
|
||||
/* set rsa pss sign callback */
|
||||
internRsaPssSignCb = callback;
|
||||
|
||||
/* register internal callback with native lib */
|
||||
setRsaPssSignCb(getContextPtr());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows caller to set the Public Key Callback for RSA-PSS Sign Check
|
||||
* (verify a PSS signature that was just created). The callback should
|
||||
* return the number of plaintext bytes for success or a negative value
|
||||
* for an error. <b>hash</b> and <b>mgf</b> specify the hash algorithm and
|
||||
* mask generation function.
|
||||
*
|
||||
* @param callback object to be registered as the RSA-PSS sign check
|
||||
* callback for the WolfSSL context. The signature of
|
||||
* this object and corresponding method must match that as
|
||||
* shown in WolfSSLRsaPssVerifyCallback.java.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws WolfSSLJNIException Internal JNI error
|
||||
* @see WolfSSLSession#setRsaVerifyCtx(Object)
|
||||
*/
|
||||
public synchronized void setRsaPssSignCheckCb(
|
||||
WolfSSLRsaPssVerifyCallback callback) throws IllegalStateException,
|
||||
WolfSSLJNIException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (ctxLock) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||
WolfSSLDebug.INFO, getContextPtr(),
|
||||
() -> "entered setRsaPssSignCheckCb(" + callback + ")");
|
||||
|
||||
/* set rsa pss sign check callback */
|
||||
internRsaPssSignCheckCb = callback;
|
||||
|
||||
/* register internal callback with native lib */
|
||||
setRsaPssSignCheckCb(getContextPtr());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows caller to set the Public Key Callback for RSA Public Encrypt.
|
||||
* The callback should return 0 for success or negative value for an error.
|
||||
* The <b>ssl</b> and <b>ctx</b> objects are available for the users
|
||||
* convenience. <b>in</b> is the input buffer to encrypt while <b>inSz</b>
|
||||
* denotes the length of the input. <b>out</b> is the output buffer where
|
||||
* the result of the encryption should be stored. <b>outSz</b> is an
|
||||
* input/output variable that specifies the size of the output buffer upon
|
||||
* invocation and the actual size of the encryption should be stored there
|
||||
* before returning. <b>keyDer</b> is the RSA Public key in ASN1 format
|
||||
* and <b>keySz</b> is the length of the key in bytes. An example callback
|
||||
* can be found in examples/MyRsaEncCallback.java.
|
||||
*
|
||||
* @param callback object to be registered as the RSA public encrypt
|
||||
* callback for the WolfSSL context. The signature of
|
||||
* this object and corresponding method must match that as
|
||||
* shown in WolfSSLRsaEncCallback.java, inside
|
||||
* rsaEncCallback().
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws WolfSSLJNIException Internal JNI exception
|
||||
* @see WolfSSLSession#setRsaEncCtx(Object)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/* WolfSSLRsaPssSignCallback.java
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
package com.wolfssl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* wolfSSL RSA-PSS Signing Callback Interface.
|
||||
* This interface specifies how applications should implement the RSA-PSS
|
||||
* signing callback class to be used by wolfSSL.
|
||||
* <p>
|
||||
* After implementing this interface, it should be passed as a parameter to the
|
||||
* {@link WolfSSLContext#setRsaPssSignCb(WolfSSLRsaPssSignCallback)
|
||||
* WolfSSLContext.setRsaPssSignCb()} method to be registered with the native
|
||||
* wolfSSL library.
|
||||
*
|
||||
* @author wolfSSL
|
||||
*/
|
||||
public interface WolfSSLRsaPssSignCallback {
|
||||
|
||||
/**
|
||||
* RSA-PSS signing callback method.
|
||||
* This method acts as RSA-PSS signing callback.
|
||||
*
|
||||
* @param ssl the current SSL session object from which the callback was
|
||||
* initiated.
|
||||
* @param in input buffer to sign
|
||||
* @param inSz length of the input, <b>in</b>
|
||||
* @param out output buffer where the result of the signature should be
|
||||
* stored.
|
||||
* @param outSz input/output variable that specifies the size of the output
|
||||
* buffer upon invocation. The actual size of the signature
|
||||
* should be stored there before returning. Use the first
|
||||
* element of the array for storage.
|
||||
* @param hash hash algorithm type
|
||||
* @param mgf mask generation function
|
||||
* @param keyDer RSA Private key in ASN1 format
|
||||
* @param keySz length of the key, <b>keyDer</b>, in bytes
|
||||
* @param ctx custom user-registered RSA-PSS signing context
|
||||
* @return <b><code>0</code></b> upon success, otherwise a negative
|
||||
* value on error.
|
||||
*/
|
||||
public int rsaPssSignCallback(WolfSSLSession ssl, ByteBuffer in, long inSz,
|
||||
ByteBuffer out, int[] outSz, int hash, int mgf, ByteBuffer keyDer,
|
||||
long keySz, Object ctx);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* WolfSSLRsaPssVerifyCallback.java
|
||||
*
|
||||
* Copyright (C) 2006-2026 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfSSL.
|
||||
*
|
||||
* wolfSSL is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfSSL is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
package com.wolfssl;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* wolfSSL RSA-PSS Verification Callback Interface.
|
||||
* This interface specifies how applications should implement the RSA-PSS
|
||||
* verification callback class to be used by wolfSSL.
|
||||
* <p>
|
||||
* After implementing this interface, it should be passed as a parameter to the
|
||||
* {@link WolfSSLContext#setRsaPssSignCheckCb(WolfSSLRsaPssVerifyCallback)
|
||||
* WolfSSLContext.setRsaPssSignCheckCb()} method to be registered with the
|
||||
* native wolfSSL library.
|
||||
*
|
||||
* @author wolfSSL
|
||||
*/
|
||||
public interface WolfSSLRsaPssVerifyCallback {
|
||||
|
||||
/**
|
||||
* RSA-PSS verification callback method.
|
||||
* This method acts as RSA-PSS verification callback.
|
||||
*
|
||||
* @param ssl the current SSL session object from which the callback
|
||||
* was initiated.
|
||||
* @param sig the signature to verify
|
||||
* @param sigSz length of the signature, <b>sig</b>
|
||||
* @param out the verification/output buffer after the decryption
|
||||
* process and padding.
|
||||
* @param outSz size of the output buffer, <b>out</b>
|
||||
* @param hash hash algorithm type
|
||||
* @param mgf mask generation function
|
||||
* @param keyDer the RSA Public key in ASN1 format
|
||||
* @param keySz the length of the key, <b>keyDer</b>, in bytes
|
||||
* @param ctx custom user-registered RSA-PSS verify context
|
||||
* @return the number of plaintext bytes on success, otherwise a
|
||||
* negative value on error.
|
||||
*/
|
||||
public int rsaPssVerifyCallback(WolfSSLSession ssl, ByteBuffer sig,
|
||||
long sigSz, ByteBuffer out, long outSz, int hash, int mgf,
|
||||
ByteBuffer keyDer, long keySz, Object ctx);
|
||||
}
|
||||
|
||||
|
|
@ -25,6 +25,18 @@ import org.junit.Test;
|
|||
import org.junit.BeforeClass;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.ServerSocket;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.wolfssl.WolfSSL;
|
||||
import com.wolfssl.WolfSSLContext;
|
||||
import com.wolfssl.WolfSSLException;
|
||||
|
|
@ -32,6 +44,11 @@ import com.wolfssl.WolfSSLJNIException;
|
|||
import com.wolfssl.WolfSSLPskClientCallback;
|
||||
import com.wolfssl.WolfSSLPskServerCallback;
|
||||
import com.wolfssl.WolfSSLSession;
|
||||
import com.wolfssl.WolfSSLRsaSignCallback;
|
||||
import com.wolfssl.WolfSSLRsaVerifyCallback;
|
||||
import com.wolfssl.WolfSSLRsaPssSignCallback;
|
||||
import com.wolfssl.WolfSSLRsaPssVerifyCallback;
|
||||
import com.wolfssl.WolfCryptRSA;
|
||||
|
||||
public class WolfSSLContextTest {
|
||||
|
||||
|
|
@ -40,6 +57,8 @@ public class WolfSSLContextTest {
|
|||
|
||||
public static String cliCert = "examples/certs/client-cert.pem";
|
||||
public static String cliKey = "examples/certs/client-key.pem";
|
||||
public static String svrCert = "examples/certs/server-cert.pem";
|
||||
public static String svrKey = "examples/certs/server-key.pem";
|
||||
public static String svrCertEcc = "examples/certs/server-ecc.pem";
|
||||
public static String caCert = "examples/certs/ca-cert.pem";
|
||||
public static String dhParams = "examples/certs/dh2048.pem";
|
||||
|
|
@ -63,6 +82,8 @@ public class WolfSSLContextTest {
|
|||
|
||||
cliCert = WolfSSLTestCommon.getPath(cliCert);
|
||||
cliKey = WolfSSLTestCommon.getPath(cliKey);
|
||||
svrCert = WolfSSLTestCommon.getPath(svrCert);
|
||||
svrKey = WolfSSLTestCommon.getPath(svrKey);
|
||||
svrCertEcc = WolfSSLTestCommon.getPath(svrCertEcc);
|
||||
caCert = WolfSSLTestCommon.getPath(caCert);
|
||||
dhParams = WolfSSLTestCommon.getPath(dhParams);
|
||||
|
|
@ -80,6 +101,7 @@ public class WolfSSLContextTest {
|
|||
test_WolfSSLContext_set1SigAlgsList();
|
||||
test_WolfSSLContext_setMinRSAKeySize();
|
||||
test_WolfSSLContext_setMinECCKeySize();
|
||||
test_WolfSSLContext_rsaCbHandshake();
|
||||
test_WolfSSLContext_free();
|
||||
}
|
||||
|
||||
|
|
@ -735,6 +757,442 @@ public class WolfSSLContextTest {
|
|||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
/* Context object shared between RSA sign/verify callbacks, tracks whether
|
||||
* callback was invoked during handshake */
|
||||
class TestRsaCbCtx
|
||||
{
|
||||
public boolean called = false;
|
||||
}
|
||||
|
||||
class TestRsaSignCb implements WolfSSLRsaSignCallback
|
||||
{
|
||||
public int rsaSignCallback(WolfSSLSession ssl, ByteBuffer in, long inSz,
|
||||
ByteBuffer out, int[] outSz, ByteBuffer keyDer, long keySz,
|
||||
Object ctx) {
|
||||
|
||||
TestRsaCbCtx myCtx = (TestRsaCbCtx)ctx;
|
||||
myCtx.called = true;
|
||||
|
||||
WolfCryptRSA rsa = new WolfCryptRSA();
|
||||
return rsa.doSign(in, inSz, out, outSz, keyDer, keySz);
|
||||
}
|
||||
}
|
||||
|
||||
class TestRsaVerifyCb implements WolfSSLRsaVerifyCallback
|
||||
{
|
||||
public int rsaVerifyCallback(WolfSSLSession ssl, ByteBuffer sig,
|
||||
long sigSz, ByteBuffer out, long outSz, ByteBuffer keyDer,
|
||||
long keySz, Object ctx) {
|
||||
|
||||
TestRsaCbCtx myCtx = (TestRsaCbCtx)ctx;
|
||||
myCtx.called = true;
|
||||
|
||||
WolfCryptRSA rsa = new WolfCryptRSA();
|
||||
return rsa.doVerify(sig, sigSz, out, outSz, keyDer, keySz);
|
||||
}
|
||||
}
|
||||
|
||||
class TestRsaPssSignCb implements WolfSSLRsaPssSignCallback
|
||||
{
|
||||
public int rsaPssSignCallback(WolfSSLSession ssl, ByteBuffer in,
|
||||
long inSz, ByteBuffer out, int[] outSz, int hash, int mgf,
|
||||
ByteBuffer keyDer, long keySz, Object ctx) {
|
||||
|
||||
TestRsaCbCtx myCtx = (TestRsaCbCtx)ctx;
|
||||
myCtx.called = true;
|
||||
|
||||
WolfCryptRSA rsa = new WolfCryptRSA();
|
||||
return rsa.doPssSign(in, inSz, out, outSz, hash, mgf, keyDer,
|
||||
keySz);
|
||||
}
|
||||
}
|
||||
|
||||
class TestRsaPssVerifyCb implements WolfSSLRsaPssVerifyCallback
|
||||
{
|
||||
public int rsaPssVerifyCallback(WolfSSLSession ssl, ByteBuffer sig,
|
||||
long sigSz, ByteBuffer out, long outSz, int hash, int mgf,
|
||||
ByteBuffer keyDer, long keySz, Object ctx) {
|
||||
|
||||
TestRsaCbCtx myCtx = (TestRsaCbCtx)ctx;
|
||||
myCtx.called = true;
|
||||
|
||||
WolfCryptRSA rsa = new WolfCryptRSA();
|
||||
return rsa.doPssVerify(sig, sigSz, out, outSz, hash, mgf, keyDer,
|
||||
keySz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to create and configure a WolfSSLContext with cert, key, and CA
|
||||
* for handshake tests.
|
||||
*/
|
||||
private WolfSSLContext createCtx(String certPath, String keyPath,
|
||||
String caPath, long method) throws Exception {
|
||||
|
||||
int ret;
|
||||
WolfSSLContext c = new WolfSSLContext(method);
|
||||
|
||||
ret = c.useCertificateChainFile(certPath);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
c.free();
|
||||
throw new Exception("Failed to load cert: " + certPath);
|
||||
}
|
||||
|
||||
ret = c.usePrivateKeyFile(keyPath, WolfSSL.SSL_FILETYPE_PEM);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
c.free();
|
||||
throw new Exception("Failed to load key: " + keyPath);
|
||||
}
|
||||
|
||||
ret = c.loadVerifyLocations(caPath, null);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
c.free();
|
||||
throw new Exception("Failed to load CA: " + caPath);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public void test_WolfSSLContext_rsaCbHandshake() {
|
||||
|
||||
System.out.print("\trsaCbHandshake()");
|
||||
|
||||
if (!WolfSSL.RsaEnabled() || !WolfSSL.FileSystemEnabled()) {
|
||||
System.out.println("\t\t... skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
/* TLS 1.2 handshake with RSA PK callbacks */
|
||||
rsaCbHandshakeTls12();
|
||||
|
||||
/* TLS 1.3 handshake with RSA-PSS PK callbacks */
|
||||
if (WolfSSL.TLSv13Enabled() && WolfSSL.RsaPssEnabled()) {
|
||||
rsaCbHandshakeTls13();
|
||||
}
|
||||
|
||||
System.out.println("\t\t... passed");
|
||||
}
|
||||
|
||||
private void rsaCbHandshakeTls12() {
|
||||
|
||||
WolfSSLContext srvCtx = null;
|
||||
WolfSSLContext cliCtx = null;
|
||||
ServerSocket srvSocket = null;
|
||||
ExecutorService es = null;
|
||||
Socket cliSock = null;
|
||||
WolfSSLSession cliSes = null;
|
||||
|
||||
try {
|
||||
srvCtx = createCtx(svrCert, svrKey, caCert,
|
||||
WolfSSL.TLSv1_2_ServerMethod());
|
||||
cliCtx = createCtx(cliCert, cliKey, caCert,
|
||||
WolfSSL.TLSv1_2_ClientMethod());
|
||||
|
||||
/* Register server-side RSA sign + sign check */
|
||||
TestRsaSignCb signCb = new TestRsaSignCb();
|
||||
TestRsaVerifyCb signCheckCb = new TestRsaVerifyCb();
|
||||
srvCtx.setRsaSignCb(signCb);
|
||||
srvCtx.setRsaSignCheckCb(signCheckCb);
|
||||
|
||||
/* Register client-side RSA verify */
|
||||
TestRsaVerifyCb verifyCb = new TestRsaVerifyCb();
|
||||
cliCtx.setRsaVerifyCb(verifyCb);
|
||||
|
||||
/* Register RSA-PSS callbacks in case rsa_pss_sa_algo is used
|
||||
* as sig algo in TLS 1.2 */
|
||||
if (WolfSSL.RsaPssEnabled()) {
|
||||
TestRsaPssSignCb pssSignCb = new TestRsaPssSignCb();
|
||||
TestRsaPssVerifyCb pssSrvChk = new TestRsaPssVerifyCb();
|
||||
TestRsaPssVerifyCb pssCliChk = new TestRsaPssVerifyCb();
|
||||
srvCtx.setRsaPssSignCb(pssSignCb);
|
||||
srvCtx.setRsaPssSignCheckCb(pssSrvChk);
|
||||
cliCtx.setRsaPssSignCheckCb(pssCliChk);
|
||||
}
|
||||
|
||||
/* Context objects to track invocation */
|
||||
final TestRsaCbCtx srvSignCtx = new TestRsaCbCtx();
|
||||
final TestRsaCbCtx srvVerifyCtx = new TestRsaCbCtx();
|
||||
final TestRsaCbCtx cliVerifyCtx = new TestRsaCbCtx();
|
||||
|
||||
srvSocket = new ServerSocket(0);
|
||||
srvSocket.setSoTimeout(10000);
|
||||
final int port = srvSocket.getLocalPort();
|
||||
final ServerSocket fSrvSock = srvSocket;
|
||||
final WolfSSLContext fSrvCtx = srvCtx;
|
||||
|
||||
final CountDownLatch ready = new CountDownLatch(1);
|
||||
|
||||
es = Executors.newSingleThreadExecutor();
|
||||
Future<Void> srvFuture = es.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
int ret;
|
||||
int err;
|
||||
Socket srv = null;
|
||||
WolfSSLSession srvSes = null;
|
||||
try {
|
||||
ready.countDown();
|
||||
srv = fSrvSock.accept();
|
||||
srvSes = new WolfSSLSession(fSrvCtx);
|
||||
srvSes.setRsaSignCtx(srvSignCtx);
|
||||
srvSes.setRsaVerifyCtx(srvVerifyCtx);
|
||||
ret = srvSes.setFd(srv);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new Exception("srv setFd fail: " + ret);
|
||||
}
|
||||
do {
|
||||
ret = srvSes.accept();
|
||||
err = srvSes.getError(ret);
|
||||
} while (
|
||||
ret != WolfSSL.SSL_SUCCESS &&
|
||||
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new Exception("srv accept fail: " + ret);
|
||||
}
|
||||
srvSes.shutdownSSL();
|
||||
|
||||
} finally {
|
||||
if (srvSes != null) {
|
||||
srvSes.freeSSL();
|
||||
}
|
||||
if (srv != null) {
|
||||
srv.close();
|
||||
}
|
||||
fSrvSock.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (!ready.await(2, TimeUnit.SECONDS)) {
|
||||
fail("Server did not become ready within timeout");
|
||||
}
|
||||
|
||||
cliSock = new Socket("localhost", port);
|
||||
cliSes = new WolfSSLSession(cliCtx);
|
||||
cliSes.setRsaVerifyCtx(cliVerifyCtx);
|
||||
|
||||
int ret = cliSes.setFd(cliSock);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
fail("cli setFd fail: " + ret);
|
||||
}
|
||||
|
||||
int err;
|
||||
do {
|
||||
ret = cliSes.connect();
|
||||
err = cliSes.getError(ret);
|
||||
} while (ret != WolfSSL.SSL_SUCCESS &&
|
||||
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
fail("TLS 1.2 RSA CB connect fail: " + ret);
|
||||
}
|
||||
|
||||
cliSes.shutdownSSL();
|
||||
cliSes.freeSSL();
|
||||
cliSock.close();
|
||||
|
||||
/* Check server thread for errors */
|
||||
es.shutdown();
|
||||
srvFuture.get(5, TimeUnit.SECONDS);
|
||||
|
||||
/* Verify callbacks were invoked */
|
||||
assertTrue("RSA sign cb not called", srvSignCtx.called);
|
||||
assertTrue("RSA sign check cb not called", srvVerifyCtx.called);
|
||||
if (!WolfSSL.RsaPssEnabled()) {
|
||||
assertTrue("RSA verify (cli) cb not called",
|
||||
cliVerifyCtx.called);
|
||||
}
|
||||
|
||||
} catch (WolfSSLJNIException e) {
|
||||
/* PK callbacks may not be compiled in */
|
||||
if (e.getMessage() != null &&
|
||||
e.getMessage().contains("PK Callback")) {
|
||||
return;
|
||||
}
|
||||
System.out.println("\t\t... failed");
|
||||
fail("TLS 1.2 RSA CB handshake: " + e.getMessage());
|
||||
|
||||
} catch (ExecutionException e) {
|
||||
System.out.println("\t\t... failed");
|
||||
fail("TLS 1.2 RSA CB server: " + e.getCause().getMessage());
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("\t\t... failed");
|
||||
fail("TLS 1.2 RSA CB handshake: " + e.getMessage());
|
||||
|
||||
} finally {
|
||||
if (cliSes != null) {
|
||||
try { cliSes.freeSSL(); }
|
||||
catch (Exception e) { /* ignore */ }
|
||||
}
|
||||
if (cliSock != null) {
|
||||
try { cliSock.close(); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
if (srvSocket != null && !srvSocket.isClosed()) {
|
||||
try { srvSocket.close(); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
if (cliCtx != null) cliCtx.free();
|
||||
if (srvCtx != null) srvCtx.free();
|
||||
if (es != null) {
|
||||
es.shutdownNow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void rsaCbHandshakeTls13() {
|
||||
|
||||
WolfSSLContext srvCtx = null;
|
||||
WolfSSLContext cliCtx = null;
|
||||
ServerSocket srvSocket = null;
|
||||
ExecutorService es = null;
|
||||
Socket cliSock = null;
|
||||
WolfSSLSession cliSes = null;
|
||||
|
||||
try {
|
||||
srvCtx = createCtx(svrCert, svrKey, caCert,
|
||||
WolfSSL.TLSv1_3_ServerMethod());
|
||||
cliCtx = createCtx(cliCert, cliKey, caCert,
|
||||
WolfSSL.TLSv1_3_ClientMethod());
|
||||
|
||||
/* Server: RSA-PSS sign + sign check */
|
||||
TestRsaPssSignCb pssSignCb = new TestRsaPssSignCb();
|
||||
TestRsaPssVerifyCb pssSrvChkCb = new TestRsaPssVerifyCb();
|
||||
srvCtx.setRsaPssSignCb(pssSignCb);
|
||||
srvCtx.setRsaPssSignCheckCb(pssSrvChkCb);
|
||||
|
||||
/* Context objects to track invocation */
|
||||
final TestRsaCbCtx srvSignCtx = new TestRsaCbCtx();
|
||||
final TestRsaCbCtx srvVerifyCtx = new TestRsaCbCtx();
|
||||
|
||||
srvSocket = new ServerSocket(0);
|
||||
srvSocket.setSoTimeout(10000);
|
||||
final int port = srvSocket.getLocalPort();
|
||||
final ServerSocket fSrvSock = srvSocket;
|
||||
final WolfSSLContext fSrvCtx = srvCtx;
|
||||
|
||||
final CountDownLatch ready = new CountDownLatch(1);
|
||||
|
||||
es = Executors.newSingleThreadExecutor();
|
||||
Future<Void> srvFuture = es.submit(new Callable<Void>() {
|
||||
@Override
|
||||
public Void call() throws Exception {
|
||||
int ret;
|
||||
int err;
|
||||
Socket srv = null;
|
||||
WolfSSLSession srvSes = null;
|
||||
try {
|
||||
ready.countDown();
|
||||
srv = fSrvSock.accept();
|
||||
srvSes = new WolfSSLSession(fSrvCtx);
|
||||
srvSes.setRsaSignCtx(srvSignCtx);
|
||||
srvSes.setRsaVerifyCtx(srvVerifyCtx);
|
||||
ret = srvSes.setFd(srv);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new Exception("srv setFd fail: " + ret);
|
||||
}
|
||||
do {
|
||||
ret = srvSes.accept();
|
||||
err = srvSes.getError(ret);
|
||||
} while (ret != WolfSSL.SSL_SUCCESS &&
|
||||
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
throw new Exception("srv accept fail: " + ret);
|
||||
}
|
||||
srvSes.shutdownSSL();
|
||||
|
||||
} finally {
|
||||
if (srvSes != null) {
|
||||
srvSes.freeSSL();
|
||||
}
|
||||
if (srv != null) {
|
||||
srv.close();
|
||||
}
|
||||
fSrvSock.close();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
if (!ready.await(2, TimeUnit.SECONDS)) {
|
||||
fail("Server did not become ready within timeout");
|
||||
}
|
||||
|
||||
cliSock = new Socket("localhost", port);
|
||||
cliSes = new WolfSSLSession(cliCtx);
|
||||
|
||||
int ret = cliSes.setFd(cliSock);
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
fail("cli setFd fail: " + ret);
|
||||
}
|
||||
|
||||
int err;
|
||||
do {
|
||||
ret = cliSes.connect();
|
||||
err = cliSes.getError(ret);
|
||||
} while (ret != WolfSSL.SSL_SUCCESS &&
|
||||
(err == WolfSSL.SSL_ERROR_WANT_READ ||
|
||||
err == WolfSSL.SSL_ERROR_WANT_WRITE));
|
||||
if (ret != WolfSSL.SSL_SUCCESS) {
|
||||
fail("TLS 1.3 PSS CB connect fail: " + ret);
|
||||
}
|
||||
|
||||
cliSes.shutdownSSL();
|
||||
cliSes.freeSSL();
|
||||
cliSock.close();
|
||||
|
||||
/* Check server thread for errors */
|
||||
es.shutdown();
|
||||
srvFuture.get(5, TimeUnit.SECONDS);
|
||||
|
||||
/* Verify server-side callbacks were invoked. Client-side PSS peer
|
||||
* verify uses internal wolfSSL code (no setRsaPssVerifyCb in
|
||||
* JNI yet). */
|
||||
assertTrue("PSS sign cb not called", srvSignCtx.called);
|
||||
assertTrue("PSS sign check cb not called", srvVerifyCtx.called);
|
||||
|
||||
} catch (WolfSSLJNIException e) {
|
||||
/* PK callbacks may not be compiled in */
|
||||
if (e.getMessage() != null &&
|
||||
e.getMessage().contains("PK Callback")) {
|
||||
return;
|
||||
}
|
||||
System.out.println("\t\t... failed");
|
||||
fail("TLS 1.3 PSS CB handshake: " + e.getMessage());
|
||||
|
||||
} catch (ExecutionException e) {
|
||||
System.out.println("\t\t... failed");
|
||||
fail("TLS 1.3 PSS CB server: " + e.getCause().getMessage());
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("\t\t... failed");
|
||||
fail("TLS 1.3 PSS CB handshake: " + e.getMessage());
|
||||
|
||||
} finally {
|
||||
if (cliSes != null) {
|
||||
try { cliSes.freeSSL(); }
|
||||
catch (Exception e) { /* ignore */ }
|
||||
}
|
||||
if (cliSock != null) {
|
||||
try { cliSock.close(); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
if (srvSocket != null && !srvSocket.isClosed()) {
|
||||
try { srvSocket.close(); }
|
||||
catch (IOException e) { /* ignore */ }
|
||||
}
|
||||
if (cliCtx != null) cliCtx.free();
|
||||
if (srvCtx != null) srvCtx.free();
|
||||
if (es != null) {
|
||||
es.shutdownNow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void test_WolfSSLContext_free() {
|
||||
|
||||
System.out.print("\tfree()");
|
||||
|
|
|
|||
Loading…
Reference in New Issue