Skip to content

Commit

Permalink
Merge pull request #100 from cconlon/connectTimeout
Browse files Browse the repository at this point in the history
Throw SocketTimeoutException from WolfSSLSession.connect()
  • Loading branch information
JacobBarthelmeh authored Apr 15, 2022
2 parents 193361e + 488d6e7 commit e56b05b
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 26 deletions.
2 changes: 2 additions & 0 deletions native/com_wolfssl_WolfSSL.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions native/com_wolfssl_WolfSSLSession.c
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getFd
/* enum values used in socketSelect() */
enum {
WOLFJNI_SELECT_FAIL = -10,
WOLFJNI_TIMEOUT = -11,
WOLFJNI_TIMEOUT = -11, /* also in WolfSSL.java */
WOLFJNI_RECV_READY = -12,
WOLFJNI_SEND_READY = -13,
WOLFJNI_ERROR_READY = -14
Expand Down Expand Up @@ -623,7 +623,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect
(void)jcl;

if (jenv == NULL || ssl == NULL) {
return SSL_FATAL_ERROR;
return SSL_FAILURE;
}

/* make sure we don't have any outstanding exceptions pending */
Expand Down Expand Up @@ -674,8 +674,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
/* I/O ready, continue handshake and try again */
continue;
} else if (ret == WOLFJNI_TIMEOUT) {
/* Java will throw SocketTimeoutException */
break;
} else {
/* error or timeout */
/* error */
ret = SSL_FAILURE;
break;
}
}
Expand Down Expand Up @@ -745,6 +749,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write
break;
}

if (ret >= 0) /* return if it is success */
break;

