Merge pull request #43 from cconlon/sslparams

WolfSSLParameters, client-side SNI support
pull/45/head
JacobBarthelmeh 2020-05-15 11:42:06 -06:00 committed by GitHub
commit 21bde33473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 840 additions and 112 deletions

View File

@ -30,6 +30,10 @@
<property environment="env"/> <property environment="env"/>
<!-- check for SNIHostName class to determine if JDK version >= 1.8 -->
<available property="have-SNIHostName" classname="javax.net.ssl.SNIHostName" />
<!-- check if javac nativeheaderdir is available -->
<condition property="have-nativeheaderdir"> <condition property="have-nativeheaderdir">
<and> <and>
<antversion atleast="1.9.8"/> <antversion atleast="1.9.8"/>
@ -88,8 +92,7 @@
<target name="build-jacoco" depends="init, compile-nativeheaderdir, compile-javah, jar, jar-jsse, javah, javadoc, examples, test-jacoco, coverage-report"/> <target name="build-jacoco" depends="init, compile-nativeheaderdir, compile-javah, jar, jar-jsse, javah, javadoc, examples, test-jacoco, coverage-report"/>
<target name="compile-nativeheaderdir" if="have-nativeheaderdir"> <target name="compile-nativeheaderdir" if="have-nativeheaderdir">
<javac srcdir="${src.dir}" <javac destdir="${build.dir}"
destdir="${build.dir}"
nativeheaderdir="${native.dir}" nativeheaderdir="${native.dir}"
debug="${java.debug}" debug="${java.debug}"
debuglevel="${java.debuglevel}" debuglevel="${java.debuglevel}"
@ -100,12 +103,16 @@
classpathref="classpath" classpathref="classpath"
includeantruntime="false"> includeantruntime="false">
<compilerarg value="-Xlint:-options"/> <compilerarg value="-Xlint:-options"/>
<src path="${src.dir}" />
<include name="com/wolfssl/**" />
<include name="com/wolfssl/provider/jsse/**" />
<include name="com/wolfssl/provider/jsse/adapter/**" />
<exclude name="com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java" unless="have-SNIHostName" />
</javac> </javac>
</target> </target>
<target name="compile-javah" unless="have-nativeheaderdir"> <target name="compile-javah" unless="have-nativeheaderdir">
<javac srcdir="${src.dir}" <javac destdir="${build.dir}"
destdir="${build.dir}"
debug="${java.debug}" debug="${java.debug}"
debuglevel="${java.debuglevel}" debuglevel="${java.debuglevel}"
deprecation="${java.deprecation}" deprecation="${java.deprecation}"
@ -115,6 +122,11 @@
classpathref="classpath" classpathref="classpath"
includeantruntime="false"> includeantruntime="false">
<compilerarg value="-Xlint:-options"/> <compilerarg value="-Xlint:-options"/>
<src path="${src.dir}" />
<include name="com/wolfssl/**" />
<include name="com/wolfssl/provider/jsse/**" />
<include name="com/wolfssl/provider/jsse/adapter/**" />
<exclude name="com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java" unless="have-SNIHostName" />
</javac> </javac>
</target> </target>
@ -157,7 +169,13 @@
</target> </target>
<target name="javadoc" description="generate documentation"> <target name="javadoc" description="generate documentation">
<javadoc sourcepath="${src.dir}" destdir="${doc.dir}"/> <javadoc destdir="${doc.dir}">
<fileset dir="${src.dir}">
<include name="com/wolfssl/**"/>
<include name="com/wolfssl/provider/jsse/**"/>
<exclude name="com/wolfssl/provider/jsse/adapter/WolfSSLJDK8Helper.java" unless="have-SNIHostName" />
</fileset>
</javadoc>
</target> </target>
<target name="examples" depends="build"> <target name="examples" depends="build">

View File

@ -697,11 +697,11 @@ JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocols
/* /*
* Class: com_wolfssl_WolfSSL * Class: com_wolfssl_WolfSSL
* Method: getProtocols * Method: getProtocolsMask
* Signature: ()[Ljava/lang/String; * Signature: (J)[Ljava/lang/String;
*/ */
JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocolsMask JNIEXPORT jobjectArray JNICALL Java_com_wolfssl_WolfSSL_getProtocolsMask
(JNIEnv*, jclass, jlong); (JNIEnv *, jclass, jlong);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -603,7 +603,11 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLCertificate_X509_1verify
int sz = (int)pubKeySz; int sz = (int)pubKeySz;
int ret; int ret;
unsigned char buff[sz]; unsigned char buff[sz];
#if LIBWOLFSSL_VERSION_HEX >= 0x04004000
const unsigned char* ptr = buff;
#else
unsigned char* ptr = buff; unsigned char* ptr = buff;
#endif
(void)jcl; (void)jcl;

View File

@ -73,8 +73,8 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLContext_setOptions
/* /*
* Class: com_wolfssl_WolfSSLContext * Class: com_wolfssl_WolfSSLContext
* Method: setOptions * Method: getOptions
* Signature: (JJ)J * Signature: (J)J
*/ */
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLContext_getOptions JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLContext_getOptions
(JNIEnv *, jobject, jlong); (JNIEnv *, jobject, jlong);

View File

@ -2934,6 +2934,41 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getShutdown
return (jint)wolfSSL_get_shutdown((WOLFSSL*)(uintptr_t)ssl); 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 JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIORecv
(JNIEnv* jenv, jobject jcl, jlong ssl) (JNIEnv* jenv, jobject jcl, jlong ssl)
{ {

View File

@ -650,7 +650,7 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_setOptions
/* /*
* Class: com_wolfssl_WolfSSLSession * Class: com_wolfssl_WolfSSLSession
* Method: getOptions * Method: getOptions
* Signature: (JJ)J * Signature: (J)J
*/ */
JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_getOptions JNIEXPORT jlong JNICALL Java_com_wolfssl_WolfSSLSession_getOptions
(JNIEnv *, jobject, jlong); (JNIEnv *, jobject, jlong);
@ -679,6 +679,14 @@ JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIORecv
JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIOSend JNIEXPORT void JNICALL Java_com_wolfssl_WolfSSLSession_setSSLIOSend
(JNIEnv *, jobject, jlong); (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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -4,7 +4,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE:= libwolfssl LOCAL_MODULE:= libwolfssl
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) 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 += \ LOCAL_C_INCLUDES += \
external/wolfssl/wolfssl \ external/wolfssl/wolfssl \
external/wolfssl \ external/wolfssl \

View File

@ -8,7 +8,17 @@ native_cflags := -Wall
# Create the wolfSSL JNI library # Create the wolfSSL JNI library
include $(CLEAR_VARS) 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 := $(call all-java-files-under,src/java)
LOCAL_SRC_FILES := $(filter-out $(LOCAL_SRC_EXCLUDES), $(LOCAL_SRC_FILES))
LOCAL_JAVACFLAGS := $(javac_flags) LOCAL_JAVACFLAGS := $(javac_flags)
LOCAL_MODULE_TAGS := optional LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := wolfssljni LOCAL_MODULE := wolfssljni
@ -20,7 +30,7 @@ include $(BUILD_JAVA_LIBRARY)
# Create wolfSSL JNI native library # Create wolfSSL JNI native library
include $(CLEAR_VARS) include $(CLEAR_VARS)
LOCAL_CFLAGS += $(native_cflags) 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 := \ LOCAL_SRC_FILES := \
native/com_wolfssl_wolfcrypt_ECC.c \ native/com_wolfssl_wolfcrypt_ECC.c \
native/com_wolfssl_wolfcrypt_EccKey.c \ native/com_wolfssl_wolfcrypt_EccKey.c \

View File

@ -264,6 +264,7 @@ public class WolfSSLSession {
private native int getShutdown(long ssl); private native int getShutdown(long ssl);
private native void setSSLIORecv(long ssl); private native void setSSLIORecv(long ssl);
private native void setSSLIOSend(long ssl); private native void setSSLIOSend(long ssl);
private native int useSNI(long ssl, byte type, byte[] data);
/* ------------------- session-specific methods --------------------- */ /* ------------------- session-specific methods --------------------- */
@ -2425,6 +2426,18 @@ public class WolfSSLSession {
setSSLIOSend(getSessionPtr()); 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 * Getter function to tell if shutdown has been sent or received
* @return WolfSSL.SSL_SENT_SHUTDOWN or WolfSSL.SSL_RECEIVED_SHUTDOWN * @return WolfSSL.SSL_SENT_SHUTDOWN or WolfSSL.SSL_RECEIVED_SHUTDOWN

View File

@ -56,7 +56,7 @@ public class WolfSSLContext extends SSLContextSpi {
private TLS_VERSION currentVersion = TLS_VERSION.SSLv23; private TLS_VERSION currentVersion = TLS_VERSION.SSLv23;
private WolfSSLAuthStore authStore = null; private WolfSSLAuthStore authStore = null;
private com.wolfssl.WolfSSLContext ctx = null; private com.wolfssl.WolfSSLContext ctx = null;
private SSLParameters params = null; private WolfSSLParameters params = null;
private WolfSSLContext(TLS_VERSION version) { private WolfSSLContext(TLS_VERSION version) {
this.currentVersion = version; this.currentVersion = version;
@ -302,7 +302,7 @@ public class WolfSSLContext extends SSLContextSpi {
try { try {
authStore = new WolfSSLAuthStore(km, tm, sr, currentVersion); authStore = new WolfSSLAuthStore(km, tm, sr, currentVersion);
params = new SSLParameters(); params = new WolfSSLParameters();
createCtx(); createCtx();
} catch (IllegalArgumentException iae) { } catch (IllegalArgumentException iae) {
@ -423,7 +423,7 @@ public class WolfSSLContext extends SSLContextSpi {
*/ */
@Override @Override
protected SSLParameters engineGetDefaultSSLParameters() { protected SSLParameters engineGetDefaultSSLParameters() {
return WolfSSLEngineHelper.decoupleParams(this.params); return WolfSSLParametersHelper.decoupleParams(this.params);
} }
/** /**
@ -432,7 +432,7 @@ public class WolfSSLContext extends SSLContextSpi {
*/ */
@Override @Override
protected SSLParameters engineGetSupportedSSLParameters() { protected SSLParameters engineGetSupportedSSLParameters() {
return WolfSSLEngineHelper.decoupleParams(this.params); return WolfSSLParametersHelper.decoupleParams(this.params);
} }
/* used internally by SSLSocketFactory() */ /* used internally by SSLSocketFactory() */
@ -441,7 +441,7 @@ public class WolfSSLContext extends SSLContextSpi {
} }
/* used internally by SSLSocketFactory() */ /* used internally by SSLSocketFactory() */
protected SSLParameters getInternalSSLParams() { protected WolfSSLParameters getInternalSSLParams() {
return this.params; return this.params;
} }
@ -458,7 +458,7 @@ public class WolfSSLContext extends SSLContextSpi {
} }
super.finalize(); super.finalize();
} }
public String[] getProtocolsMask(long noOpt) { public String[] getProtocolsMask(long noOpt) {
if(ctx != null) if(ctx != null)
ctx.setOptions(noOpt); ctx.setOptions(noOpt);

View File

@ -35,8 +35,8 @@ import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus; import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status; import javax.net.ssl.SSLEngineResult.Status;
import javax.net.ssl.SSLException; import javax.net.ssl.SSLException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLParameters;
/** /**
* wolfSSL implementation of SSLEngine * wolfSSL implementation of SSLEngine
@ -49,7 +49,7 @@ public class WolfSSLEngine extends SSLEngine {
private WolfSSLSession ssl; private WolfSSLSession ssl;
private com.wolfssl.WolfSSLContext ctx; private com.wolfssl.WolfSSLContext ctx;
private WolfSSLAuthStore authStore; private WolfSSLAuthStore authStore;
private SSLParameters params; private WolfSSLParameters params;
private byte[] toSend; /* encrypted packet to send */ private byte[] toSend; /* encrypted packet to send */
private byte[] toRead; /* encrypted packet coming in */ private byte[] toRead; /* encrypted packet coming in */
private int toReadSz = 0; private int toReadSz = 0;
@ -74,12 +74,12 @@ public class WolfSSLEngine extends SSLEngine {
* @throws WolfSSLException if there is an issue creating the engine * @throws WolfSSLException if there is an issue creating the engine
*/ */
protected WolfSSLEngine(com.wolfssl.WolfSSLContext ctx, protected WolfSSLEngine(com.wolfssl.WolfSSLContext ctx,
WolfSSLAuthStore auth, SSLParameters params) WolfSSLAuthStore auth, WolfSSLParameters params)
throws WolfSSLException { throws WolfSSLException {
super(); super();
this.ctx = ctx; this.ctx = ctx;
this.authStore = auth; this.authStore = auth;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
} catch (WolfSSLJNIException ex) { } catch (WolfSSLJNIException ex) {
@ -102,12 +102,12 @@ public class WolfSSLEngine extends SSLEngine {
* @throws WolfSSLException if there is an issue creating the engine * @throws WolfSSLException if there is an issue creating the engine
*/ */
protected WolfSSLEngine(com.wolfssl.WolfSSLContext ctx, protected WolfSSLEngine(com.wolfssl.WolfSSLContext ctx,
WolfSSLAuthStore auth, SSLParameters params, String host, WolfSSLAuthStore auth, WolfSSLParameters params, String host,
int port) throws WolfSSLException { int port) throws WolfSSLException {
super(); super();
this.ctx = ctx; this.ctx = ctx;
this.authStore = auth; this.authStore = auth;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
} catch (WolfSSLJNIException ex) { } catch (WolfSSLJNIException ex) {
@ -520,6 +520,17 @@ public class WolfSSLEngine extends SSLEngine {
return EngineHelper.getEnableSessionCreation(); 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 /* encrypted packet ready to be sent out. Copies buffer to end of to send
* queue */ * queue */
protected int setOut(byte[] in, int sz) { protected int setOut(byte[] in, int sz) {

View File

@ -48,7 +48,7 @@ import java.io.IOException;
public class WolfSSLEngineHelper { public class WolfSSLEngineHelper {
private final WolfSSLSession ssl; private final WolfSSLSession ssl;
private WolfSSLImplementSSLSession session = null; private WolfSSLImplementSSLSession session = null;
private SSLParameters params; private WolfSSLParameters params;
private WolfSSLDebug debug; private WolfSSLDebug debug;
private int port; private int port;
private String host = null; private String host = null;
@ -65,7 +65,7 @@ public class WolfSSLEngineHelper {
* @throws WolfSSLException if an exception happens during session creation * @throws WolfSSLException if an exception happens during session creation
*/ */
protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store, protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store,
SSLParameters params) throws WolfSSLException { WolfSSLParameters params) throws WolfSSLException {
if (params == null || ssl == null || store == null) { if (params == null || ssl == null || store == null) {
throw new WolfSSLException("Bad argument"); throw new WolfSSLException("Bad argument");
} }
@ -86,7 +86,7 @@ public class WolfSSLEngineHelper {
* @throws WolfSSLException if an exception happens during session resume * @throws WolfSSLException if an exception happens during session resume
*/ */
protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store, protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store,
SSLParameters params, int port, String host) WolfSSLParameters params, int port, String host)
throws WolfSSLException { throws WolfSSLException {
if (params == null || ssl == null || store == null) { if (params == null || ssl == null || store == null) {
throw new WolfSSLException("Bad argument"); 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<WolfSSLSNIServerName> 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() { private void setLocalParams() {
this.setLocalCiphers(this.params.getCipherSuites()); this.setLocalCiphers(this.params.getCipherSuites());
this.setLocalProtocol(this.params.getProtocols()); this.setLocalProtocol(this.params.getProtocols());
this.setLocalAuth(); this.setLocalAuth();
this.setLocalServerNames();
} }
/* sets all parameters from SSLParameters into WOLFSSL object and creates /* sets all parameters from WolfSSLParameters into WOLFSSL object and
* session. * creates session.
* Should be called before doHandshake */ * Should be called before doHandshake */
protected void initHandshake() throws SSLException { protected void initHandshake() throws SSLException {
if (!modeSet) { if (!modeSet) {
@ -418,7 +433,6 @@ public class WolfSSLEngineHelper {
} }
} }
/** /**
* Saves session on connection close for resumption * 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 /* Internal verify callback. This is used when a user registers a
* TrustManager which is NOT com.wolfssl.provider.jsse.WolfSSLTrustManager * TrustManager which is NOT com.wolfssl.provider.jsse.WolfSSLTrustManager
* and is used to call TrustManager checkClientTrusted() or * and is used to call TrustManager checkClientTrusted() or

View File

@ -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);
}
}

View File

@ -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<WolfSSLSNIServerName> 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<WolfSSLSNIServerName> serverNames) {
if (serverNames == null) {
this.serverNames = null;
} else {
this.serverNames = Collections.unmodifiableList(
new ArrayList<WolfSSLSNIServerName>(serverNames));
}
}
List<WolfSSLSNIServerName> getServerNames() {
if (this.serverNames == null) {
return null;
} else {
return Collections.unmodifiableList(
new ArrayList<WolfSSLSNIServerName>(this.serverNames));
}
}
/* TODO, create our own class for SNIMatcher, in case Java doesn't support it */
//void setSNIMatchers(Collection<SNIMatcher> matchers) {
// /* TODO */
//}
/* TODO, create our own class for SNIMatcher, in case Java doesn't support it */
//Collection<SNIMatcher> 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();
}
}

View File

@ -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<Object>() {
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());
*/
}
}

View File

@ -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();
}
}

View File

@ -42,7 +42,7 @@ public class WolfSSLServerSocket extends SSLServerSocket {
private com.wolfssl.WolfSSLContext context = null; private com.wolfssl.WolfSSLContext context = null;
private WolfSSLAuthStore authStore = null; private WolfSSLAuthStore authStore = null;
private SSLParameters params = null; private WolfSSLParameters params = null;
private boolean clientMode = false; private boolean clientMode = false;
private boolean enableSessionCreation = true; private boolean enableSessionCreation = true;
@ -51,18 +51,18 @@ public class WolfSSLServerSocket extends SSLServerSocket {
public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, WolfSSLAuthStore authStore,
SSLParameters params) throws IOException { WolfSSLParameters params) throws IOException {
super(); super();
/* defer creating WolfSSLSocket until accept() is called */ /* defer creating WolfSSLSocket until accept() is called */
this.context = context; this.context = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
} }
public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, int port) WolfSSLAuthStore authStore, WolfSSLParameters params, int port)
throws IOException { throws IOException {
super(port); super(port);
@ -70,12 +70,12 @@ public class WolfSSLServerSocket extends SSLServerSocket {
/* defer creating WolfSSLSocket until accept() is called */ /* defer creating WolfSSLSocket until accept() is called */
this.context = context; this.context = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
} }
public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, WolfSSLAuthStore authStore,
SSLParameters params, int port, int backlog) WolfSSLParameters params, int port, int backlog)
throws IOException { throws IOException {
super(port, backlog); super(port, backlog);
@ -83,12 +83,13 @@ public class WolfSSLServerSocket extends SSLServerSocket {
/* defer creating WolfSSLSocket until accept() is called */ /* defer creating WolfSSLSocket until accept() is called */
this.context = context; this.context = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
} }
public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context, public WolfSSLServerSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, WolfSSLAuthStore authStore,
SSLParameters params, int port, int backlog, InetAddress address) WolfSSLParameters params, int port, int backlog,
InetAddress address)
throws IOException { throws IOException {
super(port, backlog, address); super(port, backlog, address);
@ -96,7 +97,7 @@ public class WolfSSLServerSocket extends SSLServerSocket {
/* defer creating WolfSSLSocket until accept() is called */ /* defer creating WolfSSLSocket until accept() is called */
this.context = context; this.context = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
} }
@Override @Override
@ -230,6 +231,18 @@ public class WolfSSLServerSocket extends SSLServerSocket {
return enableSessionCreation; 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 @Override
synchronized public Socket accept() throws IOException { synchronized public Socket accept() throws IOException {

View File

@ -25,24 +25,23 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLServerSocketFactory;
import java.net.ServerSocket; import java.net.ServerSocket;
import javax.net.ssl.SSLParameters;
import com.wolfssl.WolfSSL; import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLContext; import com.wolfssl.WolfSSLContext;
/** /**
* wolfSSL implementation of SSLServerSocketFactory * wolfSSL implementation of SSLServerSocketFactory
* *
* @author wolfSSL * @author wolfSSL
*/ */
public class WolfSSLServerSocketFactory extends SSLServerSocketFactory { public class WolfSSLServerSocketFactory extends SSLServerSocketFactory {
private WolfSSLAuthStore authStore = null; private WolfSSLAuthStore authStore = null;
private WolfSSLContext ctx = null; private WolfSSLContext ctx = null;
private SSLParameters params; private WolfSSLParameters params;
public WolfSSLServerSocketFactory(com.wolfssl.WolfSSLContext ctx, public WolfSSLServerSocketFactory(com.wolfssl.WolfSSLContext ctx,
WolfSSLAuthStore authStore, SSLParameters params) { WolfSSLAuthStore authStore, WolfSSLParameters params) {
super(); super();
this.ctx = ctx; this.ctx = ctx;
this.authStore = authStore; this.authStore = authStore;

View File

@ -35,9 +35,9 @@ import java.util.Arrays;
import javax.net.ssl.HandshakeCompletedEvent; import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener; import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLParameters;
import com.wolfssl.WolfSSL; import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLContext; import com.wolfssl.WolfSSLContext;
@ -61,7 +61,7 @@ public class WolfSSLSocket extends SSLSocket {
/* WOLFSSL reference, created in this class */ /* WOLFSSL reference, created in this class */
private WolfSSLSession ssl = null; private WolfSSLSession ssl = null;
private SSLParameters params = null; private WolfSSLParameters params = null;
private WolfSSLEngineHelper EngineHelper = null; private WolfSSLEngineHelper EngineHelper = null;
private Socket socket = null; private Socket socket = null;
@ -76,13 +76,14 @@ public class WolfSSLSocket extends SSLSocket {
protected volatile boolean handshakeInitCalled = false; protected volatile boolean handshakeInitCalled = false;
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, boolean clientMode) WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode)
throws IOException { throws IOException {
super(); super();
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
@ -99,14 +100,14 @@ public class WolfSSLSocket extends SSLSocket {
} }
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode, InetAddress host, int port) boolean clientMode, InetAddress host, int port)
throws IOException { throws IOException {
super(host, port); super(host, port);
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
@ -123,7 +124,7 @@ public class WolfSSLSocket extends SSLSocket {
} }
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode, InetAddress address, int port, boolean clientMode, InetAddress address, int port,
InetAddress localAddress, int localPort) InetAddress localAddress, int localPort)
throws IOException { throws IOException {
@ -131,7 +132,7 @@ public class WolfSSLSocket extends SSLSocket {
super(address, port, localAddress, localPort); super(address, port, localAddress, localPort);
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
@ -148,14 +149,14 @@ public class WolfSSLSocket extends SSLSocket {
} }
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode, String host, int port) boolean clientMode, String host, int port)
throws IOException { throws IOException {
super(host, port); super(host, port);
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
@ -172,7 +173,7 @@ public class WolfSSLSocket extends SSLSocket {
} }
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode, String host, int port, InetAddress localHost, boolean clientMode, String host, int port, InetAddress localHost,
int localPort) int localPort)
throws IOException { throws IOException {
@ -180,7 +181,7 @@ public class WolfSSLSocket extends SSLSocket {
super(host, port, localHost, localPort); super(host, port, localHost, localPort);
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
try { try {
initSSL(); initSSL();
@ -200,14 +201,14 @@ public class WolfSSLSocket extends SSLSocket {
named host, at the given port. host/port refer to logical peer, but named host, at the given port. host/port refer to logical peer, but
Socket could be connected to a proxy */ Socket could be connected to a proxy */
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode, Socket s, String host, int port, boolean clientMode, Socket s, String host, int port,
boolean autoClose) throws IOException { boolean autoClose) throws IOException {
super(); super();
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
this.socket = s; this.socket = s;
this.autoClose = autoClose; this.autoClose = autoClose;
this.address = new InetSocketAddress(host, port); this.address = new InetSocketAddress(host, port);
@ -236,14 +237,14 @@ public class WolfSSLSocket extends SSLSocket {
} }
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, WolfSSLAuthStore authStore, WolfSSLParameters params,
boolean clientMode, Socket s, boolean autoClose) boolean clientMode, Socket s, boolean autoClose)
throws IOException { throws IOException {
super(); super();
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
this.socket = s; this.socket = s;
this.autoClose = autoClose; this.autoClose = autoClose;
@ -268,13 +269,13 @@ public class WolfSSLSocket extends SSLSocket {
/* only creates a server mode Socket */ /* only creates a server mode Socket */
public WolfSSLSocket(com.wolfssl.WolfSSLContext context, public WolfSSLSocket(com.wolfssl.WolfSSLContext context,
WolfSSLAuthStore authStore, SSLParameters params, Socket s, WolfSSLAuthStore authStore, WolfSSLParameters params, Socket s,
InputStream consumed, boolean autoClose) throws IOException { InputStream consumed, boolean autoClose) throws IOException {
super(); super();
this.ctx = context; this.ctx = context;
this.authStore = authStore; this.authStore = authStore;
this.params = WolfSSLEngineHelper.decoupleParams(params); this.params = params.copy();
this.socket = s; this.socket = s;
this.autoClose = autoClose; this.autoClose = autoClose;
@ -688,6 +689,17 @@ public class WolfSSLSocket extends SSLSocket {
return outStream; 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. * Closes this SSLSocket.
* *

View File

@ -27,7 +27,6 @@ import java.net.InetAddress;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLSocketFactory;
import com.wolfssl.WolfSSL; import com.wolfssl.WolfSSL;
@ -44,7 +43,7 @@ public class WolfSSLSocketFactory extends SSLSocketFactory {
private WolfSSLAuthStore authStore = null; private WolfSSLAuthStore authStore = null;
private com.wolfssl.WolfSSLContext ctx = null; private com.wolfssl.WolfSSLContext ctx = null;
private com.wolfssl.provider.jsse.WolfSSLContext jsseCtx = null; private com.wolfssl.provider.jsse.WolfSSLContext jsseCtx = null;
private SSLParameters params; private WolfSSLParameters params;
/* This constructor is used when the JSSE call /* This constructor is used when the JSSE call
* SSLSocketFactory.getDefault() */ * SSLSocketFactory.getDefault() */
@ -57,7 +56,7 @@ public class WolfSSLSocketFactory extends SSLSocketFactory {
} }
public WolfSSLSocketFactory(com.wolfssl.WolfSSLContext ctx, public WolfSSLSocketFactory(com.wolfssl.WolfSSLContext ctx,
WolfSSLAuthStore authStore, SSLParameters params) { WolfSSLAuthStore authStore, WolfSSLParameters params) {
super(); super();
this.ctx = ctx; this.ctx = ctx;
this.authStore = authStore; this.authStore = authStore;

View File

@ -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<WolfSSLSNIServerName> wsni = in.getServerNames();
if (wsni != null) {
/* convert WolfSSLSNIServerName list to SNIServerName */
final ArrayList<SNIServerName> sni = new ArrayList<SNIServerName>(wsni.size());
for (WolfSSLSNIServerName name : wsni) {
sni.add(new SNIHostName(name.getEncoded()));
}
/* call SSLParameters.setServerName() */
AccessController.doPrivileged(new PrivilegedAction<Object>() {
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<SNIServerName> sni = in.getServerNames();
if (sni != null) {
/* convert SNIServerName list to WolfSSLSNIServerName */
final ArrayList<WolfSSLSNIServerName> wsni = new ArrayList<WolfSSLSNIServerName>(sni.size());
for (SNIServerName name : sni) {
wsni.add(new WolfSSLGenericHostName(name.getType(), name.getEncoded()));
}
/* call WolfSSLParameters.setServerNames() */
out.setServerNames(wsni);
}
}
}

View File

@ -40,6 +40,7 @@ import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.TrustManagerFactory;
import java.net.Socket; import java.net.Socket;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException; import java.net.SocketException;
import java.security.Security; import java.security.Security;
import java.security.Provider; import java.security.Provider;
@ -227,6 +228,18 @@ public class WolfSSLSocketFactoryTest {
Socket s = null; Socket s = null;
InputStream in = 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 { try {
addr = InetAddress.getByName("www.example.com"); addr = InetAddress.getByName("www.example.com");
} catch (UnknownHostException e) { } catch (UnknownHostException e) {

View File

@ -185,7 +185,7 @@ public class WolfSSLSocketTest {
SSLSocket s; SSLSocket s;
try { try {
s = (SSLSocket)sf.createSocket("www.example.com", 443); s = (SSLSocket)sf.createSocket("www.example.com", 443);
} catch (UnknownHostException e) { } catch (Exception e) {
/* skip adding, no Internet connection */ /* skip adding, no Internet connection */
continue; continue;
} }
@ -686,30 +686,43 @@ public class WolfSSLSocketTest {
SSLParameters p = s.getSSLParameters(); SSLParameters p = s.getSSLParameters();
assertNotNull(p); assertNotNull(p);
/* TODO: this returns null for wolfJSSE. */ /* test getting and setting cipher suites */
/* assertNotNull(p.getAlgorithmConstraints()); */
String[] suites = p.getCipherSuites(); String[] suites = p.getCipherSuites();
assertNotNull(suites); assertNotNull(suites);
assertNotSame(suites, p.getCipherSuites()); /* should return copy */ 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 */ assertFalse(p.getNeedClientAuth()); /* default: false */
p.setNeedClientAuth(true); p.setNeedClientAuth(true);
assertTrue(p.getNeedClientAuth()); assertTrue(p.getNeedClientAuth());
/* test getting and setting want client auth */
assertFalse(p.getWantClientAuth()); /* default: false */ assertFalse(p.getWantClientAuth()); /* default: false */
p.setWantClientAuth(true); p.setWantClientAuth(true);
assertTrue(p.getWantClientAuth()); assertTrue(p.getWantClientAuth());
/* test getting and setting protocols */
String[] protos = p.getProtocols(); String[] protos = p.getProtocols();
assertNotNull(protos); assertNotNull(protos);
assertNotSame(protos, p.getProtocols()); assertNotSame(protos, p.getProtocols());
assertNotNull(s.getSupportedProtocols());
p.setProtocols(s.getSupportedProtocols()); String[] supportedProtos = s.getSupportedProtocols();
assertArrayEquals(s.getSupportedProtocols(), p.getProtocols()); 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(); s.close();

View File

@ -63,7 +63,7 @@ public class WolfSSLSessionTest {
cliCert = WolfSSLTestCommon.getPath(cliCert); cliCert = WolfSSLTestCommon.getPath(cliCert);
cliKey = WolfSSLTestCommon.getPath(cliKey); cliKey = WolfSSLTestCommon.getPath(cliKey);
caCert = WolfSSLTestCommon.getPath(caCert); caCert = WolfSSLTestCommon.getPath(caCert);
test_WolfSSLSession_new(); test_WolfSSLSession_new();
test_WolfSSLSession_useCertificateFile(); test_WolfSSLSession_useCertificateFile();
test_WolfSSLSession_usePrivateKeyFile(); test_WolfSSLSession_usePrivateKeyFile();
@ -75,6 +75,7 @@ public class WolfSSLSessionTest {
test_WolfSSLSession_getPskIdentity(); test_WolfSSLSession_getPskIdentity();
test_WolfSSLSession_timeout(); test_WolfSSLSession_timeout();
test_WolfSSLSession_status(); test_WolfSSLSession_status();
test_WolfSSLSession_useSNI();
test_WolfSSLSession_freeSSL(); test_WolfSSLSession_freeSSL();
test_WolfSSLSession_UseAfterFree(); test_WolfSSLSession_UseAfterFree();
} }
@ -330,7 +331,7 @@ public class WolfSSLSessionTest {
} }
System.out.println("\t\t... passed"); System.out.println("\t\t... passed");
} }
public void test_WolfSSLSession_timeout() { public void test_WolfSSLSession_timeout() {
System.out.print("\ttimeout()"); System.out.print("\ttimeout()");
@ -349,7 +350,23 @@ public class WolfSSLSessionTest {
} }
System.out.println("\t\t\t... passed"); 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() { public void test_WolfSSLSession_freeSSL() {
System.out.print("\tfreeSSL()"); System.out.print("\tfreeSSL()");