Skip to content

Commit e56b05b

Browse files
Merge pull request #100 from cconlon/connectTimeout
Throw SocketTimeoutException from WolfSSLSession.connect()
2 parents 193361e + 488d6e7 commit e56b05b

11 files changed

Lines changed: 107 additions & 26 deletions

native/com_wolfssl_WolfSSL.h

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

native/com_wolfssl_WolfSSLSession.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,7 +554,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_getFd
554554
/* enum values used in socketSelect() */
555555
enum {
556556
WOLFJNI_SELECT_FAIL = -10,
557-
WOLFJNI_TIMEOUT = -11,
557+
WOLFJNI_TIMEOUT = -11, /* also in WolfSSL.java */
558558
WOLFJNI_RECV_READY = -12,
559559
WOLFJNI_SEND_READY = -13,
560560
WOLFJNI_ERROR_READY = -14
@@ -623,7 +623,7 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect
623623
(void)jcl;
624624

625625
if (jenv == NULL || ssl == NULL) {
626-
return SSL_FATAL_ERROR;
626+
return SSL_FAILURE;
627627
}
628628

629629
/* make sure we don't have any outstanding exceptions pending */
@@ -674,8 +674,12 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_connect
674674
if (ret == WOLFJNI_RECV_READY || ret == WOLFJNI_SEND_READY) {
675675
/* I/O ready, continue handshake and try again */
676676
continue;
677+
} else if (ret == WOLFJNI_TIMEOUT) {
678+
/* Java will throw SocketTimeoutException */
679+
break;
677680
} else {
678-
/* error or timeout */
681+
/* error */
682+
ret = SSL_FAILURE;
679683
break;
680684
}
681685
}
@@ -745,6 +749,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_WolfSSLSession_write
745749
break;
746750
}
747751

