JSSE: add initial SSLEngine support for DTLSv1.3
parent
36a1057366
commit
372ef97746
|
|
@ -373,9 +373,12 @@ Additional instructions can be found on the wolfSSL.com website:
|
|||
|
||||
### JSSE Class Implementation Support
|
||||
|
||||
wolfJSSE extends or implements the following JSSE classes:
|
||||
wolfJSSE extends or implements the following JSSE classes. Note that
|
||||
SSLContext `DTLSv1.3` support is only supported through the `SSLEngine`
|
||||
interface.
|
||||
|
||||
- javax.net.ssl.SSLContextSpi
|
||||
- SSL, TLS, DEFAULT, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3
|
||||
- SSL, TLS, DEFAULT, TLSv1, TLSv1.1, TLSv1.2, TLSv1.3, DTLSv1.3
|
||||
- javax.net.ssl.KeyManagerFactorySpi
|
||||
- PKIX, X509, SunX509
|
||||
- javax.net.ssl.TrustManagerFactorySpi
|
||||
|
|
|
|||
|
|
@ -530,6 +530,19 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_TLSv13Enabled
|
|||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_DTLSv13Enabled
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS13)
|
||||
return JNI_TRUE;
|
||||
#else
|
||||
return JNI_FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_ShaEnabled
|
||||
(JNIEnv* jenv, jclass jcl)
|
||||
{
|
||||
|
|
@ -1996,41 +2009,43 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocolsMask
|
|||
|
||||
(void)jcl;
|
||||
|
||||
/* get the number of protocols enabled */
|
||||
/* Get the number of protocols enabled, based on provided mask. Native
|
||||
* wolfSSL doesn't have mask values for DTLS, so we lump them together
|
||||
* with their corresponding TLS version, if correct defines are set. */
|
||||
#ifdef WOLFSSL_TLS13
|
||||
if(!(mask & SSL_OP_NO_TLSv1_3))
|
||||
if(!(mask & SSL_OP_NO_TLSv1_3)) {
|
||||
numProtocols += 1;
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS13)
|
||||
numProtocols += 1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
if(!(mask & SSL_OP_NO_TLSv1_2))
|
||||
if(!(mask & SSL_OP_NO_TLSv1_2)) {
|
||||
numProtocols += 1;
|
||||
#if defined(WOLFSSL_DTLS) && !defined(WOLFSSL_NO_TLS12)
|
||||
numProtocols += 1;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_OLD_TLS
|
||||
if(!(mask & SSL_OP_NO_TLSv1_1))
|
||||
if(!(mask & SSL_OP_NO_TLSv1_1)) {
|
||||
numProtocols += 1;
|
||||
}
|
||||
#ifdef WOLFSSL_ALLOW_TLSV10
|
||||
if(!(mask & SSL_OP_NO_TLSv1))
|
||||
if(!(mask & SSL_OP_NO_TLSv1)) {
|
||||
numProtocols += 1;
|
||||
#ifdef WOLFSSL_DTLS
|
||||
numProtocols += 1;
|
||||
#endif
|
||||
}
|
||||
#endif /* WOLFSSL_ALLOW_TLSv10 */
|
||||
#endif /* !NO_OLD_TLS */
|
||||
#ifdef WOLFSSL_ALLOW_SSLv3
|
||||
if(!(mask & SSL_OP_NO_SSLv3))
|
||||
if(!(mask & SSL_OP_NO_SSLv3)) {
|
||||
numProtocols += 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifndef NO_OLD_TLS
|
||||
/* DTLS 1.0 */
|
||||
numProtocols += 1;
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
/* DTLS 1.2 */
|
||||
numProtocols += 1;
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* DTLS 1.3 */
|
||||
numProtocols += 1;
|
||||
#endif
|
||||
#endif /* WOLFSSL_DTLS */
|
||||
|
||||
ret = (*jenv)->NewObjectArray(jenv, numProtocols,
|
||||
(*jenv)->FindClass(jenv, "java/lang/String"), NULL);
|
||||
|
|
@ -2104,36 +2119,39 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocolsMask
|
|||
|
||||
#ifdef WOLFSSL_DTLS
|
||||
#ifndef NO_OLD_TLS
|
||||
/* DTLS 1.0 */
|
||||
(*jenv)->SetObjectArrayElement(jenv, ret, idx++,
|
||||
(*jenv)->NewStringUTF(jenv, "DTLSv1"));
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, jcl, "Error setting DTLSv1 string");
|
||||
return NULL;
|
||||
if(!(mask & SSL_OP_NO_TLSv1)) {
|
||||
(*jenv)->SetObjectArrayElement(jenv, ret, idx++,
|
||||
(*jenv)->NewStringUTF(jenv, "DTLSv1"));
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, jcl, "Error setting DTLSv1 string");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifndef WOLFSSL_NO_TLS12
|
||||
/* DTLS 1.2 */
|
||||
(*jenv)->SetObjectArrayElement(jenv, ret, idx++,
|
||||
(*jenv)->NewStringUTF(jenv, "DTLSv1.2"));
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, jcl, "Error setting DTLSv1.2 string");
|
||||
return NULL;
|
||||
if(!(mask & SSL_OP_NO_TLSv1_2)) {
|
||||
(*jenv)->SetObjectArrayElement(jenv, ret, idx++,
|
||||
(*jenv)->NewStringUTF(jenv, "DTLSv1.2"));
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, jcl, "Error setting DTLSv1.2 string");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WOLFSSL_DTLS13
|
||||
/* DTLS 1.3 */
|
||||
(*jenv)->SetObjectArrayElement(jenv, ret, idx++,
|
||||
(*jenv)->NewStringUTF(jenv, "DTLSv1.3"));
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, jcl, "Error setting DTLSv1.3 string");
|
||||
return NULL;
|
||||
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_DTLS13)
|
||||
if(!(mask & SSL_OP_NO_TLSv1_3)) {
|
||||
(*jenv)->SetObjectArrayElement(jenv, ret, idx++,
|
||||
(*jenv)->NewStringUTF(jenv, "DTLSv1.3"));
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
(*jenv)->ThrowNew(jenv, jcl, "Error setting DTLSv1.3 string");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -93,10 +93,14 @@ extern "C" {
|
|||
#define com_wolfssl_WolfSSL_SOCKET_ERROR_E -308L
|
||||
#undef com_wolfssl_WolfSSL_FATAL_ERROR
|
||||
#define com_wolfssl_WolfSSL_FATAL_ERROR -313L
|
||||
#undef com_wolfssl_WolfSSL_OUT_OF_ORDER_E
|
||||
#define com_wolfssl_WolfSSL_OUT_OF_ORDER_E -373L
|
||||
#undef com_wolfssl_WolfSSL_SSL_ERROR_SOCKET_PEER_CLOSED
|
||||
#define com_wolfssl_WolfSSL_SSL_ERROR_SOCKET_PEER_CLOSED -397L
|
||||
#undef com_wolfssl_WolfSSL_UNKNOWN_ALPN_PROTOCOL_NAME_E
|
||||
#define com_wolfssl_WolfSSL_UNKNOWN_ALPN_PROTOCOL_NAME_E -405L
|
||||
#undef com_wolfssl_WolfSSL_APP_DATA_READY
|
||||
#define com_wolfssl_WolfSSL_APP_DATA_READY -441L
|
||||
#undef com_wolfssl_WolfSSL_WOLFSSL_CRL_CHECKALL
|
||||
#define com_wolfssl_WolfSSL_WOLFSSL_CRL_CHECKALL 1L
|
||||
#undef com_wolfssl_WolfSSL_WOLFSSL_OCSP_URL_OVERRIDE
|
||||
|
|
@ -597,6 +601,14 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_TLSv12Enabled
|
|||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_TLSv13Enabled
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSL
|
||||
* Method: DTLSv13Enabled
|
||||
* Signature: ()Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSL_DTLSv13Enabled
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSL
|
||||
* Method: ShaEnabled
|
||||
|
|
|
|||
|
|
@ -1568,6 +1568,16 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuff
|
|||
return size;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_pending
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
(void)jcl;
|
||||
|
||||
/* Checks ssl for NULL internally, will return WOLFSSL_FAILURE */
|
||||
return (jint)wolfSSL_pending(ssl);
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_accept
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jint timeout)
|
||||
{
|
||||
|
|
@ -2414,20 +2424,11 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtlsGotTimeout
|
|||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
#if !defined(WOLFSSL_LEANPSK) && defined(WOLFSSL_DTLS)
|
||||
jclass excClass;
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
if (ssl == NULL) {
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Input WolfSSLSession object was null in "
|
||||
"dtlsGotTimeout()");
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
|
|
@ -2440,22 +2441,35 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtlsGotTimeout
|
|||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtls
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtlsRetransmit
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
jclass excClass;
|
||||
#if !defined(WOLFSSL_LEANPSK) && defined(WOLFSSL_DTLS)
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
if (ssl == NULL) {
|
||||
return SSL_FATAL_ERROR;
|
||||
}
|
||||
|
||||
return wolfSSL_dtls_retransmit(ssl);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)sslPtr;
|
||||
return NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtls
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
if (ssl == NULL) {
|
||||
excClass = (*jenv)->FindClass(jenv, "com/wolfssl/WolfSSLException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return 0;
|
||||
}
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Input WolfSSLSession object was null in dtls()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -2694,6 +2708,51 @@ JNIEXPORT jobject JNICALL Java_com_wolfssl_WolfSSLSession_dtlsGetPeer
|
|||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setMTU
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr, jint mtu)
|
||||
{
|
||||
#if defined(WOLFSSL_DTLS) && defined(WOLFSSL_DTLS_MTU)
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
|
||||
/* wolfSSL_dtls_set_mtu() checks ssl for NULL */
|
||||
return (jint)wolfSSL_dtls_set_mtu(ssl, (unsigned short)mtu);
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)sslPtr;
|
||||
(void)mtu;
|
||||
return (jint)NOT_COMPILED_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLSession_stateStringLong
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
#ifdef OPENSSL_EXTRA
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
const char* stateString;
|
||||
jstring stateStr = NULL;
|
||||
(void)jcl;
|
||||
|
||||
if (jenv == NULL || ssl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
stateString = wolfSSL_state_string_long(ssl);
|
||||
|
||||
if (stateString != NULL) {
|
||||
stateStr = (*jenv)->NewStringUTF(jenv, stateString);
|
||||
}
|
||||
|
||||
return stateStr;
|
||||
#else
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
(void)sslPtr;
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_sessionReused
|
||||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
|
|
@ -4681,9 +4740,8 @@ JNIEXPORT jboolean JNICALL Java_com_wolfssl_WolfSSLSession_handshakeDone
|
|||
if (wolfSSL_is_init_finished(ssl)) {
|
||||
return JNI_TRUE;
|
||||
}
|
||||
else {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setConnectState
|
||||
|
|
@ -5777,24 +5835,12 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIORecv
|
|||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
/* find exception class */
|
||||
jclass excClass = (*jenv)->FindClass(jenv,
|
||||
"com/wolfssl/WolfSSLJNIException");
|
||||
if ((*jenv)->ExceptionOccurred(jenv)) {
|
||||
(*jenv)->ExceptionDescribe(jenv);
|
||||
(*jenv)->ExceptionClear(jenv);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ssl != NULL) {
|
||||
/* set I/O recv callback */
|
||||
wolfSSL_SSLSetIORecv(ssl, NativeSSLIORecvCb);
|
||||
|
||||
} else {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Input WolfSSLContext object was null when setting IORecv");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5931,23 +5977,12 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIOSend
|
|||
(JNIEnv* jenv, jobject jcl, jlong sslPtr)
|
||||
{
|
||||
WOLFSSL* ssl = (WOLFSSL*)(uintptr_t)sslPtr;
|
||||
jclass excClass = NULL;
|
||||
(void)jenv;
|
||||
(void)jcl;
|
||||
|
||||
/* 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 (ssl != NULL) {
|
||||
/* set I/O send callback */
|
||||
wolfSSL_SSLSetIOSend(ssl, NativeSSLIOSendCb);
|
||||
|
||||
} else {
|
||||
(*jenv)->ThrowNew(jenv, excClass,
|
||||
"Input WolfSSLContext object was null when setting IOSend");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,6 +111,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__J_3BIII
|
|||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_read__JLjava_nio_ByteBuffer_2II
|
||||
(JNIEnv *, jobject, jlong, jobject, jint, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLSession
|
||||
* Method: pending
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_pending
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLSession
|
||||
* Method: accept
|
||||
|
|
@ -279,6 +287,14 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtlsGetCurrentTimeout
|
|||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtlsGotTimeout
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLSession
|
||||
* Method: dtlsRetransmit
|
||||
* Signature: (J)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_dtlsRetransmit
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLSession
|
||||
* Method: dtls
|
||||
|
|
@ -895,6 +911,22 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_interruptBlockedIO
|
|||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getThreadsBlockedInPoll
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLSession
|
||||
* Method: setMTU
|
||||
* Signature: (JI)I
|
||||
*/
|
||||
JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_setMTU
|
||||
(JNIEnv *, jobject, jlong, jint);
|
||||
|
||||
/*
|
||||
* Class: com_wolfssl_WolfSSLSession
|
||||
* Method: stateStringLong
|
||||
* Signature: (J)Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_com_wolfssl_WolfSSLSession_stateStringLong
|
||||
(JNIEnv *, jobject, jlong);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -214,10 +214,14 @@ public class WolfSSL {
|
|||
public static final int SOCKET_ERROR_E = -308;
|
||||
/** Received fatal alert error */
|
||||
public static final int FATAL_ERROR = -313;
|
||||
/** Out of order message */
|
||||
public static final int OUT_OF_ORDER_E = -373;
|
||||
/** Peer closed socket */
|
||||
public static final int SSL_ERROR_SOCKET_PEER_CLOSED = -397;
|
||||
/** Unrecognized ALPN protocol name */
|
||||
public static final int UNKNOWN_ALPN_PROTOCOL_NAME_E = -405;
|
||||
/** DTLS application data ready for read */
|
||||
public static final int APP_DATA_READY = -441;
|
||||
|
||||
/* extra definitions from ssl.h */
|
||||
/** CertManager: check all cert CRLs */
|
||||
|
|
@ -844,6 +848,13 @@ public class WolfSSL {
|
|||
*/
|
||||
public static native boolean TLSv13Enabled();
|
||||
|
||||
/**
|
||||
* Tests if DTLS 1.3 has been compiled into the native wolfSSL library.
|
||||
*
|
||||
* @return true if enabled, otherwise false if not compiled in.
|
||||
*/
|
||||
public static native boolean DTLSv13Enabled();
|
||||
|
||||
/**
|
||||
* Tests if SHA-1 is enabled in the native wolfSSL library.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -316,6 +316,7 @@ public class WolfSSLSession {
|
|||
int timeout);
|
||||
private native int read(long ssl, ByteBuffer data, int sz, int timeout)
|
||||
throws WolfSSLException;
|
||||
private native int pending(long ssl);
|
||||
private native int accept(long ssl, int timeout);
|
||||
private native void freeSSL(long ssl);
|
||||
private native int shutdownSSL(long ssl, int timeout);
|
||||
|
|
@ -337,6 +338,7 @@ public class WolfSSLSession {
|
|||
private native int setCipherList(long ssl, String list);
|
||||
private native int dtlsGetCurrentTimeout(long ssl);
|
||||
private native int dtlsGotTimeout(long ssl);
|
||||
private native int dtlsRetransmit(long ssl);
|
||||
private native int dtls(long ssl);
|
||||
private native int dtlsSetPeer(long ssl, InetSocketAddress peer);
|
||||
private native InetSocketAddress dtlsGetPeer(long ssl);
|
||||
|
|
@ -419,6 +421,8 @@ public class WolfSSLSession {
|
|||
private native int hasTicket(long session);
|
||||
private native int interruptBlockedIO(long ssl);
|
||||
private native int getThreadsBlockedInPoll(long ssl);
|
||||
private native int setMTU(long ssl, int mtu);
|
||||
private native String stateStringLong(long ssl);
|
||||
|
||||
/* ------------------- session-specific methods --------------------- */
|
||||
|
||||
|
|
@ -1139,7 +1143,7 @@ public class WolfSSLSession {
|
|||
* <code>read()</code> again. Use <code>getError</code> to
|
||||
* get a specific error code.
|
||||
* <code>BAD_FUNC_ARC</code> when bad arguments are used.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws IllegalStateException WolfSSLSession has been freed
|
||||
* @throws SocketTimeoutException if socket timeout occurs
|
||||
* @throws SocketException Native socket select/poll() failed
|
||||
*/
|
||||
|
|
@ -1257,6 +1261,29 @@ public class WolfSSLSession {
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return number of bytes available on the internal output buffer that
|
||||
* have already been decrypted and available immediately via a call to
|
||||
* read().
|
||||
*
|
||||
* @return number of bytes available on success, WolfSSL.SSL_FAILURE
|
||||
* on error.
|
||||
*
|
||||
* @throws IllegalStateException WolfSSLSession has been freed
|
||||
*/
|
||||
public int pending() throws IllegalStateException {
|
||||
|
||||
int ret = 0;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
ret = pending(this.sslPtr);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Waits for an SSL client to initiate the SSL/TLS handshake.
|
||||
* This method is called on the server side. When it is called, the
|
||||
|
|
@ -2260,14 +2287,12 @@ public class WolfSSLSession {
|
|||
* the peer. <code>NOT_COMPILED_IN</code> if wolfSSL was
|
||||
* not compiled with DTLS support.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws WolfSSLJNIException Internal JNI error
|
||||
* @see #dtlsGetCurrentTimeout()
|
||||
* @see #dtlsGetPeer()
|
||||
* @see #dtlsSetPeer(InetSocketAddress)
|
||||
* @see #dtls()
|
||||
*/
|
||||
public int dtlsGotTimeout()
|
||||
throws IllegalStateException, WolfSSLJNIException {
|
||||
public int dtlsGotTimeout() throws IllegalStateException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
|
|
@ -2279,20 +2304,47 @@ public class WolfSSLSession {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When using non-blocking sockets with DTLS, this function retransmits
|
||||
* the last handshake flight ignoring the expected timeout value and
|
||||
* retransmit count.
|
||||
*
|
||||
* It is useful for applications that are using DTLS and need to manage
|
||||
* even the timeout and retry count.
|
||||
*
|
||||
* @return <code>SSL_SUCCESS</code> upon success. <code>
|
||||
* SSL_FATAL_ERROR</code> if there have been too many
|
||||
* retransmissions/timeouts without getting a response from
|
||||
* the peer. <code>NOT_COMPILED_IN</code> if wolfSSL was
|
||||
* not compiled with DTLS support.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @see #dtlsGetCurrentTimeout()
|
||||
* @see #dtlsGetPeer()
|
||||
* @see #dtlsSetPeer(InetSocketAddress)
|
||||
* @see #dtlsGotTimeout()
|
||||
* @see #dtls()
|
||||
*/
|
||||
public int dtlsRetransmit() throws IllegalStateException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
return dtlsRetransmit(this.sslPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to determine if the SSL session has been configured to use DTLS.
|
||||
*
|
||||
* @return <code>1</code> if the SSL has been configured to use DTLS,
|
||||
* otherwise, <code>0</code>.
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
* @throws WolfSSLJNIException Internal JNI error
|
||||
* @see #dtlsGetCurrentTimeout()
|
||||
* @see #dtlsGetPeer()
|
||||
* @see #dtlsGotTimeout()
|
||||
* @see #dtlsSetPeer(InetSocketAddress)
|
||||
*/
|
||||
public int dtls()
|
||||
throws IllegalStateException, WolfSSLJNIException {
|
||||
public int dtls() throws IllegalStateException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
|
|
@ -2355,6 +2407,57 @@ public class WolfSSLSession {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the DTLS MTU to use.
|
||||
*
|
||||
* Native wolfSSL must be compiled with "--enable-dtls-mtu" in addition
|
||||
* to "--enable-dtls".
|
||||
*
|
||||
* @param mtu DTLS MTU value, must be lower than MAX_RECORD_SIZE (16k)
|
||||
*
|
||||
* @return <code>SSL_SUCCESS</code> on success,
|
||||
* <code>SSL_FAILURE</code> on error, or
|
||||
* <code>NOT_COMPILED_IN</code> if native support has not
|
||||
* been compiled into native wolfSSL.
|
||||
*
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
*/
|
||||
public int dtlsSetMTU(int mtu) throws IllegalStateException {
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
return setMTU(this.sslPtr, mtu);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current handshake state of the native WOLFSSL object as
|
||||
* a String.
|
||||
*
|
||||
* @return String representing current state of handshake or empty
|
||||
* String if not able to retrieve one.
|
||||
*
|
||||
* @throws IllegalStateException WolfSSLContext has been freed
|
||||
*/
|
||||
public String getStateStringLong() throws IllegalStateException {
|
||||
|
||||
String state = null;
|
||||
|
||||
confirmObjectIsActive();
|
||||
|
||||
synchronized (sslLock) {
|
||||
state = stateStringLong(this.sslPtr);
|
||||
if (state == null) {
|
||||
/* Return empty string instead of null, may prevent some
|
||||
* NullPoinerExceptions from callers */
|
||||
state = "";
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a reused session was negotiated during the SSL
|
||||
* handshake.
|
||||
|
|
@ -4168,8 +4271,10 @@ public class WolfSSLSession {
|
|||
/* set user I/O recv */
|
||||
internRecvSSLCb = callback;
|
||||
|
||||
/* register internal callback with native library */
|
||||
setSSLIORecv(this.sslPtr);
|
||||
if (callback != null) {
|
||||
/* register internal callback with native library */
|
||||
setSSLIORecv(this.sslPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4206,8 +4311,10 @@ public class WolfSSLSession {
|
|||
/* set user I/O send */
|
||||
internSendSSLCb = callback;
|
||||
|
||||
/* register internal callback with native library */
|
||||
setSSLIOSend(this.sslPtr);
|
||||
if (callback != null) {
|
||||
/* register internal callback with native library */
|
||||
setSSLIOSend(this.sslPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,8 @@ public class WolfSSLContext extends SSLContextSpi {
|
|||
ctxAttr.version == TLS_VERSION.TLSv1_1 ||
|
||||
ctxAttr.version == TLS_VERSION.TLSv1_2 ||
|
||||
ctxAttr.version == TLS_VERSION.TLSv1_3 ||
|
||||
ctxAttr.version == TLS_VERSION.SSLv23) {
|
||||
ctxAttr.version == TLS_VERSION.SSLv23 ||
|
||||
ctxAttr.version == TLS_VERSION.DTLSv1_3) {
|
||||
this.currentVersion = ctxAttr.version;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
|
|
@ -134,6 +135,11 @@ public class WolfSSLContext extends SSLContextSpi {
|
|||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"creating WolfSSLContext with SSLv23");
|
||||
break;
|
||||
case DTLSv1_3:
|
||||
method = WolfSSL.DTLSv1_3_Method();
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"creating WolfSSLContext with DTLSv1_3");
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid SSL/TLS protocol version");
|
||||
|
|
@ -175,7 +181,7 @@ public class WolfSSLContext extends SSLContextSpi {
|
|||
* which have been disabled via system property get filtered in
|
||||
* WolfSSLEngineHelper.sanitizeProtocols() */
|
||||
params.setProtocols(WolfSSLUtil.sanitizeProtocols(
|
||||
this.getProtocolsMask(ctxAttr.noOptions)));
|
||||
this.getProtocolsMask(ctxAttr.noOptions), this.currentVersion));
|
||||
|
||||
try {
|
||||
LoadTrustedRootCerts();
|
||||
|
|
@ -677,6 +683,20 @@ public class WolfSSLContext extends SSLContextSpi {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* SSLContext implementation supporting DTLS 1.3
|
||||
*/
|
||||
public static final class DTLSV13_Context extends WolfSSLContext {
|
||||
/**
|
||||
* Create new DTLSv13_Context, calls parent WolfSSLContext constructor
|
||||
*/
|
||||
public DTLSV13_Context() {
|
||||
super(TLS_VERSION.DTLSv1_3);
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"creating new WolfSSLContext using DTLSV13_Context");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* DEFAULT SSLContext class.
|
||||
|
|
|
|||
|
|
@ -72,6 +72,8 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
private WolfSSLAuthStore authStore = null;
|
||||
private WolfSSLParameters params = null;
|
||||
private byte[] toSend = null; /* encrypted packet to send */
|
||||
private int nativeWantsToWrite = 0;
|
||||
private int nativeWantsToRead = 0;
|
||||
private HandshakeStatus hs = SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
|
||||
|
||||
/* Does TLS handshake need initialization */
|
||||
|
|
@ -218,6 +220,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
|
||||
try {
|
||||
this.engineHelper.LoadKeyAndCertChain(null, this);
|
||||
certKeyLoaded = true;
|
||||
} catch (CertificateEncodingException | IOException |
|
||||
WolfSSLException e) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
|
|
@ -441,26 +444,43 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
* times out. This should not happen since infinite timeout is
|
||||
* being used for these calls.
|
||||
*/
|
||||
private synchronized int DoHandshake() throws SSLException {
|
||||
private synchronized int DoHandshake(boolean fromWrap) throws SSLException {
|
||||
int ret = WolfSSL.SSL_SUCCESS;
|
||||
|
||||
try {
|
||||
if (this.getUseClientMode()) {
|
||||
/* If DTLS and calling from wrap() but HandshakeStatus is
|
||||
* actually NEED_UNWRAP, this is a signal from the application
|
||||
* that we need to retransmit messages */
|
||||
if ((this.ssl.dtls() == 1) && fromWrap &&
|
||||
(this.hs == SSLEngineResult.HandshakeStatus.NEED_UNWRAP)) {
|
||||
synchronized (ioLock) {
|
||||
ret = this.ssl.connect();
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"ssl.connect() ret:err = " + ret + " : " +
|
||||
ssl.getError(ret));
|
||||
"Calling wrap() while status is NEED_UNWRAP, " +
|
||||
"retransmitting DTLS messages");
|
||||
ret = this.ssl.dtlsGotTimeout();
|
||||
if (ret == 0) {
|
||||
ret = WolfSSL.SSL_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
synchronized (ioLock) {
|
||||
ret = this.ssl.accept();
|
||||
if (ret == WolfSSL.SSL_SUCCESS) {
|
||||
if (this.getUseClientMode()) {
|
||||
synchronized (ioLock) {
|
||||
ret = this.ssl.connect();
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"ssl.accept() ret:err = " + ret + " : " +
|
||||
ssl.getError(ret));
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"ssl.connect() ret:err = " + ret + " : " +
|
||||
ssl.getError(ret));
|
||||
}
|
||||
}
|
||||
else {
|
||||
synchronized (ioLock) {
|
||||
ret = this.ssl.accept();
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"ssl.accept() ret:err = " + ret + " : " +
|
||||
ssl.getError(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -633,6 +653,12 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
"handshakeStatus: " + hs);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"handshakeFinished: " + this.handshakeFinished);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeHandshakeState: " + this.ssl.getStateStringLong());
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToRead: " + this.nativeWantsToRead);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToWrite: " + this.nativeWantsToWrite);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"===========================================================");
|
||||
}
|
||||
|
|
@ -691,7 +717,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
else if (produced == 0) {
|
||||
/* continue handshake or application data */
|
||||
if (!this.handshakeFinished) {
|
||||
ret = DoHandshake();
|
||||
ret = DoHandshake(true);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
|
|
@ -756,6 +782,12 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
"consumed: " + consumed);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"produced: " + produced);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeHandshakeState: " + this.ssl.getStateStringLong());
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToRead: " + this.nativeWantsToRead);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToWrite: " + this.nativeWantsToWrite);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"===========================================================");
|
||||
}
|
||||
|
|
@ -830,10 +862,22 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
* ByteBuffer array */
|
||||
if (out.length == 1) {
|
||||
ret = this.ssl.read(out[0], maxOutSz, 0);
|
||||
if ((ret < 0) &&
|
||||
(ssl.getError(ret) == WolfSSL.APP_DATA_READY)) {
|
||||
/* If DTLS, we may need to call SSL_read() again
|
||||
* right away again if app data was received */
|
||||
ret = this.ssl.read(out[0], maxOutSz, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
tmp = new byte[maxOutSz];
|
||||
ret = this.ssl.read(tmp, maxOutSz);
|
||||
if ((ret < 0) &&
|
||||
(ssl.getError(ret) == WolfSSL.APP_DATA_READY)) {
|
||||
/* If DTLS, we may need to call SSL_read() again
|
||||
* right away again if app data was received */
|
||||
ret = this.ssl.read(tmp, maxOutSz);
|
||||
}
|
||||
}
|
||||
} catch (SocketTimeoutException | SocketException e) {
|
||||
throw new SSLException(e);
|
||||
|
|
@ -855,6 +899,11 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
"RecvAppData(), got WANT_READ/WANT_WRITE");
|
||||
break;
|
||||
|
||||
case WolfSSL.APP_DATA_READY:
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"RecvAppData(), got APP_DATA_READY");
|
||||
break;
|
||||
|
||||
/* In 0 and ZERO_RETURN cases we may have gotten a
|
||||
* close_notify alert, check on shutdown status */
|
||||
case WolfSSL.SSL_ERROR_ZERO_RETURN:
|
||||
|
|
@ -1024,6 +1073,12 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
"handshakeStatus: " + hs);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"status: " + status);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeHandshakeState: " + this.ssl.getStateStringLong());
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToRead: " + this.nativeWantsToRead);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToWrite: " + this.nativeWantsToWrite);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"===========================================================");
|
||||
}
|
||||
|
|
@ -1066,12 +1121,10 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
}
|
||||
}
|
||||
else {
|
||||
|
||||
if (this.handshakeFinished == false) {
|
||||
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"starting or continuing handshake");
|
||||
ret = DoHandshake();
|
||||
ret = DoHandshake(false);
|
||||
}
|
||||
else {
|
||||
/* If we have input data, make sure output buffer length is
|
||||
|
|
@ -1093,17 +1146,32 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
if (ret > 0) {
|
||||
produced += ret;
|
||||
}
|
||||
else {
|
||||
synchronized (netDataLock) {
|
||||
if (ret == 0 && in.remaining() > 0 &&
|
||||
getTotalOutputSize(out, ofst,
|
||||
length) == 0) {
|
||||
/* We have more data to read, but no more
|
||||
* out space left in ByteBuffer[], ask for
|
||||
* more */
|
||||
status =
|
||||
SSLEngineResult.Status.BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* Check for BUFFER_OVERFLOW status. This can happen
|
||||
* if either we have data cached internally
|
||||
* (in.remaining()) and we have no more output space,
|
||||
* or if we have more decrypted plaintext in the native
|
||||
* wolfSSL output buffer and ssl.pending() is > 0. */
|
||||
synchronized (ioLock) {
|
||||
if ((ret > 0) && (ssl.pending() > 0)) {
|
||||
status =
|
||||
SSLEngineResult.Status.BUFFER_OVERFLOW;
|
||||
}
|
||||
else if ((ret == 0) && (ssl.pending() > 0) &&
|
||||
getTotalOutputSize(out, ofst, length) == 0) {
|
||||
status =
|
||||
SSLEngineResult.Status.BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
synchronized (netDataLock) {
|
||||
if (ret == 0 && in.remaining() > 0 &&
|
||||
getTotalOutputSize(out, ofst,
|
||||
length) == 0) {
|
||||
/* We have more data to read, but no more
|
||||
* out space left in ByteBuffer[], ask for
|
||||
* more */
|
||||
status =
|
||||
SSLEngineResult.Status.BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1125,7 +1193,7 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} /* end DoHandshake() / RecvAppData() */
|
||||
|
||||
if (outBoundOpen == false || this.closeNotifySent) {
|
||||
/* Mark SSLEngine status as CLOSED */
|
||||
|
|
@ -1138,9 +1206,18 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
synchronized (ioLock) {
|
||||
err = ssl.getError(ret);
|
||||
}
|
||||
if (ret < 0 &&
|
||||
if (ret < 0 && (this.ssl.dtls() == 1) &&
|
||||
(err == WolfSSL.OUT_OF_ORDER_E)) {
|
||||
/* Received out of order DTLS message. Ignore and set our
|
||||
* status to NEED_UNWRAP again to wait for correct data */
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"out of order message, dropping and putting state " +
|
||||
"back to NEED_UNWRAP");
|
||||
}
|
||||
else if (ret < 0 &&
|
||||
(err != WolfSSL.SSL_ERROR_WANT_READ) &&
|
||||
(err != WolfSSL.SSL_ERROR_WANT_WRITE)) {
|
||||
|
||||
if (err == WolfSSL.UNKNOWN_ALPN_PROTOCOL_NAME_E) {
|
||||
/* Native wolfSSL could not negotiate a common ALPN
|
||||
* protocol */
|
||||
|
|
@ -1167,11 +1244,17 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
|
||||
synchronized (toSendLock) {
|
||||
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 ||
|
||||
(this.toSend != null && this.toSend.length == 0))) {
|
||||
/* Need more data */
|
||||
status = SSLEngineResult.Status.BUFFER_UNDERFLOW;
|
||||
if ((this.ssl.dtls() == 0) ||
|
||||
this.handshakeFinished) {
|
||||
/* Need more data. For DTLS only set
|
||||
* after handshake has completed, since
|
||||
* apps expect to switch on NEED_UNWRAP
|
||||
* HandshakeStatus at that point */
|
||||
status = SSLEngineResult.Status.BUFFER_UNDERFLOW;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1191,10 +1274,19 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
if (this.getUseClientMode() && this.handshakeFinished &&
|
||||
this.ssl.hasSessionTicket() &&
|
||||
this.sessionTicketReceived == false) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"received session ticket, returning " +
|
||||
"HandshakeStatus FINISHED");
|
||||
hs = SSLEngineResult.HandshakeStatus.FINISHED;
|
||||
if (this.ssl.dtls() == 1 && this.toSend != null &&
|
||||
this.toSend.length > 0) {
|
||||
/* DTLS 1.3 ACK has been produced in response to
|
||||
* session ticket message, let's set HS status to
|
||||
* NEED_WRAP so application knows it needs to be sent. */
|
||||
hs = SSLEngineResult.HandshakeStatus.NEED_WRAP;
|
||||
}
|
||||
else {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"received session ticket, returning " +
|
||||
"HandshakeStatus FINISHED");
|
||||
hs = SSLEngineResult.HandshakeStatus.FINISHED;
|
||||
}
|
||||
this.sessionTicketReceived = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1245,6 +1337,12 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
"consumed: " + consumed);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"produced: " + produced);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeHandshakeState: " + this.ssl.getStateStringLong());
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToRead: " + this.nativeWantsToRead);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"nativeWantsToWrite: " + this.nativeWantsToWrite);
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"===========================================================");
|
||||
}
|
||||
|
|
@ -1306,7 +1404,9 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
else {
|
||||
synchronized (netDataLock) {
|
||||
synchronized (ioLock) {
|
||||
if (ssl.handshakeDone() && this.toSend == null) {
|
||||
if (ssl.handshakeDone() && (this.toSend == null) &&
|
||||
(this.nativeWantsToWrite == 0) &&
|
||||
(this.nativeWantsToRead == 0)) {
|
||||
this.handshakeFinished = true;
|
||||
hs = SSLEngineResult.HandshakeStatus.FINISHED;
|
||||
this.engineHelper.getSession().updateStoredSessionValues();
|
||||
|
|
@ -1336,6 +1436,9 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
else if (err == WolfSSL.SSL_ERROR_WANT_WRITE) {
|
||||
hs = SSLEngineResult.HandshakeStatus.NEED_WRAP;
|
||||
}
|
||||
else if (err == WolfSSL.OUT_OF_ORDER_E) {
|
||||
hs = SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
|
||||
}
|
||||
else {
|
||||
hs = SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
|
||||
}
|
||||
|
|
@ -1489,7 +1592,13 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
public synchronized SSLSession getHandshakeSession() {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"entered getHandshakeSession()");
|
||||
return this.engineHelper.getSession();
|
||||
|
||||
if (!this.handshakeFinished) {
|
||||
/* Only return handshake session during the handshake */
|
||||
return this.engineHelper.getSession();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1526,18 +1635,20 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
"setUseClientMode() has not been called on this SSLEngine");
|
||||
}
|
||||
|
||||
if (this.handshakeStartedExplicitly) {
|
||||
/* Renegotiation (thus calling beginHandshake() multiple times)
|
||||
* is not supported in wolfJSSE SSLEngine implementation yet. If
|
||||
* already called once by user, throw SSLException. */
|
||||
throw new SSLException("Renegotiation not supported");
|
||||
}
|
||||
else if (!this.needInit && !this.handshakeFinished) {
|
||||
/* Handshake has started implicitly by wrap() or unwrap(). Simply
|
||||
* return since this is the first time that the user has called
|
||||
* beginHandshake() themselves. */
|
||||
this.handshakeStartedExplicitly = true;
|
||||
return;
|
||||
synchronized (initLock) {
|
||||
if (this.handshakeStartedExplicitly) {
|
||||
/* Renegotiation (thus calling beginHandshake() multiple times)
|
||||
* is not supported in wolfJSSE SSLEngine implementation yet. If
|
||||
* already called once by user, throw SSLException. */
|
||||
throw new SSLException("Renegotiation not supported");
|
||||
}
|
||||
else if (!this.needInit && !this.handshakeFinished) {
|
||||
/* Handshake has started implicitly by wrap() or unwrap(). Simply
|
||||
* return since this is the first time that the user has called
|
||||
* beginHandshake() themselves. */
|
||||
this.handshakeStartedExplicitly = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* No network data source yet */
|
||||
|
|
@ -1556,11 +1667,9 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
throw new SSLException(e);
|
||||
}
|
||||
|
||||
if (needInit == true) {
|
||||
/* will throw SSLHandshakeException if session creation is
|
||||
not allowed */
|
||||
checkAndInitSSLEngine();
|
||||
}
|
||||
/* will throw SSLHandshakeException if session creation is
|
||||
not allowed */
|
||||
checkAndInitSSLEngine();
|
||||
|
||||
try {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
|
|
@ -1865,6 +1974,30 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
byte[] prevToSend = null;
|
||||
|
||||
synchronized (toSendLock) {
|
||||
/* As per JSSE Reference Guide, Section 8 DTLS implementation
|
||||
* of wrap() contains at most one record so every DTLS record
|
||||
* can be marshaled and delivered to datagram individually. As
|
||||
* such, if we have data wait to send before caching more */
|
||||
/* TODO - do we need to fragment data here if larger than
|
||||
* SSLParameters.getMaximumPacketSize() with DTLS? */
|
||||
if (this.ssl.dtls() == 1) {
|
||||
if (this.toSend != null) {
|
||||
/* Cause SSLEngine to only send one packet at a time.
|
||||
* Keep track if wolfSSL had wanted to send data. We will
|
||||
* use that information when setting the handshake
|
||||
* status */
|
||||
if (sz > 0) {
|
||||
this.nativeWantsToWrite = sz;
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Reset native wants to send data flag. We have cleared
|
||||
* cached data in the object, so this call of the send CB
|
||||
* should be with the desired native data now. */
|
||||
this.nativeWantsToWrite = 0;
|
||||
}
|
||||
|
||||
/* Make copy of existing toSend array before expanding */
|
||||
if (this.toSend != null) {
|
||||
prevToSend = this.toSend.clone();
|
||||
|
|
@ -1927,9 +2060,15 @@ public class WolfSSLEngine extends SSLEngine {
|
|||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"CB Read: returning WOLFSSL_CBIO_ERR_WANT_READ");
|
||||
}
|
||||
if (this.ssl.dtls() == 1 && this.handshakeFinished) {
|
||||
this.nativeWantsToRead = 1;
|
||||
}
|
||||
return WolfSSL.WOLFSSL_CBIO_ERR_WANT_READ;
|
||||
}
|
||||
|
||||
/* Reset native wants to read flag */
|
||||
this.nativeWantsToRead = 0;
|
||||
|
||||
max = (sz < this.netData.remaining()) ? sz : this.netData.remaining();
|
||||
this.netData.get(toRead, 0, max);
|
||||
|
||||
|
|
|
|||
|
|
@ -495,7 +495,8 @@ public class WolfSSLEngineHelper {
|
|||
for (int i = 0; i < suites.length; i++) {
|
||||
if (!supported.contains(suites[i])) {
|
||||
throw new IllegalArgumentException("Unsupported CipherSuite: " +
|
||||
suites[i]);
|
||||
suites[i] + "(Supported: " +
|
||||
Arrays.toString(getAllCiphers()) + ")");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -532,7 +533,8 @@ public class WolfSSLEngineHelper {
|
|||
}
|
||||
}
|
||||
|
||||
this.params.setProtocols(WolfSSLUtil.sanitizeProtocols(p));
|
||||
this.params.setProtocols(
|
||||
WolfSSLUtil.sanitizeProtocols(p, WolfSSL.TLS_VERSION.INVALID));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -541,7 +543,8 @@ public class WolfSSLEngineHelper {
|
|||
* @return String array of enabled SSL/TLS protocols
|
||||
*/
|
||||
protected synchronized String[] getProtocols() {
|
||||
return WolfSSLUtil.sanitizeProtocols(this.params.getProtocols());
|
||||
return WolfSSLUtil.sanitizeProtocols(
|
||||
this.params.getProtocols(), WolfSSL.TLS_VERSION.INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -552,7 +555,8 @@ public class WolfSSLEngineHelper {
|
|||
* @return String array of supported protocols
|
||||
*/
|
||||
protected static synchronized String[] getAllProtocols() {
|
||||
return WolfSSLUtil.sanitizeProtocols(WolfSSL.getProtocols());
|
||||
return WolfSSLUtil.sanitizeProtocols(
|
||||
WolfSSL.getProtocols(), WolfSSL.TLS_VERSION.INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -751,10 +755,12 @@ public class WolfSSLEngineHelper {
|
|||
}
|
||||
|
||||
for (i = 0; i < p.length; i++) {
|
||||
if (p[i].equals("TLSv1.3")) {
|
||||
/* TLS 1.3 needs to be enabled for DTLS 1.3 */
|
||||
if (p[i].equals("TLSv1.3") || p[i].equals("DTLSv1.3")) {
|
||||
set[0] = true;
|
||||
}
|
||||
if (p[i].equals("TLSv1.2")) {
|
||||
/* TLS 1.2 needs to be enabled for DTLS 1.2 */
|
||||
if (p[i].equals("TLSv1.2") || p[i].equals("DTLSv1.2")) {
|
||||
set[1] = true;
|
||||
}
|
||||
if (p[i].equals("TLSv1.1")) {
|
||||
|
|
@ -768,6 +774,7 @@ public class WolfSSLEngineHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/* Note: No SSL_OP_NO_* for DTLS in native wolfSSL */
|
||||
if (set[0] == false) {
|
||||
mask |= WolfSSL.SSL_OP_NO_TLSv1_3;
|
||||
}
|
||||
|
|
@ -1140,13 +1147,43 @@ public class WolfSSLEngineHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private void setLocalMaximumPacketSize() {
|
||||
/* Set maximum packet size, currently only makes a differnce if
|
||||
* DTLS is enabled and used. Calling application will set this via
|
||||
* SSLParameters.setMaximumPacketSize(). */
|
||||
int ret;
|
||||
int maxPacketSize = this.params.getMaximumPacketSize();
|
||||
if (maxPacketSize != 0) {
|
||||
/* Zero size means use implicit sizing logic of implementation,
|
||||
* take no special action here if 0. */
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"Maximum packet size found in SSLParameters: " + maxPacketSize);
|
||||
|
||||
ret = this.ssl.dtlsSetMTU(maxPacketSize);
|
||||
if (ret == WolfSSL.SSL_SUCCESS) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"set maximum packet size (DTLS MTU): " + maxPacketSize);
|
||||
}
|
||||
else if (ret == WolfSSL.NOT_COMPILED_IN) {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"DTLS or MTU not compiled in, skipping setting " +
|
||||
"max packet size");
|
||||
}
|
||||
else {
|
||||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"error setting DTLS MTU, ret = " + ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setLocalParams(SSLSocket socket, SSLEngine engine)
|
||||
throws SSLException {
|
||||
|
||||
this.setLocalCiphers(
|
||||
WolfSSLUtil.sanitizeSuites(this.params.getCipherSuites()));
|
||||
this.setLocalProtocol(
|
||||
WolfSSLUtil.sanitizeProtocols(this.params.getProtocols()));
|
||||
WolfSSLUtil.sanitizeProtocols(
|
||||
this.params.getProtocols(), WolfSSL.TLS_VERSION.INVALID));
|
||||
this.setLocalAuth(socket, engine);
|
||||
this.setLocalServerNames();
|
||||
this.setLocalSessionTicket();
|
||||
|
|
@ -1154,6 +1191,7 @@ public class WolfSSLEngineHelper {
|
|||
this.setLocalSecureRenegotiation();
|
||||
this.setLocalSigAlgorithms();
|
||||
this.setLocalSupportedCurves();
|
||||
this.setLocalMaximumPacketSize();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -49,6 +49,8 @@ final class WolfSSLParameters {
|
|||
String[] applicationProtocols = new String[0];
|
||||
private boolean useSessionTickets = false;
|
||||
private byte[] alpnProtocols = null;
|
||||
/* Default to 0, means use implicit implementation size */
|
||||
private int maxPacketSize = 0;
|
||||
|
||||
/* create duplicate copy of these parameters */
|
||||
protected synchronized WolfSSLParameters copy() {
|
||||
|
|
@ -62,6 +64,7 @@ final class WolfSSLParameters {
|
|||
cp.endpointIdAlgorithm = this.endpointIdAlgorithm;
|
||||
cp.setApplicationProtocols(this.applicationProtocols);
|
||||
cp.useCipherSuiteOrder = this.useCipherSuiteOrder;
|
||||
cp.maxPacketSize = this.maxPacketSize;
|
||||
|
||||
if (alpnProtocols != null && alpnProtocols.length != 0) {
|
||||
cp.setAlpnProtocols(this.alpnProtocols);
|
||||
|
|
@ -213,5 +216,13 @@ final class WolfSSLParameters {
|
|||
this.applicationProtocols = protocols.clone();
|
||||
}
|
||||
}
|
||||
|
||||
int getMaximumPacketSize() {
|
||||
return this.maxPacketSize;
|
||||
}
|
||||
|
||||
void setMaximumPacketSize(int maximumPacketSize) {
|
||||
this.maxPacketSize = maximumPacketSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
package com.wolfssl.provider.jsse;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import javax.net.ssl.SSLParameters;
|
||||
|
|
@ -37,6 +38,8 @@ public class WolfSSLParametersHelper
|
|||
private static Method setApplicationProtocols = null;
|
||||
private static Method getEndpointIdentificationAlgorithm = null;
|
||||
private static Method setEndpointIdentificationAlgorithm = null;
|
||||
private static Method getMaximumPacketSize = null;
|
||||
private static Method setMaximumPacketSize = null;
|
||||
|
||||
/** Default WolfSSLParametersHelper constructor */
|
||||
public WolfSSLParametersHelper() { }
|
||||
|
|
@ -73,6 +76,12 @@ public class WolfSSLParametersHelper
|
|||
case "setEndpointIdentificationAlgorithm":
|
||||
setEndpointIdentificationAlgorithm = m;
|
||||
continue;
|
||||
case "getMaximumPacketSize":
|
||||
getMaximumPacketSize = m;
|
||||
continue;
|
||||
case "setMaximumPacketSize":
|
||||
setMaximumPacketSize = m;
|
||||
continue;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
|
@ -112,15 +121,17 @@ public class WolfSSLParametersHelper
|
|||
ret.setWantClientAuth(in.getWantClientAuth());
|
||||
}
|
||||
|
||||
/* Methods added as of JDK 1.8, older JDKs will not have them. Using
|
||||
* Java reflection to detect availability. */
|
||||
|
||||
/* Methods added as of JDK 1.8 that rely on specific classes that
|
||||
* do not existing in older JDKs. Since older JDKs will not have them,
|
||||
* use Java reflection to detect availability in helper class. */
|
||||
if (setServerNames != null || setApplicationProtocols != null ||
|
||||
setEndpointIdentificationAlgorithm != null) {
|
||||
|
||||
try {
|
||||
/* load WolfSSLJDK8Helper at runtime, not compiled on older JDKs */
|
||||
Class<?> cls = Class.forName("com.wolfssl.provider.jsse.WolfSSLJDK8Helper");
|
||||
/* load WolfSSLJDK8Helper at runtime, not compiled
|
||||
* on older JDKs */
|
||||
Class<?> cls = Class.forName(
|
||||
"com.wolfssl.provider.jsse.WolfSSLJDK8Helper");
|
||||
Object obj = cls.getConstructor().newInstance();
|
||||
Class<?>[] paramList = new Class<?>[3];
|
||||
paramList[0] = javax.net.ssl.SSLParameters.class;
|
||||
|
|
@ -133,12 +144,15 @@ public class WolfSSLParametersHelper
|
|||
mth.invoke(obj, ret, setServerNames, in);
|
||||
}
|
||||
if (setApplicationProtocols != null) {
|
||||
mth = cls.getDeclaredMethod("setApplicationProtocols", paramList);
|
||||
mth = cls.getDeclaredMethod(
|
||||
"setApplicationProtocols", paramList);
|
||||
mth.invoke(obj, ret, setApplicationProtocols, in);
|
||||
}
|
||||
if (setEndpointIdentificationAlgorithm != null) {
|
||||
mth = cls.getDeclaredMethod("setEndpointIdentificationAlgorithm", paramList);
|
||||
mth.invoke(obj, ret, setEndpointIdentificationAlgorithm, in);
|
||||
mth = cls.getDeclaredMethod(
|
||||
"setEndpointIdentificationAlgorithm", paramList);
|
||||
mth.invoke(obj, ret,
|
||||
setEndpointIdentificationAlgorithm, in);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
|
|
@ -146,6 +160,18 @@ public class WolfSSLParametersHelper
|
|||
}
|
||||
}
|
||||
|
||||
/* Methods added in later versions of SSLParameters which do not
|
||||
* use any additional classes. Since no unique class names, these
|
||||
* are called here directly instead of placed into a separate helper
|
||||
* class. */
|
||||
try {
|
||||
if (setMaximumPacketSize != null) {
|
||||
setMaximumPacketSize.invoke(ret, in.getMaximumPacketSize());
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
/* Not available, just ignore and continue */
|
||||
}
|
||||
|
||||
/* The following SSLParameters features are not yet supported
|
||||
* by wolfJSSE (see Android API 23 note above). They are supported
|
||||
* with newer versions of SSLParameters, but will need to be added
|
||||
|
|
@ -191,14 +217,15 @@ public class WolfSSLParametersHelper
|
|||
out.setWantClientAuth(in.getWantClientAuth());
|
||||
}
|
||||
|
||||
/* Methods added as of JDK 1.8, older JDKs will not have them. Using
|
||||
* Java reflection to detect availability. */
|
||||
|
||||
/* Methods added as of JDK 1.8 that rely on specific classes that
|
||||
* do not existing in older JDKs. Since older JDKs will not have them,
|
||||
* use Java reflection to detect availability in helper class. */
|
||||
if (getServerNames != null || getApplicationProtocols != null ||
|
||||
getEndpointIdentificationAlgorithm != null) {
|
||||
try {
|
||||
/* load WolfSSLJDK8Helper at runtime, not compiled on older JDKs */
|
||||
Class<?> cls = Class.forName("com.wolfssl.provider.jsse.WolfSSLJDK8Helper");
|
||||
Class<?> cls = Class.forName(
|
||||
"com.wolfssl.provider.jsse.WolfSSLJDK8Helper");
|
||||
Object obj = cls.getConstructor().newInstance();
|
||||
Class<?>[] paramList = new Class<?>[2];
|
||||
paramList[0] = javax.net.ssl.SSLParameters.class;
|
||||
|
|
@ -210,11 +237,13 @@ public class WolfSSLParametersHelper
|
|||
mth.invoke(obj, in, out);
|
||||
}
|
||||
if (getApplicationProtocols != null) {
|
||||
mth = cls.getDeclaredMethod("getApplicationProtocols", paramList);
|
||||
mth = cls.getDeclaredMethod(
|
||||
"getApplicationProtocols", paramList);
|
||||
mth.invoke(obj, in, out);
|
||||
}
|
||||
if (getEndpointIdentificationAlgorithm != null) {
|
||||
mth = cls.getDeclaredMethod("getEndpointIdentificationAlgorithm", paramList);
|
||||
mth = cls.getDeclaredMethod(
|
||||
"getEndpointIdentificationAlgorithm", paramList);
|
||||
mth.invoke(obj, in, out);
|
||||
}
|
||||
|
||||
|
|
@ -223,6 +252,19 @@ public class WolfSSLParametersHelper
|
|||
}
|
||||
}
|
||||
|
||||
/* Methods added in later versions of SSLParameters which do not
|
||||
* use any additional classes. Since no unique class names, these
|
||||
* are called here directly instead of placed into a separate helper
|
||||
* class. */
|
||||
try {
|
||||
if (getMaximumPacketSize != null) {
|
||||
int maxPacketSz = (int)getMaximumPacketSize.invoke(in);
|
||||
out.setMaximumPacketSize(maxPacketSz);
|
||||
}
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
/* Not available, just ignore and continue */
|
||||
}
|
||||
|
||||
/* The following SSLParameters features are not yet supported
|
||||
* by wolfJSSE (see Android API 23 note above). They are supported
|
||||
* with newer versions of SSLParameters, but will need to be added
|
||||
|
|
|
|||
|
|
@ -134,6 +134,10 @@ public final class WolfSSLProvider extends Provider {
|
|||
put("SSLContext.TLSv1.3",
|
||||
"com.wolfssl.provider.jsse.WolfSSLContext$TLSV13_Context");
|
||||
}
|
||||
if (WolfSSL.DTLSv13Enabled()) {
|
||||
put("SSLContext.DTLSv1.3",
|
||||
"com.wolfssl.provider.jsse.WolfSSLContext$DTLSV13_Context");
|
||||
}
|
||||
put("SSLContext.SSL",
|
||||
"com.wolfssl.provider.jsse.WolfSSLContext$TLSV23_Context");
|
||||
put("SSLContext.TLS",
|
||||
|
|
|
|||
|
|
@ -211,7 +211,8 @@ public class WolfSSLServerSocket extends SSLServerSocket {
|
|||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"entered getSupportedProtocols()");
|
||||
|
||||
return WolfSSLUtil.sanitizeProtocols(params.getProtocols());
|
||||
return WolfSSLUtil.sanitizeProtocols(
|
||||
params.getProtocols(), WolfSSL.TLS_VERSION.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -220,7 +221,8 @@ public class WolfSSLServerSocket extends SSLServerSocket {
|
|||
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
|
||||
"entered getEnabledProtocols()");
|
||||
|
||||
return WolfSSLUtil.sanitizeProtocols(params.getProtocols());
|
||||
return WolfSSLUtil.sanitizeProtocols(
|
||||
params.getProtocols(), WolfSSL.TLS_VERSION.INVALID);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -242,7 +244,8 @@ public class WolfSSLServerSocket extends SSLServerSocket {
|
|||
List<String> supported;
|
||||
|
||||
supported = Arrays.asList(
|
||||
WolfSSLUtil.sanitizeProtocols(WolfSSL.getProtocols()));
|
||||
WolfSSLUtil.sanitizeProtocols(
|
||||
WolfSSL.getProtocols(), WolfSSL.TLS_VERSION.INVALID));
|
||||
|
||||
for (int i = 0; i < protocols.length; i++) {
|
||||
if (!supported.contains(protocols[i])) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.security.KeyStoreException;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
import com.wolfssl.WolfSSL;
|
||||
import com.wolfssl.WolfSSLDebug;
|
||||
import com.wolfssl.WolfSSLException;
|
||||
|
||||
|
|
@ -50,7 +51,8 @@ public class WolfSSLUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* Sanitize or filter protocol list based on system property limitations.
|
||||
* Sanitize or filter protocol list based on system property limitations
|
||||
* and current TLS/DTLS protocol being established.
|
||||
*
|
||||
* Supported system properties which limit protocol list are:
|
||||
* - java.security.Security:
|
||||
|
|
@ -61,17 +63,18 @@ public class WolfSSLUtil {
|
|||
*
|
||||
* jdk.tls.disabledAlgorithms="TLSv1, TLSv1.1"
|
||||
*
|
||||
* This method force-removes DTLSv1.2 and DTLSv1.3 if the input
|
||||
* protocols list advertises support for it. This is because native
|
||||
* wolfSSL JNI supports DTLS but the JSSE layer does not yet. When
|
||||
* DTLS support is added to wolfJSSE, this restriction can/will be removed.
|
||||
*
|
||||
* @param protocols Full list of protocols to sanitize/filter, should be
|
||||
* in a format similar to: "TLSv1", "TLSv1.1", etc.
|
||||
* @param currentVersion current protocol being used by the object
|
||||
* that is calling this method. If WolfSSL.INVALID
|
||||
* is passed in, no filtering is done on protocol
|
||||
* list based on currentVersion.
|
||||
*
|
||||
* @return New filtered String array of protocol strings
|
||||
*/
|
||||
protected static String[] sanitizeProtocols(String[] protocols) {
|
||||
protected static String[] sanitizeProtocols(String[] protocols,
|
||||
WolfSSL.TLS_VERSION currentVersion) {
|
||||
|
||||
ArrayList<String> filtered = new ArrayList<String>();
|
||||
|
||||
String disabledAlgos =
|
||||
|
|
@ -83,14 +86,17 @@ public class WolfSSLUtil {
|
|||
WolfSSLDebug.log(WolfSSLUtil.class, WolfSSLDebug.INFO,
|
||||
"jdk.tls.disabledAlgorithms: " + disabledAlgos);
|
||||
|
||||
/* Force remove DTLS from supported JSSE protocols. Currently only
|
||||
* JNI layer supports DTLS, not JSSE. When JSSE layer gets DTLS
|
||||
* support added, take this restriction out. */
|
||||
if (disabledAlgos == null) {
|
||||
disabledAlgos = "DTLSv1.2, DTLSv1.3";
|
||||
}
|
||||
else {
|
||||
disabledAlgos += ",DTLSv1.2,DTLSv1.3";
|
||||
/* If WolfSSL.INVALID is passed in as currentVersion, no filtering
|
||||
* is done based on current protocol */
|
||||
if (currentVersion != WolfSSL.TLS_VERSION.INVALID) {
|
||||
/* Remove DTLS protocols if using TLS explicitly. Needed
|
||||
* since native wolfSSL doesn't have protocol masks for DTLS. */
|
||||
if (currentVersion != WolfSSL.TLS_VERSION.DTLSv1_2) {
|
||||
disabledAlgos += ",DTLSv1.2";
|
||||
}
|
||||
if (currentVersion != WolfSSL.TLS_VERSION.DTLSv1_3) {
|
||||
disabledAlgos += ",DTLSv1.3";
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove spaces after commas, split into List */
|
||||
|
|
|
|||
|
|
@ -1212,6 +1212,7 @@ public class WolfSSLEngineTest {
|
|||
ByteBuffer netData = null;
|
||||
ByteBuffer peerAppData = null;
|
||||
ByteBuffer peerNetData = null;
|
||||
boolean readAgain = false;
|
||||
|
||||
SocketChannel sock = null;
|
||||
|
||||
|
|
@ -1350,7 +1351,7 @@ public class WolfSSLEngineTest {
|
|||
}
|
||||
}
|
||||
|
||||
/* read response */
|
||||
/* read response (might get TLS 1.3 session ticket instead) */
|
||||
peerNetData.clear();
|
||||
int recvd = sock.read(peerNetData);
|
||||
if (recvd > 0) {
|
||||
|
|
@ -1370,14 +1371,55 @@ public class WolfSSLEngineTest {
|
|||
throw new Exception(
|
||||
"BUFFER_OVERFLOW during engine.unwrp()");
|
||||
case BUFFER_UNDERFLOW:
|
||||
throw new Exception(
|
||||
"BUFFER_UNDERFLOW during engine.unwrap()");
|
||||
/* With TLS 1.3, we may get a session ticket
|
||||
* message post handshake, resulting in BUFFER_UNDERFLOW
|
||||
* status since we read the ticket but didn't get the
|
||||
* chance to read the response waiting from the peer. */
|
||||
sess = engine.getSession();
|
||||
if (sess.getProtocol().equals("TLSv1.3")) {
|
||||
readAgain = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
throw new Exception(
|
||||
"BUFFER_UNDERFLOW during engine.unwrap()");
|
||||
}
|
||||
default:
|
||||
throw new Exception(
|
||||
"Unknown HandshakeStatus");
|
||||
}
|
||||
}
|
||||
|
||||
if (readAgain) {
|
||||
/* read response */
|
||||
peerNetData.clear();
|
||||
recvd = sock.read(peerNetData);
|
||||
if (recvd > 0) {
|
||||
peerNetData.flip();
|
||||
result = engine.unwrap(peerNetData, peerAppData);
|
||||
peerNetData.compact();
|
||||
switch (result.getStatus()) {
|
||||
case OK:
|
||||
peerAppData.flip();
|
||||
/* not doing anything with returned data */
|
||||
break;
|
||||
case CLOSED:
|
||||
engine.closeOutbound();
|
||||
engine.closeInbound();
|
||||
break;
|
||||
case BUFFER_OVERFLOW:
|
||||
throw new Exception(
|
||||
"BUFFER_OVERFLOW during engine.unwrp()");
|
||||
case BUFFER_UNDERFLOW:
|
||||
throw new Exception(
|
||||
"BUFFER_UNDERFLOW during engine.unwrap()");
|
||||
default:
|
||||
throw new Exception(
|
||||
"Unknown HandshakeStatus");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* shutdown */
|
||||
engine.closeOutbound();
|
||||
while (engine.isOutboundDone() == false) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue