diff --git a/build.xml b/build.xml index 6973311..fcee195 100644 --- a/build.xml +++ b/build.xml @@ -30,6 +30,10 @@ + + + + @@ -88,8 +92,7 @@ - + + + + + - + + + + + @@ -157,7 +169,13 @@ - + + + + + + + diff --git a/native/com_wolfssl_WolfSSL.h b/native/com_wolfssl_WolfSSL.h index 93fb733..26ee676 100644 --- a/native/com_wolfssl_WolfSSL.h +++ b/native/com_wolfssl_WolfSSL.h @@ -697,11 +697,11 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocols /* * Class: com_wolfssl_WolfSSL - * Method: getProtocols - * Signature: ()[Ljava/lang/String; + * Method: getProtocolsMask + * Signature: (J)[Ljava/lang/String; */ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocolsMask - (JNIEnv*, jclass, jlong); + (JNIEnv *, jclass, jlong); #ifdef __cplusplus } diff --git a/native/com_wolfssl_WolfSSLCertificate.c b/native/com_wolfssl_WolfSSLCertificate.c index 51e617e..c5cc408 100644 --- a/native/com_wolfssl_WolfSSLCertificate.c +++ b/native/com_wolfssl_WolfSSLCertificate.c @@ -603,7 +603,11 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1verify int sz = (int)pubKeySz; int ret; unsigned char buff[sz]; +#if LIBWOLFSSL_VERSION_HEX >= 0x04004000 + const unsigned char* ptr = buff; +#else unsigned char* ptr = buff; +#endif (void)jcl; diff --git a/native/com_wolfssl_WolfSSLContext.h b/native/com_wolfssl_WolfSSLContext.h index 6d416fa..d21e0ac 100644 --- a/native/com_wolfssl_WolfSSLContext.h +++ b/native/com_wolfssl_WolfSSLContext.h @@ -73,8 +73,8 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLContext_setOptions /* * Class: com_wolfssl_WolfSSLContext - * Method: setOptions - * Signature: (JJ)J + * Method: getOptions + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLContext_getOptions (JNIEnv *, jobject, jlong); diff --git a/native/com_wolfssl_WolfSSLSession.c b/native/com_wolfssl_WolfSSLSession.c index ebcd8d0..6abad2b 100644 --- a/native/com_wolfssl_WolfSSLSession.c +++ b/native/com_wolfssl_WolfSSLSession.c @@ -2934,6 +2934,41 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getShutdown return (jint)wolfSSL_get_shutdown((WOLFSSL*)(uintptr_t)ssl); } +JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSNI + (JNIEnv* jenv, jobject jcl, jlong ssl, jbyte type, jbyteArray data) +{ + int ret = SSL_FAILURE; + (void)jcl; +#ifdef HAVE_SNI + byte* dataBuf = NULL; + word32 dataSz = 0; + + if (jenv == NULL || ssl <= 0) { + return BAD_FUNC_ARG; + } + + dataBuf = (byte*)(*jenv)->GetByteArrayElements(jenv, data, NULL); + dataSz = (*jenv)->GetArrayLength(jenv, data); + + if (dataBuf != NULL && dataSz > 0) { + ret = wolfSSL_UseSNI((WOLFSSL*)(uintptr_t)ssl, (byte)type, + dataBuf, (word16)dataSz); + } + + (*jenv)->ReleaseByteArrayElements(jenv, data, (jbyte*)dataBuf, JNI_ABORT); + +#else + ret = NOT_COMPILED_IN; + (void)jenv; + (void)ssl; + (void)type; + (void)data; +#endif /* HAVE_SNI */ + + return (jint)ret; + +} + JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIORecv (JNIEnv* jenv, jobject jcl, jlong ssl) { diff --git a/native/com_wolfssl_WolfSSLSession.h b/native/com_wolfssl_WolfSSLSession.h index 3a55a8f..a8e7f75 100644 --- a/native/com_wolfssl_WolfSSLSession.h +++ b/native/com_wolfssl_WolfSSLSession.h @@ -650,7 +650,7 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_setOptions /* * Class: com_wolfssl_WolfSSLSession * Method: getOptions - * Signature: (JJ)J + * Signature: (J)J */ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_getOptions (JNIEnv *, jobject, jlong); @@ -679,6 +679,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIORecv JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIOSend (JNIEnv *, jobject, jlong); +/* + * Class: com_wolfssl_WolfSSLSession + * Method: useSNI + * Signature: (JB[B)I + */ +JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_useSNI + (JNIEnv *, jobject, jlong, jbyte, jbyteArray); + #ifdef __cplusplus } #endif diff --git a/platform/android_aosp/wolfssl/Android.mk b/platform/android_aosp/wolfssl/Android.mk index 49ad0ec..3e24f71 100644 --- a/platform/android_aosp/wolfssl/Android.mk +++ b/platform/android_aosp/wolfssl/Android.mk @@ -4,7 +4,7 @@ include $(CLEAR_VARS) LOCAL_MODULE:= libwolfssl LOCAL_MODULE_TAGS := optional LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) -LOCAL_CFLAGS:= -DHAVE_FFDHE_2048 -DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DWC_RSA_BLINDING -DHAVE_AESGCM -DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DHAVE_HKDF -DNO_DSA -DHAVE_ECC -DTFM_ECC256 -DECC_SHAMIR -DWC_RSA_PSS -DWOLFSSL_BASE64_ENCODE -DNO_RC4 -DNO_HC128 -DNO_RABBIT -DWOLFSSL_SHA224 -DWOLFSSL_SHA3 -DHAVE_POLY1305 -DHAVE_ONE_TIME_AUTH -DHAVE_CHACHA -DHAVE_HASHDRBG -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DHAVE_EXTENDED_MASTER -DWOLFSSL_JNI -DWOLFSSL_DTLS -DOPENSSL_EXTRA -DHAVE_CRL -DHAVE_OCSP -DHAVE_CRL_MONITOR -DPERSIST_SESSION_CACHE -DPERSIST_CERT_CACHE -DATOMIC_USER -DHAVE_PK_CALLBACKS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN -DHAVE_ENCRYPT_THEN_MAC -DNO_MD4 -DWOLFSSL_ENCRYPTED_KEYS -DUSE_FAST_MATH -DNO_DES3 -DKEEP_PEER_CERT -Os -fomit-frame-pointer +LOCAL_CFLAGS:= -DHAVE_FFDHE_2048 -DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DWC_RSA_BLINDING -DHAVE_AESGCM -DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DHAVE_HKDF -DNO_DSA -DHAVE_ECC -DTFM_ECC256 -DECC_SHAMIR -DWC_RSA_PSS -DWOLFSSL_BASE64_ENCODE -DNO_RC4 -DNO_HC128 -DNO_RABBIT -DWOLFSSL_SHA224 -DWOLFSSL_SHA3 -DHAVE_POLY1305 -DHAVE_ONE_TIME_AUTH -DHAVE_CHACHA -DHAVE_HASHDRBG -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DHAVE_EXTENDED_MASTER -DHAVE_SNI -DWOLFSSL_JNI -DWOLFSSL_DTLS -DOPENSSL_EXTRA -DHAVE_CRL -DHAVE_OCSP -DHAVE_CRL_MONITOR -DPERSIST_SESSION_CACHE -DPERSIST_CERT_CACHE -DATOMIC_USER -DHAVE_PK_CALLBACKS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN -DHAVE_ENCRYPT_THEN_MAC -DNO_MD4 -DWOLFSSL_ENCRYPTED_KEYS -DUSE_FAST_MATH -DNO_DES3 -DKEEP_PEER_CERT -Os -fomit-frame-pointer LOCAL_C_INCLUDES += \ external/wolfssl/wolfssl \ external/wolfssl \ diff --git a/platform/android_aosp/wolfssljni/Android.mk b/platform/android_aosp/wolfssljni/Android.mk index 29522c8..5d2db13 100644 --- a/platform/android_aosp/wolfssljni/Android.mk +++ b/platform/android_aosp/wolfssljni/Android.mk @@ -8,7 +8,17 @@ native_cflags := -Wall # Create the wolfSSL JNI library include $(CLEAR_VARS) + +# Source file list to compile, exclude WolfSSLJDK8Helper on older Android +# versions (ex: 23) that do not have newer SSLParameters methods (i.e. SNI) +LOCAL_SRC_EXCLUDES := +ifeq ($(PLATFORM_VERSION),6.0.1) + LOCAL_SRC_EXCLUDES := \ + src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java +endif LOCAL_SRC_FILES := $(call all-java-files-under,src/java) +LOCAL_SRC_FILES := $(filter-out $(LOCAL_SRC_EXCLUDES), $(LOCAL_SRC_FILES)) + LOCAL_JAVACFLAGS := $(javac_flags) LOCAL_MODULE_TAGS := optional LOCAL_MODULE := wolfssljni @@ -20,7 +30,7 @@ include $(BUILD_JAVA_LIBRARY) # Create wolfSSL JNI native library include $(CLEAR_VARS) LOCAL_CFLAGS += $(native_cflags) -LOCAL_CFLAGS:= -DHAVE_FFDHE_2048 -DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DWC_RSA_BLINDING -DHAVE_AESGCM -DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DHAVE_HKDF -DNO_DSA -DHAVE_ECC -DTFM_ECC256 -DECC_SHAMIR -DWC_RSA_PSS -DWOLFSSL_BASE64_ENCODE -DNO_RC4 -DNO_HC128 -DNO_RABBIT -DWOLFSSL_SHA224 -DWOLFSSL_SHA3 -DHAVE_POLY1305 -DHAVE_ONE_TIME_AUTH -DHAVE_CHACHA -DHAVE_HASHDRBG -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DHAVE_EXTENDED_MASTER -DWOLFSSL_JNI -DWOLFSSL_DTLS -DOPENSSL_EXTRA -DHAVE_CRL -DHAVE_OCSP -DHAVE_CRL_MONITOR -DPERSIST_SESSION_CACHE -DPERSIST_CERT_CACHE -DATOMIC_USER -DHAVE_PK_CALLBACKS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN -DHAVE_ENCRYPT_THEN_MAC -DNO_MD4 -DWOLFSSL_ENCRYPTED_KEYS -DUSE_FAST_MATH -DNO_DES3 -DKEEP_PEER_CERT -Os -fomit-frame-pointer +LOCAL_CFLAGS:= -DHAVE_FFDHE_2048 -DWOLFSSL_TLS13 -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DTFM_TIMING_RESISTANT -DECC_TIMING_RESISTANT -DWC_RSA_BLINDING -DHAVE_AESGCM -DWOLFSSL_SHA512 -DWOLFSSL_SHA384 -DHAVE_HKDF -DNO_DSA -DHAVE_ECC -DTFM_ECC256 -DECC_SHAMIR -DWC_RSA_PSS -DWOLFSSL_BASE64_ENCODE -DNO_RC4 -DNO_HC128 -DNO_RABBIT -DWOLFSSL_SHA224 -DWOLFSSL_SHA3 -DHAVE_POLY1305 -DHAVE_ONE_TIME_AUTH -DHAVE_CHACHA -DHAVE_HASHDRBG -DHAVE_TLS_EXTENSIONS -DHAVE_SUPPORTED_CURVES -DHAVE_EXTENDED_MASTER -DHAVE_SNI -DWOLFSSL_JNI -DWOLFSSL_DTLS -DOPENSSL_EXTRA -DHAVE_CRL -DHAVE_OCSP -DHAVE_CRL_MONITOR -DPERSIST_SESSION_CACHE -DPERSIST_CERT_CACHE -DATOMIC_USER -DHAVE_PK_CALLBACKS -DWOLFSSL_CERT_EXT -DWOLFSSL_CERT_GEN -DHAVE_ENCRYPT_THEN_MAC -DNO_MD4 -DWOLFSSL_ENCRYPTED_KEYS -DUSE_FAST_MATH -DNO_DES3 -DKEEP_PEER_CERT -Os -fomit-frame-pointer LOCAL_SRC_FILES := \ native/com_wolfssl_wolfcrypt_ECC.c \ native/com_wolfssl_wolfcrypt_EccKey.c \ diff --git a/src/java/com/wolfssl/WolfSSLSession.java b/src/java/com/wolfssl/WolfSSLSession.java index b923f8e..d0388b9 100644 --- a/src/java/com/wolfssl/WolfSSLSession.java +++ b/src/java/com/wolfssl/WolfSSLSession.java @@ -264,6 +264,7 @@ public class WolfSSLSession { private native int getShutdown(long ssl); private native void setSSLIORecv(long ssl); private native void setSSLIOSend(long ssl); + private native int useSNI(long ssl, byte type, byte[] data); /* ------------------- session-specific methods --------------------- */ @@ -2425,6 +2426,18 @@ public class WolfSSLSession { setSSLIOSend(getSessionPtr()); } + public int useSNI(byte type, byte[] data) throws IllegalStateException { + + int ret; + + if (this.active == false) + throw new IllegalStateException("Object has been freed"); + + ret = useSNI(getSessionPtr(), type, data); + + return ret; + } + /** * Getter function to tell if shutdown has been sent or received * @return WolfSSL.SSL_SENT_SHUTDOWN or WolfSSL.SSL_RECEIVED_SHUTDOWN diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLContext.java b/src/java/com/wolfssl/provider/jsse/WolfSSLContext.java index cb3df9c..8a4ba54 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLContext.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLContext.java @@ -56,7 +56,7 @@ public class WolfSSLContext extends SSLContextSpi { private TLS_VERSION currentVersion = TLS_VERSION.SSLv23; private WolfSSLAuthStore authStore = null; private com.wolfssl.WolfSSLContext ctx = null; - private SSLParameters params = null; + private WolfSSLParameters params = null; private WolfSSLContext(TLS_VERSION version) { this.currentVersion = version; @@ -302,7 +302,7 @@ public class WolfSSLContext extends SSLContextSpi { try { authStore = new WolfSSLAuthStore(km, tm, sr, currentVersion); - params = new SSLParameters(); + params = new WolfSSLParameters(); createCtx(); } catch (IllegalArgumentException iae) { @@ -423,7 +423,7 @@ public class WolfSSLContext extends SSLContextSpi { */ @Override protected SSLParameters engineGetDefaultSSLParameters() { - return WolfSSLEngineHelper.decoupleParams(this.params); + return WolfSSLParametersHelper.decoupleParams(this.params); } /** @@ -432,7 +432,7 @@ public class WolfSSLContext extends SSLContextSpi { */ @Override protected SSLParameters engineGetSupportedSSLParameters() { - return WolfSSLEngineHelper.decoupleParams(this.params); + return WolfSSLParametersHelper.decoupleParams(this.params); } /* used internally by SSLSocketFactory() */ @@ -441,7 +441,7 @@ public class WolfSSLContext extends SSLContextSpi { } /* used internally by SSLSocketFactory() */ - protected SSLParameters getInternalSSLParams() { + protected WolfSSLParameters getInternalSSLParams() { return this.params; } @@ -458,7 +458,7 @@ public class WolfSSLContext extends SSLContextSpi { } super.finalize(); } - + public String[] getProtocolsMask(long noOpt) { if(ctx != null) ctx.setOptions(noOpt); diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java index 218a6bf..1887b74 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java @@ -35,8 +35,8 @@ import javax.net.ssl.SSLEngineResult; import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.Status; import javax.net.ssl.SSLException; -import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLParameters; /** * wolfSSL implementation of SSLEngine @@ -49,7 +49,7 @@ public class WolfSSLEngine extends SSLEngine { private WolfSSLSession ssl; private com.wolfssl.WolfSSLContext ctx; private WolfSSLAuthStore authStore; - private SSLParameters params; + private WolfSSLParameters params; private byte[] toSend; /* encrypted packet to send */ private byte[] toRead; /* encrypted packet coming in */ private int toReadSz = 0; @@ -74,12 +74,12 @@ public class WolfSSLEngine extends SSLEngine { * @throws WolfSSLException if there is an issue creating the engine */ protected WolfSSLEngine(com.wolfssl.WolfSSLContext ctx, - WolfSSLAuthStore auth, SSLParameters params) + WolfSSLAuthStore auth, WolfSSLParameters params) throws WolfSSLException { super(); this.ctx = ctx; this.authStore = auth; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); } catch (WolfSSLJNIException ex) { @@ -102,12 +102,12 @@ public class WolfSSLEngine extends SSLEngine { * @throws WolfSSLException if there is an issue creating the engine */ protected WolfSSLEngine(com.wolfssl.WolfSSLContext ctx, - WolfSSLAuthStore auth, SSLParameters params, String host, + WolfSSLAuthStore auth, WolfSSLParameters params, String host, int port) throws WolfSSLException { super(); this.ctx = ctx; this.authStore = auth; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); } catch (WolfSSLJNIException ex) { @@ -520,6 +520,17 @@ public class WolfSSLEngine extends SSLEngine { return EngineHelper.getEnableSessionCreation(); } + /** + * Set the SSLParameters for this SSLSocket. + * + * @param params SSLParameters to set for this SSLSocket object + */ + synchronized public void setSSLParameters(SSLParameters params) { + if (params != null) { + WolfSSLParametersHelper.importParams(params, this.params); + } + } + /* encrypted packet ready to be sent out. Copies buffer to end of to send * queue */ protected int setOut(byte[] in, int sz) { diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java index 8dea657..1c8ac35 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java @@ -48,7 +48,7 @@ import java.io.IOException; public class WolfSSLEngineHelper { private final WolfSSLSession ssl; private WolfSSLImplementSSLSession session = null; - private SSLParameters params; + private WolfSSLParameters params; private WolfSSLDebug debug; private int port; private String host = null; @@ -65,7 +65,7 @@ public class WolfSSLEngineHelper { * @throws WolfSSLException if an exception happens during session creation */ protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store, - SSLParameters params) throws WolfSSLException { + WolfSSLParameters params) throws WolfSSLException { if (params == null || ssl == null || store == null) { throw new WolfSSLException("Bad argument"); } @@ -86,7 +86,7 @@ public class WolfSSLEngineHelper { * @throws WolfSSLException if an exception happens during session resume */ protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store, - SSLParameters params, int port, String host) + WolfSSLParameters params, int port, String host) throws WolfSSLException { if (params == null || ssl == null || store == null) { throw new WolfSSLException("Bad argument"); @@ -334,14 +334,29 @@ public class WolfSSLEngineHelper { } } + /* sets SNI server names, if set by application in SSLParameters */ + private void setLocalServerNames() { + if (this.clientMode) { + List names = this.params.getServerNames(); + if (names != null && names.size() > 0) { + /* should only be one server name */ + WolfSSLSNIServerName sni = names.get(0); + if (sni != null) { + this.ssl.useSNI((byte)sni.getType(), sni.getEncoded()); + } + } + } + } + private void setLocalParams() { this.setLocalCiphers(this.params.getCipherSuites()); this.setLocalProtocol(this.params.getProtocols()); this.setLocalAuth(); + this.setLocalServerNames(); } - /* sets all parameters from SSLParameters into WOLFSSL object and creates - * session. + /* sets all parameters from WolfSSLParameters into WOLFSSL object and + * creates session. * Should be called before doHandshake */ protected void initHandshake() throws SSLException { if (!modeSet) { @@ -418,7 +433,6 @@ public class WolfSSLEngineHelper { } } - /** * Saves session on connection close for resumption */ @@ -428,40 +442,6 @@ public class WolfSSLEngineHelper { } } - /** - * Creates a new SSLPArameters class with the same settings as the one - * passed in. - * - * @param in SSLParameters settings to copy - * @return new parameters object holding same settings as "in" - */ - protected static SSLParameters decoupleParams(SSLParameters in) { - SSLParameters ret = new SSLParameters(); - - ret.setCipherSuites(in.getCipherSuites()); - ret.setProtocols(in.getProtocols()); - - ret.setNeedClientAuth(in.getNeedClientAuth()); - if (!ret.getNeedClientAuth()) { - ret.setWantClientAuth(in.getWantClientAuth()); - } - - /* Supported by newer version of SSLParameters but to build with API 23 - * these are currently commented out - ret.setAlgorithmConstraints(in.getAlgorithmConstraints()); - ret.setApplicationProtocols(in.getApplicationProtocols()); - ret.setEnableRetransmissions(in.getEnableRetransmissions()); - ret.setEndpointIdentificationAlgorithm( - in.getEndpointIdentificationAlgorithm()); - ret.setMaximumPacketSize(in.getMaximumPacketSize()); - ret.setSNIMatchers(in.getSNIMatchers()); - ret.setServerNames(in.getServerNames()); - ret.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder()); - */ - - return ret; - } - /* Internal verify callback. This is used when a user registers a * TrustManager which is NOT com.wolfssl.provider.jsse.WolfSSLTrustManager * and is used to call TrustManager checkClientTrusted() or diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLGenericHostName.java b/src/java/com/wolfssl/provider/jsse/WolfSSLGenericHostName.java new file mode 100644 index 0000000..1b9ae8c --- /dev/null +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLGenericHostName.java @@ -0,0 +1,33 @@ +/* WolfSSLGenericHostName.java + * + * Copyright (C) 2006-2020 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-1301, USA + */ +package com.wolfssl.provider.jsse; + +/** + * Concrete class representing a generic host name, used with SNI and + * WolfSSLSNIServerName usage areas. + */ +public class WolfSSLGenericHostName extends WolfSSLSNIServerName +{ + WolfSSLGenericHostName(int type, byte[] encoded) { + super(type, encoded); + } +} + diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLParameters.java b/src/java/com/wolfssl/provider/jsse/WolfSSLParameters.java new file mode 100644 index 0000000..b9a52bd --- /dev/null +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLParameters.java @@ -0,0 +1,156 @@ +/* WolfSSLParameters.java + * + * Copyright (C) 2006-2020 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-1301, USA + */ +package com.wolfssl.provider.jsse; + +import java.util.List; +import java.util.ArrayList; +import java.util.Collections; + +/** + * wolfJSSE implementation of SSLParameters + * + * This class includes the functionality of java SSLParameters, but allows + * wolfJSSE better control over settings, interop with older Java versions, + * etc. Strings set and returned should be cloned. + * + * This class is used internally to wolfJSSE. When a SSLParameters needs to + * be returned to an application (ex: SSLContext.getDefaultSSLParameters(), + * SSLContext.getSupportedSSLParameters()) wolfJSSE calls + * WolfSSLEngineHelper.decoupleParams() which creates a SSLParameters object + * from a WolfSSLParameters. + */ +final class WolfSSLParameters { + + private String[] cipherSuites; + private String[] protocols; + private boolean wantClientAuth = false; + private boolean needClientAuth = false; + private String endpointIdAlgorithm; + private List serverNames; + private boolean useCipherSuiteOrder = true; + String[] applicationProtocols = new String[0]; + + /* create duplicate copy of these parameters */ + protected WolfSSLParameters copy() { + WolfSSLParameters cp = new WolfSSLParameters(); + cp.setCipherSuites(this.cipherSuites); + cp.setProtocols(this.protocols); + cp.wantClientAuth = this.wantClientAuth; + cp.needClientAuth = this.needClientAuth; + cp.setServerNames(this.getServerNames()); + + /* TODO: duplicate other properties here when WolfSSLParameters + * can handle them */ + + return cp; + } + + String[] getCipherSuites() { + return this.cipherSuites.clone(); + } + + void setCipherSuites(String[] cipherSuites) { + /* cipherSuites array is sanitized by wolfJSSE caller */ + this.cipherSuites = cipherSuites.clone(); + } + + String[] getProtocols() { + return this.protocols.clone(); + } + + void setProtocols(String[] protocols) { + /* protocols array is sanitized by wolfJSSE caller */ + this.protocols = protocols.clone(); + } + + boolean getWantClientAuth() { + return this.wantClientAuth; + } + + void setWantClientAuth(boolean wantClientAuth) { + /* wantClientAuth OR needClientAuth can be set, not both */ + this.wantClientAuth = wantClientAuth; + this.needClientAuth = false; + } + + boolean getNeedClientAuth() { + return this.needClientAuth; + } + + void setNeedClientAuth(boolean needClientAuth) { + /* wantClientAuth OR needClientAuth can be set, not both */ + this.needClientAuth = needClientAuth; + this.wantClientAuth = false; + } + + String getEndpointIdentificationAlgorithm() { + return this.endpointIdAlgorithm; + } + + void setEndPointIdentificationAlgorithm(String algorithm) { + this.endpointIdAlgorithm = algorithm; + } + + void setServerNames(List serverNames) { + if (serverNames == null) { + this.serverNames = null; + } else { + this.serverNames = Collections.unmodifiableList( + new ArrayList(serverNames)); + } + } + + List getServerNames() { + if (this.serverNames == null) { + return null; + } else { + return Collections.unmodifiableList( + new ArrayList(this.serverNames)); + } + } + + /* TODO, create our own class for SNIMatcher, in case Java doesn't support it */ + //void setSNIMatchers(Collection matchers) { + // /* TODO */ + //} + + /* TODO, create our own class for SNIMatcher, in case Java doesn't support it */ + //Collection getSNIMatchers() { + // return null; /* TODO */ + //} + + void setUseCipherSuitesOrder(boolean honorOrder) { + this.useCipherSuiteOrder = honorOrder; + } + + boolean getUseCipherSuitesOrder() { + return this.useCipherSuiteOrder; + } + + String[] getApplicationProtocols() { + return this.applicationProtocols.clone(); + } + + void setApplicationProtocols(String[] protocols) { + this.applicationProtocols = protocols.clone(); + } +} + diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLParametersHelper.java b/src/java/com/wolfssl/provider/jsse/WolfSSLParametersHelper.java new file mode 100644 index 0000000..b078372 --- /dev/null +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLParametersHelper.java @@ -0,0 +1,198 @@ +/* WolfSSLEngineHelper.java + * + * Copyright (C) 2006-2020 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-1301, USA + */ +package com.wolfssl.provider.jsse; + +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import javax.net.ssl.SSLParameters; + +public class WolfSSLParametersHelper +{ + private static Method getServerNames = null; + private static Method setServerNames = null; + + /* Runs upon class initialization to detect if this version of Java + * has SSLParameters methods that older versions may not have */ + static + { + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + Class c = SSLParameters.class; + Method[] methods = c.getDeclaredMethods(); + if (methods == null) { + return null; + } + + /* check for availability of methods */ + try { + for (Method m : methods) { + switch (m.getName()) { + case "getServerNames": + getServerNames = m; + continue; + case "setServerNames": + setServerNames = m; + continue; + default: + continue; + } + } + } catch (Exception e) { + } + + return null; + } + }); + } + + /** + * Creates a new SSLParameters class with the same settings as the + * WolfSSLParameters passed in. + * + * @param in WolfSSLParameters to convert to SSLParameters + * @return new SSLParameters object representing same settings as "in" + */ + protected static SSLParameters decoupleParams(WolfSSLParameters in) { + + /* Note: Android API 23 only supports the following SSLParameters + * methods. All newer methods we will need to conditionally + * support: + * get/setCipherSuites() + * get/setCipherSuites() + * get/setNeedClientAuth() + * get/setWantClientAuth() + */ + + SSLParameters ret = new SSLParameters(in.getCipherSuites(), + in.getProtocols()); + + ret.setNeedClientAuth(in.getNeedClientAuth()); + if (!ret.getNeedClientAuth()) { + ret.setWantClientAuth(in.getWantClientAuth()); + } + + /* Methods added as of JDK 1.8, older JDKs will not have them. Using + * Java reflection to detect availability. */ + + if (setServerNames != null) { + + try { + /* load WolfSSLJDK8Helper at runtime, not compiled on older JDKs */ + Class cls = Class.forName("com.wolfssl.provider.jsse.WolfSSLJDK8Helper"); + Object obj = cls.newInstance(); + Class[] paramList = new Class[3]; + paramList[0] = javax.net.ssl.SSLParameters.class; + paramList[1] = java.lang.reflect.Method.class; + paramList[2] = com.wolfssl.provider.jsse.WolfSSLParameters.class; + + Method mth = cls.getDeclaredMethod("setServerNames", paramList); + mth.invoke(obj, ret, setServerNames, in); + + } catch (Exception e) { + /* ignore, class not found */ + } + } + + /* 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 + * conditionally to wolfJSSE when supported. */ + /*ret.setAlgorithmConstraints(in.getAlgorithmConstraints()); + ret.setApplicationProtocols(in.getApplicationProtocols()); + ret.setEnableRetransmissions(in.getEnableRetransmissions()); + ret.setEndpointIdentificationAlgorithm( + in.getEndpointIdentificationAlgorithm()); + ret.setMaximumPacketSize(in.getMaximumPacketSize()); + ret.setSNIMatchers(in.getSNIMatchers()); + ret.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder()); + */ + + return ret; + } + + /** + * Import SSLParameters into an existing WolfSSLParameters object. Used + * internally by SSLSocket.setSSLParameters(). + * + * @param in SSLParameters to import settings from + * @param out WolfSSLParameters to copy settings into + */ + protected static void importParams(SSLParameters in, + WolfSSLParameters out) { + + if (in == null || out == null) { + throw new NullPointerException("input parameters cannot be " + + "null to WolfSSLParametersHelper.importParams()"); + } + + /* Note: Android API 23 only supports the following SSLParameters + * methods. All newer methods we will need to conditionally + * support: + * get/setCipherSuites() + * get/setCipherSuites() + * get/setNeedClientAuth() + * get/setWantClientAuth() + */ + + out.setCipherSuites(in.getCipherSuites()); + out.setProtocols(in.getProtocols()); + out.setNeedClientAuth(in.getNeedClientAuth()); + if (!out.getNeedClientAuth()) { + out.setWantClientAuth(in.getWantClientAuth()); + } + + /* Methods added as of JDK 1.8, older JDKs will not have them. Using + * Java reflection to detect availability. */ + + if (getServerNames != null) { + try { + /* load WolfSSLJDK8Helper at runtime, not compiled on older JDKs */ + Class cls = Class.forName("com.wolfssl.provider.jsse.WolfSSLJDK8Helper"); + Object obj = cls.newInstance(); + Class[] paramList = new Class[2]; + paramList[0] = javax.net.ssl.SSLParameters.class; + paramList[1] = com.wolfssl.provider.jsse.WolfSSLParameters.class; + + Method mth = cls.getDeclaredMethod("getServerNames", paramList); + mth.invoke(obj, in, out); + + } catch (Exception e) { + /* ignore, class not found */ + } + } + + /* 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 + * conditionally to wolfJSSE when supported. */ + /*out.setAlgorithmConstraints(in.getAlgorithmConstraints()); + out.setApplicationProtocols(in.getApplicationProtocols()); + out.setEnableRetransmissions(in.getEnableRetransmissions()); + out.setEndpointIdentificationAlgorithm( + in.getEndpointIdentificationAlgorithm()); + out.setMaximumPacketSize(in.getMaximumPacketSize()); + out.setSNIMatchers(in.getSNIMatchers()); + out.setUseCipherSuitesOrder(in.getUseCipherSuitesOrder()); + */ + } +} + diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java b/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java new file mode 100644 index 0000000..c0c12e9 --- /dev/null +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLSNIServerName.java @@ -0,0 +1,97 @@ +/* WolfSSLSNIServerName.java + * + * Copyright (C) 2006-2020 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-1301, USA + */ +package com.wolfssl.provider.jsse; + +import java.util.Objects; +import java.util.Arrays; + +/** + * wolfJSSE implementation that replicates functionality of the Java + * SNIServerName class. Used for internal WolfSSLParameters, unable to use + * standard class as some Java versions less than 1.8 do not have it + * available + */ +public abstract class WolfSSLSNIServerName +{ + private int type; + private byte[] encoded = null; + + protected WolfSSLSNIServerName(int type, byte[] encoded) { + + if (type < 0 || type > 255) { + throw new IllegalArgumentException( + "type must be between 0 and 255"); + } + + if (encoded == null) { + throw new NullPointerException( + "encoded input array cannot be null"); + } + + this.type = type; + this.encoded = encoded.clone(); + } + + public final int getType() { + return this.type; + } + + public final byte[] getEncoded() { + if (this.encoded == null) { + return null; + } + return encoded.clone(); + } + + public boolean equals(Object other) { + if (!(other instanceof WolfSSLSNIServerName)) { + return false; + } + WolfSSLSNIServerName tmp = (WolfSSLSNIServerName)other; + + if (tmp.type != this.type) { + return false; + } + + if (!Arrays.equals(tmp.encoded, this.encoded)) { + return false; + } + + return true; + } + + public int hashCode() { + return Objects.hash(this.type, this.encoded); + } + + public String toString() { + StringBuilder s = new StringBuilder(); + s.append("type=(" + this.type + "), "); + + for (byte b : this.encoded) { + String h = Integer.toHexString((int)b & 0xff); + s.append(h); + } + + return s.toString(); + } +} + diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java b/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java index 353498e..810fb3c 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocket.java @@ -42,7 +42,7 @@ public class WolfSSLServerSocket extends SSLServerSocket { private com.wolfssl.WolfSSLContext context = null; private WolfSSLAuthStore authStore = null; - private SSLParameters params = null; + private WolfSSLParameters params = null; private boolean clientMode = false; private boolean enableSessionCreation = true; @@ -51,18 +51,18 @@ public class WolfSSLServerSocket extends SSLServerSocket { public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, WolfSSLAuthStore authStore, - SSLParameters params) throws IOException { + WolfSSLParameters params) throws IOException { super(); /* defer creating WolfSSLSocket until accept() is called */ this.context = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); } public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, int port) + WolfSSLAuthStore authStore, WolfSSLParameters params, int port) throws IOException { super(port); @@ -70,12 +70,12 @@ public class WolfSSLServerSocket extends SSLServerSocket { /* defer creating WolfSSLSocket until accept() is called */ this.context = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); } public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, WolfSSLAuthStore authStore, - SSLParameters params, int port, int backlog) + WolfSSLParameters params, int port, int backlog) throws IOException { super(port, backlog); @@ -83,12 +83,13 @@ public class WolfSSLServerSocket extends SSLServerSocket { /* defer creating WolfSSLSocket until accept() is called */ this.context = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); } public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, WolfSSLAuthStore authStore, - SSLParameters params, int port, int backlog, InetAddress address) + WolfSSLParameters params, int port, int backlog, + InetAddress address) throws IOException { super(port, backlog, address); @@ -96,7 +97,7 @@ public class WolfSSLServerSocket extends SSLServerSocket { /* defer creating WolfSSLSocket until accept() is called */ this.context = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); } @Override @@ -230,6 +231,18 @@ public class WolfSSLServerSocket extends SSLServerSocket { return enableSessionCreation; } + /** + * Set the SSLParameters for this SSLServerSocket. + * + * @param params SSLParameters to set for this SSLSocket object + */ + synchronized public void setSSLParameters(SSLParameters params) { + if (params != null) { + WolfSSLParametersHelper.importParams(params, this.params); + } + } + + @Override synchronized public Socket accept() throws IOException { diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocketFactory.java b/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocketFactory.java index c730838..8b81126 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocketFactory.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLServerSocketFactory.java @@ -25,24 +25,23 @@ import java.io.IOException; import java.net.InetAddress; import javax.net.ssl.SSLServerSocketFactory; import java.net.ServerSocket; -import javax.net.ssl.SSLParameters; import com.wolfssl.WolfSSL; import com.wolfssl.WolfSSLContext; /** * wolfSSL implementation of SSLServerSocketFactory - * + * * @author wolfSSL */ public class WolfSSLServerSocketFactory extends SSLServerSocketFactory { private WolfSSLAuthStore authStore = null; private WolfSSLContext ctx = null; - private SSLParameters params; + private WolfSSLParameters params; public WolfSSLServerSocketFactory(com.wolfssl.WolfSSLContext ctx, - WolfSSLAuthStore authStore, SSLParameters params) { + WolfSSLAuthStore authStore, WolfSSLParameters params) { super(); this.ctx = ctx; this.authStore = authStore; diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java b/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java index 8fc3ade..a816471 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java @@ -35,9 +35,9 @@ import java.util.Arrays; import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.SSLHandshakeException; -import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLParameters; import com.wolfssl.WolfSSL; import com.wolfssl.WolfSSLContext; @@ -61,7 +61,7 @@ public class WolfSSLSocket extends SSLSocket { /* WOLFSSL reference, created in this class */ private WolfSSLSession ssl = null; - private SSLParameters params = null; + private WolfSSLParameters params = null; private WolfSSLEngineHelper EngineHelper = null; private Socket socket = null; @@ -76,13 +76,14 @@ public class WolfSSLSocket extends SSLSocket { protected volatile boolean handshakeInitCalled = false; public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, boolean clientMode) + WolfSSLAuthStore authStore, WolfSSLParameters params, + boolean clientMode) throws IOException { super(); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); @@ -99,14 +100,14 @@ public class WolfSSLSocket extends SSLSocket { } public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, + WolfSSLAuthStore authStore, WolfSSLParameters params, boolean clientMode, InetAddress host, int port) throws IOException { super(host, port); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); @@ -123,7 +124,7 @@ public class WolfSSLSocket extends SSLSocket { } public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, + WolfSSLAuthStore authStore, WolfSSLParameters params, boolean clientMode, InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { @@ -131,7 +132,7 @@ public class WolfSSLSocket extends SSLSocket { super(address, port, localAddress, localPort); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); @@ -148,14 +149,14 @@ public class WolfSSLSocket extends SSLSocket { } public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, + WolfSSLAuthStore authStore, WolfSSLParameters params, boolean clientMode, String host, int port) throws IOException { super(host, port); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); @@ -172,7 +173,7 @@ public class WolfSSLSocket extends SSLSocket { } public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, + WolfSSLAuthStore authStore, WolfSSLParameters params, boolean clientMode, String host, int port, InetAddress localHost, int localPort) throws IOException { @@ -180,7 +181,7 @@ public class WolfSSLSocket extends SSLSocket { super(host, port, localHost, localPort); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); try { initSSL(); @@ -200,14 +201,14 @@ public class WolfSSLSocket extends SSLSocket { named host, at the given port. host/port refer to logical peer, but Socket could be connected to a proxy */ public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, + WolfSSLAuthStore authStore, WolfSSLParameters params, boolean clientMode, Socket s, String host, int port, boolean autoClose) throws IOException { super(); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); this.socket = s; this.autoClose = autoClose; this.address = new InetSocketAddress(host, port); @@ -236,14 +237,14 @@ public class WolfSSLSocket extends SSLSocket { } public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, + WolfSSLAuthStore authStore, WolfSSLParameters params, boolean clientMode, Socket s, boolean autoClose) throws IOException { super(); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); this.socket = s; this.autoClose = autoClose; @@ -268,13 +269,13 @@ public class WolfSSLSocket extends SSLSocket { /* only creates a server mode Socket */ public WolfSSLSocket(com.wolfssl.WolfSSLContext context, - WolfSSLAuthStore authStore, SSLParameters params, Socket s, + WolfSSLAuthStore authStore, WolfSSLParameters params, Socket s, InputStream consumed, boolean autoClose) throws IOException { super(); this.ctx = context; this.authStore = authStore; - this.params = WolfSSLEngineHelper.decoupleParams(params); + this.params = params.copy(); this.socket = s; this.autoClose = autoClose; @@ -688,6 +689,17 @@ public class WolfSSLSocket extends SSLSocket { return outStream; } + /** + * Set the SSLParameters for this SSLSocket. + * + * @param params SSLParameters to set for this SSLSocket object + */ + synchronized public void setSSLParameters(SSLParameters params) { + if (params != null) { + WolfSSLParametersHelper.importParams(params, this.params); + } + } + /** * Closes this SSLSocket. * diff --git a/src/java/com/wolfssl/provider/jsse/WolfSSLSocketFactory.java b/src/java/com/wolfssl/provider/jsse/WolfSSLSocketFactory.java index 1956294..5f71c5f 100644 --- a/src/java/com/wolfssl/provider/jsse/WolfSSLSocketFactory.java +++ b/src/java/com/wolfssl/provider/jsse/WolfSSLSocketFactory.java @@ -27,7 +27,6 @@ import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; -import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocketFactory; import com.wolfssl.WolfSSL; @@ -44,7 +43,7 @@ public class WolfSSLSocketFactory extends SSLSocketFactory { private WolfSSLAuthStore authStore = null; private com.wolfssl.WolfSSLContext ctx = null; private com.wolfssl.provider.jsse.WolfSSLContext jsseCtx = null; - private SSLParameters params; + private WolfSSLParameters params; /* This constructor is used when the JSSE call * SSLSocketFactory.getDefault() */ @@ -57,7 +56,7 @@ public class WolfSSLSocketFactory extends SSLSocketFactory { } public WolfSSLSocketFactory(com.wolfssl.WolfSSLContext ctx, - WolfSSLAuthStore authStore, SSLParameters params) { + WolfSSLAuthStore authStore, WolfSSLParameters params) { super(); this.ctx = ctx; this.authStore = authStore; diff --git a/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java b/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java new file mode 100644 index 0000000..b27a57b --- /dev/null +++ b/src/java/com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java @@ -0,0 +1,99 @@ +/* WolfSSLJDK8Helper.java + * + * Copyright (C) 2006-2020 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-1301, USA + */ +package com.wolfssl.provider.jsse; + +import java.util.List; +import java.util.ArrayList; +import java.lang.reflect.Method; +import java.security.AccessController; +import java.security.PrivilegedAction; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SNIServerName; +import javax.net.ssl.SNIHostName; + +/** + * This class contains functionality that was added as of JDK 1.8, and is + * isolated in this class as to more easily avoid pre-JDK 1.8 execution from + * loading this class. Otherwise, importing the classes that did not exist + * on older JDKs would fail. + * + * Execution should be prevented from calling functions in this class on + * JDK version less than 1.8. + */ +public class WolfSSLJDK8Helper +{ + /* Call SSLParameters.setServerNames() to set SNI server names from + * WolfSSLParameters into SSLParameters */ + protected static void setServerNames(final SSLParameters out, + final Method m, WolfSSLParameters in) { + + if (out == null || m == null || in == null) { + throw new NullPointerException("input arguments to " + + "WolfSSLJDK8Helper.setServerNames() cannot be null"); + } + + List wsni = in.getServerNames(); + if (wsni != null) { + /* convert WolfSSLSNIServerName list to SNIServerName */ + final ArrayList sni = new ArrayList(wsni.size()); + for (WolfSSLSNIServerName name : wsni) { + sni.add(new SNIHostName(name.getEncoded())); + } + + /* call SSLParameters.setServerName() */ + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + try { + m.invoke(out, sni); + } catch (Exception e) { + throw new RuntimeException(e); + } + + return null; + } + }); + } + } + + /* Call SSLParameters.getServerNames() to set SNI server names from + * SSLParameters into WolfSSLParameters */ + protected static void getServerNames(final SSLParameters in, + WolfSSLParameters out) { + + if (out == null || in == null) { + throw new NullPointerException("input arguments to " + + "WolfSSLJDK8Helper.getServerNames() cannot be null"); + } + + List sni = in.getServerNames(); + if (sni != null) { + /* convert SNIServerName list to WolfSSLSNIServerName */ + final ArrayList wsni = new ArrayList(sni.size()); + for (SNIServerName name : sni) { + wsni.add(new WolfSSLGenericHostName(name.getType(), name.getEncoded())); + } + + /* call WolfSSLParameters.setServerNames() */ + out.setServerNames(wsni); + } + } +} + diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketFactoryTest.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketFactoryTest.java index dbc8645..e0370a6 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketFactoryTest.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketFactoryTest.java @@ -40,6 +40,7 @@ import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.TrustManagerFactory; import java.net.Socket; import java.net.InetAddress; +import java.net.InetSocketAddress; import java.net.SocketException; import java.security.Security; import java.security.Provider; @@ -227,6 +228,18 @@ public class WolfSSLSocketFactoryTest { Socket s = null; InputStream in = null; + /* test that we can connect to www.example.com */ + try { + Socket testConn = new Socket(); + testConn.connect(new InetSocketAddress(addrStr, port)); + testConn.close(); + } catch (Exception e) { + /* unable to connect, skip test */ + System.out.println("\t\t\t... skipped"); + return; + } + + /* set up InetAddress for www.example.com */ try { addr = InetAddress.getByName("www.example.com"); } catch (UnknownHostException e) { diff --git a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java index dfc8e7b..77c047f 100644 --- a/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java +++ b/src/test/com/wolfssl/provider/jsse/test/WolfSSLSocketTest.java @@ -185,7 +185,7 @@ public class WolfSSLSocketTest { SSLSocket s; try { s = (SSLSocket)sf.createSocket("www.example.com", 443); - } catch (UnknownHostException e) { + } catch (Exception e) { /* skip adding, no Internet connection */ continue; } @@ -686,30 +686,43 @@ public class WolfSSLSocketTest { SSLParameters p = s.getSSLParameters(); assertNotNull(p); - /* TODO: this returns null for wolfJSSE. */ - /* assertNotNull(p.getAlgorithmConstraints()); */ - + /* test getting and setting cipher suites */ String[] suites = p.getCipherSuites(); assertNotNull(suites); assertNotSame(suites, p.getCipherSuites()); /* should return copy */ - assertNotNull(s.getSupportedCipherSuites()); - p.setCipherSuites(s.getSupportedCipherSuites()); - assertArrayEquals(s.getSupportedCipherSuites(), p.getCipherSuites()); + String[] supportedSuites = s.getSupportedCipherSuites(); + assertNotNull(supportedSuites); + p.setCipherSuites(supportedSuites); + assertArrayEquals(supportedSuites, p.getCipherSuites()); + + /* test getting and setting need client auth */ assertFalse(p.getNeedClientAuth()); /* default: false */ p.setNeedClientAuth(true); assertTrue(p.getNeedClientAuth()); + /* test getting and setting want client auth */ assertFalse(p.getWantClientAuth()); /* default: false */ p.setWantClientAuth(true); assertTrue(p.getWantClientAuth()); + /* test getting and setting protocols */ String[] protos = p.getProtocols(); assertNotNull(protos); assertNotSame(protos, p.getProtocols()); - assertNotNull(s.getSupportedProtocols()); - p.setProtocols(s.getSupportedProtocols()); - assertArrayEquals(s.getSupportedProtocols(), p.getProtocols()); + + String[] supportedProtos = s.getSupportedProtocols(); + assertNotNull(supportedProtos); + p.setProtocols(supportedProtos); + assertArrayEquals(supportedProtos, p.getProtocols()); + + /* test setting SSLParameters on SSLSocket */ + p = s.getSSLParameters(); + String[] oneSuite = new String[] { supportedSuites[0] }; + p.setCipherSuites(oneSuite); + s.setSSLParameters(p); + p = s.getSSLParameters(); + assertArrayEquals(oneSuite, p.getCipherSuites()); s.close(); diff --git a/src/test/com/wolfssl/test/WolfSSLSessionTest.java b/src/test/com/wolfssl/test/WolfSSLSessionTest.java index 7a2aa82..cc3f969 100644 --- a/src/test/com/wolfssl/test/WolfSSLSessionTest.java +++ b/src/test/com/wolfssl/test/WolfSSLSessionTest.java @@ -63,7 +63,7 @@ public class WolfSSLSessionTest { cliCert = WolfSSLTestCommon.getPath(cliCert); cliKey = WolfSSLTestCommon.getPath(cliKey); caCert = WolfSSLTestCommon.getPath(caCert); - + test_WolfSSLSession_new(); test_WolfSSLSession_useCertificateFile(); test_WolfSSLSession_usePrivateKeyFile(); @@ -75,6 +75,7 @@ public class WolfSSLSessionTest { test_WolfSSLSession_getPskIdentity(); test_WolfSSLSession_timeout(); test_WolfSSLSession_status(); + test_WolfSSLSession_useSNI(); test_WolfSSLSession_freeSSL(); test_WolfSSLSession_UseAfterFree(); } @@ -330,7 +331,7 @@ public class WolfSSLSessionTest { } System.out.println("\t\t... passed"); } - + public void test_WolfSSLSession_timeout() { System.out.print("\ttimeout()"); @@ -349,7 +350,23 @@ public class WolfSSLSessionTest { } System.out.println("\t\t\t... passed"); } - + + public void test_WolfSSLSession_useSNI() { + + int ret; + String sniHostName = "www.example.com"; + + System.out.print("\tuseSNI()"); + ret = ssl.useSNI((byte)0, sniHostName.getBytes()); + if (ret == WolfSSL.NOT_COMPILED_IN) { + System.out.println("\t\t\t... skipped"); + } else if (ret != WolfSSL.SSL_SUCCESS) { + System.out.println("\t\t\t... failed"); + } else { + System.out.println("\t\t\t... passed"); + } + } + public void test_WolfSSLSession_freeSSL() { System.out.print("\tfreeSSL()");