752+
if (ret >= 0) /* return if it is success */
753+
break;
754+
748755
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) {
749756

750757
sockfd = wolfSSL_get_fd(ssl);

src/java/com/wolfssl/WolfSSL.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ public static enum TLS_VERSION {
5656
/** Session unavailable */
5757
public final static int JNI_SESSION_UNAVAILABLE = -10001;
5858

59+
/**
60+
* Socket timed out, matches com_wolfssl_WolfSSLSession.c socketSelect()
61+
* return value */
62+
public final static int WOLFJNI_TIMEOUT = -11;
63+
5964
/* ----------------------- wolfSSL codes ---------------------------- */
6065

6166
/** Error code: no error */

src/java/com/wolfssl/WolfSSLSession.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ public class WolfSSLSession {
6565
private WolfSSLIORecvCallback internRecvSSLCb;
6666
private WolfSSLIOSendCallback internSendSSLCb;
6767

68+
/* have session tickets been enabled for this session? */
69+
private boolean sessionTicketsEnabled = true;
70+
6871
/* is this context active, or has it been freed? */
6972
private boolean active = false;
7073

@@ -508,16 +511,26 @@ public int getFd()
508511
* before calling <code>newSSL()</code>, though it's not recommended.
509512
*
510513
* @return <code>SSL_SUCCESS</code> if successful, otherwise
511-
* <code>SSL_FATAL_ERROR</code> if an error occurred. To get
514+
* <code>SSL_FAILURE</code> if an error occurred. To get
512515
* a more detailed error code, call <code>getError()</code>.
513516
* @throws IllegalStateException WolfSSLContext has been freed
517+
* @throws SocketTimeoutException if underlying socket timed out
514518
*/
515-
public int connect() throws IllegalStateException {
519+
public int connect() throws IllegalStateException, SocketTimeoutException {
520+
521+
int ret = 0;
516522

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

520-
return connect(getSessionPtr(), 0);
526+
ret = connect(getSessionPtr(), 0);
527+
528+
if (ret == WolfSSL.WOLFJNI_TIMEOUT) {
529+
throw new SocketTimeoutException(
530+
"Native socket timed out during SSL_connect()");
531+
}
532+
533+
return ret;
521534
}
522535

523536
/**
@@ -2710,10 +2723,33 @@ public int useSNI(byte type, byte[] data) throws IllegalStateException {
27102723
*/
27112724
public int useSessionTicket() throws IllegalStateException {
27122725

2726+
int ret;
2727+
2728+
if (this.active == false)
2729+
throw new IllegalStateException("Object has been freed");
2730+
2731+
ret = useSessionTicket(getSessionPtr());
2732+
if (ret == WolfSSL.SSL_SUCCESS) {
2733+
this.sessionTicketsEnabled = true;
2734+
}
2735+
2736+
return ret;
2737+
}
2738+
2739+
/**
2740+
* Determine if session tickets have been enabled for this session.
2741+
* Session tickets can be enabled for this session by calling
2742+
* WolfSSLSession.useSessionTicket().
2743+
*
2744+
* @return true if enabled, otherwise false.
2745+
* @throws IllegalStateException WolfSSLSession has been freed
2746+
*/
2747+
public boolean sessionTicketsEnabled() throws IllegalStateException {
2748+
27132749
if (this.active == false)
27142750
throw new IllegalStateException("Object has been freed");
27152751

2716-
return useSessionTicket(getSessionPtr());
2752+
return this.sessionTicketsEnabled;
27172753
}
27182754

27192755
/**

src/java/com/wolfssl/provider/jsse/WolfSSLEngine.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,11 @@ private int ClosingConnection() {
203203
this.outBoundOpen = false;
204204
hs = SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING;
205205
}
206-
else if (ret == WolfSSL.SSL_SHUTDOWN_NOT_DONE) {
206+
/* wolfSSL_shutdown() will return either SSL_SHUTDOWN_NOT_DONE (2), or
207+
* will map that to 0 if WOLFSSL_ERROR_CODE_OPENSSL is defined. Either
208+
* should indicate that the full bidirectional shutdown has not
209+
* completed. */
210+
else if (ret == WolfSSL.SSL_SHUTDOWN_NOT_DONE || ret == 0) {
207211
hs = SSLEngineResult.HandshakeStatus.NEED_UNWRAP;
208212
}
209213
else {

src/java/com/wolfssl/provider/jsse/WolfSSLEngineHelper.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@ protected int doHandshake(int isSSLEngine, int timeout)
697697
if (this.clientMode) {
698698
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
699699
"calling native wolfSSL_connect()");
700+
/* may throw SocketTimeoutException on socket timeout */
700701
ret = this.ssl.connect(timeout);
701702

702703
} else {

src/java/com/wolfssl/provider/jsse/WolfSSLImplementSSLSession.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,9 @@ public synchronized byte[] getId() {
137137
return new byte[0];
138138
}
139139
try {
140-
if (this.ssl.getVersion().equals("TLSv1.3")) {
140+
/* use pseudo session ID if session tickets are being used */
141+
if (this.ssl.getVersion().equals("TLSv1.3") ||
142+
this.ssl.sessionTicketsEnabled()) {
141143
return this.pseudoSessionID;
142144
}
143145
else {

src/java/com/wolfssl/provider/jsse/WolfSSLSocket.java

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,25 +1130,29 @@ synchronized public void startHandshake() throws IOException {
11301130
"entered startHandshake()");
11311131

11321132
synchronized (handshakeLock) {
1133-
if (handshakeInitCalled == true || handshakeComplete == true) {
1134-
/* handshake already started or finished */
1133+
if (handshakeComplete == true) {
1134+
/* handshake already finished */
11351135
return;
11361136
}
1137+
1138+
if (handshakeInitCalled == false) {
1139+
/* will throw SSLHandshakeException if session creation is
1140+
not allowed */
1141+
EngineHelper.initHandshake();
1142+
handshakeInitCalled = true;
1143+
}
11371144
}
11381145

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

1143-
/* will throw SSLHandshakeException if session creation is
1144-
not allowed */
1145-
EngineHelper.initHandshake();
1146-
handshakeInitCalled = true;
1147-
11481150
try {
11491151
ret = EngineHelper.doHandshake(0, this.getSoTimeout());
11501152
} catch (SocketTimeoutException e) {
1151-
throw new IOException(e);
1153+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1154+
"got socket timeout in doHandshake()");
1155+
throw e;
11521156
}
11531157

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

17831787
/* do handshake if not completed yet, handles synchronization */
1784-
if (socket.handshakeComplete == false) {
1785-
socket.startHandshake();
1788+
try {
1789+
/* do handshake if not completed yet, handles synchronization */
1790+
if (socket.handshakeComplete == false) {
1791+
socket.startHandshake();
1792+
}
1793+
} catch (SocketTimeoutException e) {
1794+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1795+
"got socket timeout in read()");
1796+
throw e;
17861797
}
17871798

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

1902-
/* do handshake if not completed yet, handles synchronization */
1903-
if (socket.handshakeComplete == false) {
1904-
socket.startHandshake();
1913+
try {
1914+
/* do handshake if not completed yet, handles synchronization */
1915+
if (socket.handshakeComplete == false) {
1916+
socket.startHandshake();
1917+
}
1918+
} catch (SocketTimeoutException e) {
1919+
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
1920+
"got socket timeout in write()");
1921+
throw e;
19051922
}
19061923

19071924
if (off < 0 || len < 0 || (off + len) > b.length) {

src/test/com/wolfssl/provider/jsse/test/WolfSSLServerSocketTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -525,8 +525,10 @@ public Void call() throws Exception {
525525
fail();
526526

527527
} catch (SSLHandshakeException e) {
528-
/* expected */
529-
if (!e.toString().contains("ASN no signer")) {
528+
/* Expected. Different versions of wolfSSL can display
529+
* varying error strings. Check for either here. */
530+
if (!e.toString().contains("ASN no signer") &&
531+
!e.toString().contains("certificate verify failed")) {
530532
System.out.println("\t\t... failed");
531533
fail();
532534
}

src/test/com/wolfssl/provider/jsse/test/WolfSSLTestFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,8 +466,8 @@ protected int testConnection(SSLEngine server, SSLEngine client,
466466
printHex(serToCli);
467467
}
468468

469-
System.out.println("cliToSer remaning = " + cliToSer.remaining());
470-
System.out.println("serToCli remaning = " + serToCli.remaining());
469+
System.out.println("cliToSer remaining = " + cliToSer.remaining());
470+
System.out.println("serToCli remaining = " + serToCli.remaining());
471471
}
472472
result = client.unwrap(serToCli, cliPlain);
473473
if (extraDebug) {

0 commit comments

Comments
 (0)