JNI/JSSE: wrap wolfSSL_set_SessionTicket_cb(), add session ticket callback to SSLEngine for detection of ticket received
parent
d245630133
commit
8449b6744e
|
@ -63,6 +63,12 @@ int NativeALPNSelectCb(WOLFSSL *ssl, const unsigned char **out,
|
||||||
int NativeTls13SecretCb(WOLFSSL *ssl, int id, const unsigned char* secret,
|
int NativeTls13SecretCb(WOLFSSL *ssl, int id, const unsigned char* secret,
|
||||||
int secretSz, void* ctx);
|
int secretSz, void* ctx);
|
||||||
|
|
||||||
|
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
|
||||||
|
/* Session ticket callback prototype */
|
||||||
|
int NativeSessionTicketCb(WOLFSSL *ssl, const unsigned char* ticket,
|
||||||
|
int ticketLen, void* ctx);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_CRL
|
#ifdef HAVE_CRL
|
||||||
/* global object refs for CRL callback */
|
/* global object refs for CRL callback */
|
||||||
static jobject g_crlCbIfaceObj;
|
static jobject g_crlCbIfaceObj;
|
||||||
|
@ -5622,6 +5628,30 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setTls13SecretCb
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setSessionTicketCb
|
||||||
|
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||||
|
{
|
||||||
|
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
|
||||||
|
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||||
|
int ret = SSL_SUCCESS;
|
||||||
|
(void)jcl;
|
||||||
|
|
||||||
|
if (jenv == NULL || ssl == NULL) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Java layer handles setting and giving back user CTX */
|
||||||
|
ret = wolfSSL_set_SessionTicket_cb(ssl, NativeSessionTicketCb, NULL);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
(void)jenv;
|
||||||
|
(void)jcl;
|
||||||
|
(void)sslPtr;
|
||||||
|
return NOT_COMPILED_IN;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(WOLFSSL_TLS13) && !defined(WOLFCRYPT_ONLY) && \
|
#if defined(WOLFSSL_TLS13) && !defined(WOLFCRYPT_ONLY) && \
|
||||||
defined(HAVE_SECRET_CALLBACK)
|
defined(HAVE_SECRET_CALLBACK)
|
||||||
|
|
||||||
|
@ -5764,6 +5794,146 @@ int NativeTls13SecretCb(WOLFSSL *ssl, int id, const unsigned char* secret,
|
||||||
|
|
||||||
#endif /* WOLFSSL_TLS13 && !WOLFCRYPT_ONLY && HAVE_SECRET_CALLBACK */
|
#endif /* WOLFSSL_TLS13 && !WOLFCRYPT_ONLY && HAVE_SECRET_CALLBACK */
|
||||||
|
|
||||||
|
#if !defined(NO_WOLFSSL_CLIENT) && defined(HAVE_SESSION_TICKET)
|
||||||
|
|
||||||
|
int NativeSessionTicketCb(WOLFSSL* ssl, const unsigned char* ticket,
|
||||||
|
int ticketLen, void* ctx)
|
||||||
|
{
|
||||||
|
JNIEnv* jenv; /* JNI environment */
|
||||||
|
jclass excClass; /* WolfSSLJNIException class */
|
||||||
|
int needsDetach = 0; /* Should we explicitly detach? */
|
||||||
|
jint retval = 0;
|
||||||
|
jint vmret = 0;
|
||||||
|
|
||||||
|
jobject* g_cachedSSLObj; /* WolfSSLSession cached object */
|
||||||
|
jclass sslClass; /* WolfSSLSession class */
|
||||||
|
jmethodID sessTicketCbMethodId; /* internalTls13SecretCallback ID */
|
||||||
|
jbyteArray ticketArr = NULL;
|
||||||
|
|
||||||
|
if (g_vm == NULL || ssl == NULL) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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 object */
|
||||||
|
g_cachedSSLObj = (jobject*) wolfSSL_get_jobject(ssl);
|
||||||
|
if (!g_cachedSSLObj) {
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Can't get native WolfSSLSession object reference in "
|
||||||
|
"NativeSessionTicketCb");
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup WolfSSLSession class from object */
|
||||||
|
sslClass = (*jenv)->GetObjectClass(jenv, (jobject)(*g_cachedSSLObj));
|
||||||
|
if (sslClass == NULL) {
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Can't get native WolfSSLSession class reference in "
|
||||||
|
"NativeSessionTicketCb");
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call internal TLS 1.3 secret callback */
|
||||||
|
sessTicketCbMethodId = (*jenv)->GetMethodID(jenv, sslClass,
|
||||||
|
"internalSessionTicketCallback", "(Lcom/wolfssl/WolfSSLSession;[B)I");
|
||||||
|
if (sessTicketCbMethodId == NULL) {
|
||||||
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
(*jenv)->ExceptionClear(jenv);
|
||||||
|
}
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Error getting internalSessionTicketCallback method from JNI");
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ticketLen > 0) {
|
||||||
|
/* Create jbyteArray to hold session ticket */
|
||||||
|
ticketArr = (*jenv)->NewByteArray(jenv, ticketLen);
|
||||||
|
if (ticketArr == NULL) {
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Error creating new jbyteArray in NativeSessionTicketCb");
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*jenv)->SetByteArrayRegion(jenv, ticketArr, 0, ticketLen,
|
||||||
|
(jbyte*)ticket);
|
||||||
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
(*jenv)->ExceptionClear(jenv);
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Call Java session ticket callback, ignore native CTX since Java
|
||||||
|
* handles it */
|
||||||
|
retval = (*jenv)->CallIntMethod(jenv, (jobject)(*g_cachedSSLObj),
|
||||||
|
sessTicketCbMethodId, (jobject)(*g_cachedSSLObj), ticketArr);
|
||||||
|
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||||
|
(*jenv)->ExceptionDescribe(jenv);
|
||||||
|
(*jenv)->ExceptionClear(jenv);
|
||||||
|
(*jenv)->ThrowNew(jenv, excClass,
|
||||||
|
"Exception while calling internalSessionTicketCallback()");
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Delete local refs */
|
||||||
|
(*jenv)->DeleteLocalRef(jenv, ticketArr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detach JNIEnv from thread */
|
||||||
|
if (needsDetach) {
|
||||||
|
(*g_vm)->DetachCurrentThread(g_vm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* WOLFSSL_TLS13 && !WOLFCRYPT_ONLY && HAVE_SECRET_CALLBACK */
|
||||||
|
|
||||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSecureRenegotiation
|
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSecureRenegotiation
|
||||||
(JNIEnv* jenv, jobject jcl, jlong ssl)
|
(JNIEnv* jenv, jobject jcl, jlong ssl)
|
||||||
{
|
{
|
||||||
|
|
|
@ -863,6 +863,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setALPNSelectCb
|
||||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setTls13SecretCb
|
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setTls13SecretCb
|
||||||
(JNIEnv *, jobject, jlong);
|
(JNIEnv *, jobject, jlong);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_wolfssl_WolfSSLSession
|
||||||
|
* Method: setSessionTicketCb
|
||||||
|
* Signature: (J)I
|
||||||
|
*/
|
||||||
|
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setSessionTicketCb
|
||||||
|
(JNIEnv *, jobject, jlong);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Class: com_wolfssl_WolfSSLSession
|
* Class: com_wolfssl_WolfSSLSession
|
||||||
* Method: keepArrays
|
* Method: keepArrays
|
||||||
|
|
|
@ -61,6 +61,7 @@ infer --fail-on-issue run -- javac \
|
||||||
src/java/com/wolfssl/WolfSSLRsaSignCallback.java \
|
src/java/com/wolfssl/WolfSSLRsaSignCallback.java \
|
||||||
src/java/com/wolfssl/WolfSSLRsaVerifyCallback.java \
|
src/java/com/wolfssl/WolfSSLRsaVerifyCallback.java \
|
||||||
src/java/com/wolfssl/WolfSSLSession.java \
|
src/java/com/wolfssl/WolfSSLSession.java \
|
||||||
|
src/java/com/wolfssl/WolfSSLSessionTicketCallback.java \
|
||||||
src/java/com/wolfssl/WolfSSLTls13SecretCallback.java \
|
src/java/com/wolfssl/WolfSSLTls13SecretCallback.java \
|
||||||
src/java/com/wolfssl/WolfSSLVerifyCallback.java \
|
src/java/com/wolfssl/WolfSSLVerifyCallback.java \
|
||||||
src/java/com/wolfssl/WolfSSLVerifyDecryptCallback.java \
|
src/java/com/wolfssl/WolfSSLVerifyDecryptCallback.java \
|
||||||
|
|
|
@ -62,6 +62,7 @@ public class WolfSSLSession {
|
||||||
private Object rsaDecCtx;
|
private Object rsaDecCtx;
|
||||||
private Object alpnSelectArg;
|
private Object alpnSelectArg;
|
||||||
private Object tls13SecretCtx;
|
private Object tls13SecretCtx;
|
||||||
|
private Object sessionTicketCtx;
|
||||||
|
|
||||||
/* reference to the associated WolfSSLContext */
|
/* reference to the associated WolfSSLContext */
|
||||||
private WolfSSLContext ctx = null;
|
private WolfSSLContext ctx = null;
|
||||||
|
@ -80,10 +81,14 @@ public class WolfSSLSession {
|
||||||
* ALPN select callback */
|
* ALPN select callback */
|
||||||
private WolfSSLALPNSelectCallback internAlpnSelectCb;
|
private WolfSSLALPNSelectCallback internAlpnSelectCb;
|
||||||
|
|
||||||
/* user-registered TLS 1.3 secret callbcak, called by internal
|
/* user-registered TLS 1.3 secret callback, called by internal
|
||||||
* WolfSSLSession TLS 1.3 secret callback */
|
* WolfSSLSession TLS 1.3 secret callback */
|
||||||
private WolfSSLTls13SecretCallback internTls13SecretCb;
|
private WolfSSLTls13SecretCallback internTls13SecretCb;
|
||||||
|
|
||||||
|
/* user-registered session ticket callback, called by internal
|
||||||
|
* WolfSSLSession session ticket callback */
|
||||||
|
private WolfSSLSessionTicketCallback internSessionTicketCb;
|
||||||
|
|
||||||
/* have session tickets been enabled for this session? Default to false. */
|
/* have session tickets been enabled for this session? Default to false. */
|
||||||
private boolean sessionTicketsEnabled = false;
|
private boolean sessionTicketsEnabled = false;
|
||||||
|
|
||||||
|
@ -282,6 +287,13 @@ public class WolfSSLSession {
|
||||||
this.tls13SecretCtx);
|
this.tls13SecretCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int internalSessionTicketCallback(WolfSSLSession ssl, byte[] ticket)
|
||||||
|
{
|
||||||
|
/* call user-registered session ticket callback */
|
||||||
|
return internSessionTicketCb.sessionTicketCallback(ssl, ticket,
|
||||||
|
this.sessionTicketCtx);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the current WolfSSLSession object is active.
|
* Verifies that the current WolfSSLSession object is active.
|
||||||
*
|
*
|
||||||
|
@ -415,6 +427,7 @@ public class WolfSSLSession {
|
||||||
private native int useALPN(long ssl, String protocols, int options);
|
private native int useALPN(long ssl, String protocols, int options);
|
||||||
private native int setALPNSelectCb(long ssl);
|
private native int setALPNSelectCb(long ssl);
|
||||||
private native int setTls13SecretCb(long ssl);
|
private native int setTls13SecretCb(long ssl);
|
||||||
|
private native int setSessionTicketCb(long ssl);
|
||||||
private native void keepArrays(long ssl);
|
private native void keepArrays(long ssl);
|
||||||
private native byte[] getClientRandom(long ssl);
|
private native byte[] getClientRandom(long ssl);
|
||||||
private native int useSecureRenegotiation(long ssl);
|
private native int useSecureRenegotiation(long ssl);
|
||||||
|
@ -4819,6 +4832,47 @@ public class WolfSSLSession {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register session ticket callback.
|
||||||
|
*
|
||||||
|
* The callback registered by this method is called by native wolfSSL
|
||||||
|
* when a session ticket is received from the peer.
|
||||||
|
*
|
||||||
|
* @param cb callback to be registered with this SSL session
|
||||||
|
* @param ctx Object that will be passed back to user inside callback
|
||||||
|
*
|
||||||
|
* @return <code>SSL_SUCCESS</code> on success. <code>
|
||||||
|
* NOT_COMPILED_IN</code> if wolfSSL was not compiled with
|
||||||
|
* session ticket support, and other negative value on error.
|
||||||
|
*
|
||||||
|
* @throws IllegalStateException WolfSSLSession has been freed
|
||||||
|
* @throws WolfSSLJNIException Internal JNI error
|
||||||
|
*/
|
||||||
|
public int setSessionTicketCb(WolfSSLSessionTicketCallback cb, Object ctx)
|
||||||
|
throws IllegalStateException, WolfSSLJNIException {
|
||||||
|
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
confirmObjectIsActive();
|
||||||
|
|
||||||
|
synchronized (sslLock) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.Component.JNI,
|
||||||
|
WolfSSLDebug.INFO, this.sslPtr, "entered setSessionTicketCb(" +
|
||||||
|
cb + ", ctx: " + ctx + ")");
|
||||||
|
|
||||||
|
ret = setSessionTicketCb(this.sslPtr);
|
||||||
|
if (ret == WolfSSL.SSL_SUCCESS) {
|
||||||
|
/* Set session ticket callback */
|
||||||
|
internSessionTicketCb = cb;
|
||||||
|
|
||||||
|
/* Set session ticket ctx Object, returned to user in cb */
|
||||||
|
this.sessionTicketCtx = ctx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not free temporary arrays at end of handshake.
|
* Do not free temporary arrays at end of handshake.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/* WolfSSLSessionTicketCallback.java
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* wolfSSL session ticket callback interface.
|
||||||
|
* This interface specifies how applications should implement the session
|
||||||
|
* ticket callback class, to be used by wolfSSL when receiving a session
|
||||||
|
* ticket message.
|
||||||
|
* <p>
|
||||||
|
* To use this interface, native wolfSSL must be compiled with
|
||||||
|
* HAVE_SESSION_TICKET defined.
|
||||||
|
* </p>
|
||||||
|
* After implementing this interface, it should be passed as a parameter
|
||||||
|
* to the
|
||||||
|
* {@link WolfSSLSession#setSessionTicketCb(WolfSSLSessionTicketCallback, Object)
|
||||||
|
* WolfSSLSession.setSessionTicketCb()} method to be registered with the native
|
||||||
|
* wolfSSL library.
|
||||||
|
*/
|
||||||
|
public interface WolfSSLSessionTicketCallback {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback method which is called when native wolfSSL receives a
|
||||||
|
* session ticket message.
|
||||||
|
*
|
||||||
|
* @param ssl the current SSL session object from which the
|
||||||
|
* callback was initiated
|
||||||
|
* @param ticket Session ticket received as a byte array
|
||||||
|
* @param ctx Optional user context if set when callback was
|
||||||
|
* registered
|
||||||
|
*
|
||||||
|
* @return 0 on success. wolfSSL does not currently do anything with
|
||||||
|
* the return value of this method, but is in place for
|
||||||
|
* future expansion if needed.
|
||||||
|
*/
|
||||||
|
public int sessionTicketCallback(WolfSSLSession ssl, byte[] ticket,
|
||||||
|
Object ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import com.wolfssl.WolfSSLIOSendCallback;
|
||||||
import com.wolfssl.WolfSSLJNIException;
|
import com.wolfssl.WolfSSLJNIException;
|
||||||
import com.wolfssl.WolfSSLSession;
|
import com.wolfssl.WolfSSLSession;
|
||||||
import com.wolfssl.WolfSSLALPNSelectCallback;
|
import com.wolfssl.WolfSSLALPNSelectCallback;
|
||||||
|
import com.wolfssl.WolfSSLSessionTicketCallback;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ReadOnlyBufferException;
|
import java.nio.ReadOnlyBufferException;
|
||||||
|
@ -111,11 +112,16 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
/* TLS 1.3 session ticket received (on client side) */
|
/* TLS 1.3 session ticket received (on client side) */
|
||||||
private boolean sessionTicketReceived = false;
|
private boolean sessionTicketReceived = false;
|
||||||
|
|
||||||
|
/* Number of session tickets received, incremented in
|
||||||
|
* SessionTicketCB callback */
|
||||||
|
private int sessionTicketCount = 0;
|
||||||
|
|
||||||
/* client/server mode has been set */
|
/* client/server mode has been set */
|
||||||
private boolean clientModeSet = false;
|
private boolean clientModeSet = false;
|
||||||
|
|
||||||
private SendCB sendCb = null;
|
private SendCB sendCb = null;
|
||||||
private RecvCB recvCb = null;
|
private RecvCB recvCb = null;
|
||||||
|
private SessionTicketCB sessTicketCb = null;
|
||||||
|
|
||||||
private ByteBuffer netData = null;
|
private ByteBuffer netData = null;
|
||||||
private final Object netDataLock = new Object();
|
private final Object netDataLock = new Object();
|
||||||
|
@ -306,6 +312,12 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
ssl.setIOSend(sendCb);
|
ssl.setIOSend(sendCb);
|
||||||
ssl.setIOReadCtx(this);
|
ssl.setIOReadCtx(this);
|
||||||
ssl.setIOWriteCtx(this);
|
ssl.setIOWriteCtx(this);
|
||||||
|
|
||||||
|
/* Session ticket callback */
|
||||||
|
if (sessTicketCb == null) {
|
||||||
|
sessTicketCb = new SessionTicketCB();
|
||||||
|
}
|
||||||
|
ssl.setSessionTicketCb(sessTicketCb, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,6 +350,9 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
if (recvCb == null) {
|
if (recvCb == null) {
|
||||||
recvCb = new RecvCB();
|
recvCb = new RecvCB();
|
||||||
}
|
}
|
||||||
|
if (sessTicketCb == null) {
|
||||||
|
sessTicketCb = new SessionTicketCB();
|
||||||
|
}
|
||||||
|
|
||||||
/* will throw WolfSSLException if issue creating WOLFSSL */
|
/* will throw WolfSSLException if issue creating WOLFSSL */
|
||||||
ssl = new WolfSSLSession(ctx, false);
|
ssl = new WolfSSLSession(ctx, false);
|
||||||
|
@ -1022,6 +1037,7 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
int produced = 0;
|
int produced = 0;
|
||||||
long dtlsPrevDropCount = 0;
|
long dtlsPrevDropCount = 0;
|
||||||
long dtlsCurrDropCount = 0;
|
long dtlsCurrDropCount = 0;
|
||||||
|
int prevSessionTicketCount = 0;
|
||||||
byte[] tmp;
|
byte[] tmp;
|
||||||
|
|
||||||
/* Set initial status for SSLEngineResult return */
|
/* Set initial status for SSLEngineResult return */
|
||||||
|
@ -1149,11 +1165,13 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Get previous DTLS drop count, before we process any
|
/* Get previous DTLS drop count and session ticket count,
|
||||||
* incomming data. Allows us to set BUFFER_UNDERFLOW status
|
* before we process any incomming data. Allows us to set
|
||||||
* (or not if packet decrypt failed and was dropped) */
|
* BUFFER_UNDERFLOW status (or not if packet decrypt failed
|
||||||
|
* and was dropped) */
|
||||||
synchronized (ioLock) {
|
synchronized (ioLock) {
|
||||||
dtlsPrevDropCount = ssl.getDtlsMacDropCount();
|
dtlsPrevDropCount = ssl.getDtlsMacDropCount();
|
||||||
|
prevSessionTicketCount = this.sessionTicketCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.handshakeFinished == false) {
|
if (this.handshakeFinished == false) {
|
||||||
|
@ -1284,12 +1302,17 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
dtlsCurrDropCount = ssl.getDtlsMacDropCount();
|
dtlsCurrDropCount = ssl.getDtlsMacDropCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect if we need to set BUFFER_UNDERFLOW */
|
/* Detect if we need to set BUFFER_UNDERFLOW.
|
||||||
|
* If we consume data in unwrap() but it's just a session
|
||||||
|
* ticket, we don't set BUFFER_UNDERFLOW and just continue
|
||||||
|
* on to set status as OK. */
|
||||||
synchronized (toSendLock) {
|
synchronized (toSendLock) {
|
||||||
synchronized (netDataLock) {
|
synchronized (netDataLock) {
|
||||||
if (ret <= 0 && err == WolfSSL.SSL_ERROR_WANT_READ &&
|
if (ret <= 0 && err == WolfSSL.SSL_ERROR_WANT_READ &&
|
||||||
in.remaining() == 0 && (this.toSend == null ||
|
in.remaining() == 0 && (this.toSend == null ||
|
||||||
(this.toSend != null && this.toSend.length == 0))) {
|
(this.toSend != null && this.toSend.length == 0))
|
||||||
|
&& (prevSessionTicketCount ==
|
||||||
|
this.sessionTicketCount)) {
|
||||||
|
|
||||||
if ((this.ssl.dtls() == 0) ||
|
if ((this.ssl.dtls() == 0) ||
|
||||||
(this.handshakeFinished &&
|
(this.handshakeFinished &&
|
||||||
|
@ -2154,6 +2177,32 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal session ticket callback. Called when native wolfSSL
|
||||||
|
* receives a session ticket from peer.
|
||||||
|
*
|
||||||
|
* @param ticket byte array containing session ticket data
|
||||||
|
*
|
||||||
|
* @return 0 on success, negative value on error
|
||||||
|
*/
|
||||||
|
protected synchronized int internalSessionTicketCb(byte[] ticket) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"entered internalSessionTicketCb()");
|
||||||
|
|
||||||
|
if (ticket != null) {
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Session ticket received, length = " + ticket.length);
|
||||||
|
if (ticket.length > 0) {
|
||||||
|
this.sessionTicketCount++;
|
||||||
|
}
|
||||||
|
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||||
|
"Total session tickets received by this SSLEngine: " +
|
||||||
|
this.sessionTicketCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private class SendCB implements WolfSSLIOSendCallback {
|
private class SendCB implements WolfSSLIOSendCallback {
|
||||||
|
|
||||||
protected SendCB() {
|
protected SendCB() {
|
||||||
|
@ -2180,6 +2229,17 @@ public class WolfSSLEngine extends SSLEngine {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class SessionTicketCB implements WolfSSLSessionTicketCallback {
|
||||||
|
|
||||||
|
protected SessionTicketCB() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int sessionTicketCallback(WolfSSLSession ssl, byte[] ticket,
|
||||||
|
Object engine) {
|
||||||
|
return ((WolfSSLEngine)engine).internalSessionTicketCb(ticket);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
@Override
|
@Override
|
||||||
protected synchronized void finalize() throws Throwable {
|
protected synchronized void finalize() throws Throwable {
|
||||||
|
|
Loading…
Reference in New Issue