if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {

sockfd = wolfSSL_get_fd(ssl);
Expand Down
5 changes: 5 additions & 0 deletions src/java/com/wolfssl/WolfSSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@ public static enum TLS_VERSION {
/** Session unavailable */
public final static int JNI_SESSION_UNAVAILABLE = -10001;

/**
* Socket timed out, matches com_wolfssl_WolfSSLSession.c socketSelect()
* return value */
public final static int WOLFJNI_TIMEOUT = -11;

/* ----------------------- wolfSSL codes ---------------------------- */

/** Error code: no error */
Expand Down
44 changes: 40 additions & 4 deletions src/java/com/wolfssl/WolfSSLSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ public class WolfSSLSession {
private WolfSSLIORecvCallback internRecvSSLCb;
private WolfSSLIOSendCallback internSendSSLCb;

/* have session tickets been enabled for this session? */
private boolean sessionTicketsEnabled = true;

/* is this context active, or has it been freed? */
private boolean active = false;

Expand Down Expand Up @@ -508,16 +511,26 @@ public int getFd()
* before calling <code>newSSL()</code>, though it's not recommended.
*
* @return <code>SSL_SUCCESS</code> if successful, otherwise
* <code>SSL_FATAL_ERROR</code> if an error occurred. To get
* <code>SSL_FAILURE</code> if an error occurred. To get
* a more detailed error code, call <code>getError()</code>.
* @throws IllegalStateException WolfSSLContext has been freed
* @throws SocketTimeoutException if underlying socket timed out
*/
public int connect() throws IllegalStateException {
public int connect() throws IllegalStateException, SocketTimeoutException {

int ret = 0;

if (this.active == false)
throw new IllegalStateException("Object has been freed");

return connect(getSessionPtr(), 0);
ret = connect(getSessionPtr(), 0);

if (ret == WolfSSL.WOLFJNI_TIMEOUT) {
throw new SocketTimeoutException(
"Native socket timed out during SSL_connect()");
}

return ret;
}

/**
Expand Down Expand Up @@ -2710,10 +2723,33 @@ public int useSNI(byte type, byte[] data) throws IllegalStateException {
*/
public int useSessionTicket() throws IllegalStateException {

int ret;

if (this.active == false)
throw new IllegalStateException("Object has been freed");

ret = useSessionTicket(getSessionPtr());
if (ret == WolfSSL.SSL_SUCCESS) {
this.sessionTicketsEnabled = true;
}

return ret;
}

/**
* Determine if session tickets have been enabled for this session.
* Session tickets can be enabled for this session by calling
* WolfSSLSession.useSessionTicket().
*
* @return true if enabled, otherwise false.
* @throws IllegalStateException WolfSSLSession has been freed
*/
public boolean sessionTicketsEnabled() throws IllegalStateException {

if (this.active == false)
throw new IllegalStateException("Object has been freed");

return useSessionTicket(getSessionPtr());
return this.sessionTicketsEnabled;
}

/**
Expand Down
6 changes: 5 additions & 1 deletion src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,11 @@ private int ClosingConnection() {
this.outBoundOpen = false;
hs = SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
}
else if (ret == WolfSSL.SSL_SHUTDOWN_NOT_DONE) {
/* wolfSSL_shutdown() will return either SSL_SHUTDOWN_NOT_DONE (2), or
* will map that to 0 if WOLFSSL_ERROR_CODE_OPENSSL is defined. Either
* should indicate that the full bidirectional shutdown has not
* completed. */
else if (ret == WolfSSL.SSL_SHUTDOWN_NOT_DONE || ret == 0) {
hs = SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ protected int doHandshake(int isSSLEngine, int timeout)
if (this.clientMode) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"calling native wolfSSL_connect()");
/* may throw SocketTimeoutException on socket timeout */
ret = this.ssl.connect(timeout);

} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,9 @@ public synchronized byte[] getId() {
return new byte[0];
}
try {
if (this.ssl.getVersion().equals("TLSv1.3")) {
/* use pseudo session ID if session tickets are being used */
if (this.ssl.getVersion().equals("TLSv1.3") ||
this.ssl.sessionTicketsEnabled()) {
return this.pseudoSessionID;
}
else {
Expand Down
43 changes: 30 additions & 13 deletions src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java
Original file line number Diff line number Diff line change
Expand Up @@ -1130,25 +1130,29 @@ synchronized public void startHandshake() throws IOException {
"entered startHandshake()");

synchronized (handshakeLock) {
if (handshakeInitCalled == true || handshakeComplete == true) {
/* handshake already started or finished */
if (handshakeComplete == true) {
/* handshake already finished */
return;
}

if (handshakeInitCalled == false) {
/* will throw SSLHandshakeException if session creation is
not allowed */
EngineHelper.initHandshake();
handshakeInitCalled = true;
}
}

synchronized (ioLock) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"thread got ioLock (handshake)");

/* will throw SSLHandshakeException if session creation is
not allowed */
EngineHelper.initHandshake();
handshakeInitCalled = true;

try {
ret = EngineHelper.doHandshake(0, this.getSoTimeout());
} catch (SocketTimeoutException e) {
throw new IOException(e);
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"got socket timeout in doHandshake()");
throw e;
}

WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
Expand Down Expand Up @@ -1781,8 +1785,15 @@ public int read(byte[] b, int off, int len)
}

/* do handshake if not completed yet, handles synchronization */
if (socket.handshakeComplete == false) {
socket.startHandshake();
try {
/* do handshake if not completed yet, handles synchronization */
if (socket.handshakeComplete == false) {
socket.startHandshake();
}
} catch (SocketTimeoutException e) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"got socket timeout in read()");
throw e;
}

if (b.length == 0 || len == 0) {
Expand Down Expand Up @@ -1899,9 +1910,15 @@ public void write(byte[] b, int off, int len) throws IOException {
}
}

/* do handshake if not completed yet, handles synchronization */
if (socket.handshakeComplete == false) {
socket.startHandshake();
try {
/* do handshake if not completed yet, handles synchronization */
if (socket.handshakeComplete == false) {
socket.startHandshake();
}
} catch (SocketTimeoutException e) {
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
"got socket timeout in write()");
throw e;
}

if (off < 0 || len < 0 || (off + len) > b.length) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -525,8 +525,10 @@ public Void call() throws Exception {
fail();

} catch (SSLHandshakeException e) {
/* expected */
if (!e.toString().contains("ASN no signer")) {
/* Expected. Different versions of wolfSSL can display
* varying error strings. Check for either here. */
if (!e.toString().contains("ASN no signer") &&
!e.toString().contains("certificate verify failed")) {
System.out.println("\t\t... failed");
fail();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -466,8 +466,8 @@ protected int testConnection(SSLEngine server, SSLEngine client,
printHex(serToCli);
}

System.out.println("cliToSer remaning = " + cliToSer.remaining());
System.out.println("serToCli remaning = " + serToCli.remaining());
System.out.println("cliToSer remaining = " + cliToSer.remaining());
System.out.println("serToCli remaining = " + serToCli.remaining());
}
result = client.unwrap(serToCli, cliPlain);
if (extraDebug) {
Expand Down
5 changes: 5 additions & 0 deletions src/test/com/wolfssl/test/WolfSSLSessionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import java.net.Socket;
import java.net.UnknownHostException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import com.wolfssl.WolfSSL;
import com.wolfssl.WolfSSLContext;
Expand Down Expand Up @@ -459,6 +460,10 @@ public void test_WolfSSLSession_UseAfterFree() {
} catch (IllegalStateException ise) {
System.out.println("\t\t... passed");
return;
} catch (SocketTimeoutException e) {
System.out.println("\t\t... failed");
e.printStackTrace();
return;
}

/* fail here means WolfSSLSession was used after free without
Expand Down

0 comments on commit e56b05b

Please sign in to comment.