Skip to content

Commit 72732f0

Browse files
authored
Merge pull request #64 from JacobBarthelmeh/jsse
initial refactor of SSLSessionContext implementation
2 parents e8805ad + ee2a6ee commit 72732f0

11 files changed

Lines changed: 969 additions & 236 deletions

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

Lines changed: 139 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@
3737
import java.security.KeyManagementException;
3838
import java.security.NoSuchAlgorithmException;
3939
import java.security.UnrecoverableKeyException;
40+
import java.util.ArrayList;
41+
import java.util.Arrays;
42+
import java.util.Collections;
43+
import java.util.Date;
44+
import java.util.Enumeration;
4045
import java.util.LinkedHashMap;
46+
import java.util.List;
4147
import java.util.Map;
4248

4349
/**
@@ -61,6 +67,8 @@ static enum TLS_VERSION {
6167
private SecureRandom sr = null;
6268
private String alias = null;
6369
private SessionStore<Integer, WolfSSLImplementSSLSession> store;
70+
private WolfSSLSessionContext serverCtx = null;
71+
private WolfSSLSessionContext clientCtx = null;
6472

6573
/**
6674
* @param keyman key manager to use
@@ -73,6 +81,7 @@ static enum TLS_VERSION {
7381
protected WolfSSLAuthStore(KeyManager[] keyman, TrustManager[] trustman,
7482
SecureRandom random, TLS_VERSION version)
7583
throws IllegalArgumentException, KeyManagementException {
84+
int defaultCacheSize = 10;
7685

7786
if (version == TLS_VERSION.INVALID) {
7887
throw new IllegalArgumentException("Invalid SSL/TLS version");
@@ -86,8 +95,10 @@ protected WolfSSLAuthStore(KeyManager[] keyman, TrustManager[] trustman,
8695
initSecureRandom(random);
8796

8897
this.currentVersion = version;
89-
store = new SessionStore<Integer, WolfSSLImplementSSLSession>(10);
90-
//@TODO set max size correctly
98+
store = new SessionStore<Integer,
99+
WolfSSLImplementSSLSession>(defaultCacheSize);
100+
this.serverCtx = new WolfSSLSessionContext(this, defaultCacheSize, WolfSSL.WOLFSSL_SERVER_END);
101+
this.clientCtx = new WolfSSLSessionContext(this, defaultCacheSize, WolfSSL.WOLFSSL_CLIENT_END);
91102
}
92103

93104
/**
@@ -227,6 +238,39 @@ protected String getCertAlias() {
227238
return this.alias;
228239
}
229240

241+
242+
/**
243+
* Getter function for WolfSSLSessionContext associated with store
244+
* @return pointer to the context set
245+
*/
246+
protected WolfSSLSessionContext getServerContext() {
247+
return this.serverCtx;
248+
}
249+
250+
251+
/**
252+
* Getter function for WolfSSLSessionContext associated with store
253+
* @return pointer to the context set
254+
*/
255+
protected WolfSSLSessionContext getClientContext() {
256+
return this.clientCtx;
257+
}
258+
259+
260+
/**
261+
* Reset the size of the array to cache sessions
262+
* @param sz new array size
263+
* @param side server/client side for cache resize
264+
*/
265+
protected void resizeCache(int sz, int side) {
266+
SessionStore<Integer, WolfSSLImplementSSLSession> newStore =
267+
new SessionStore<Integer, WolfSSLImplementSSLSession>(sz);
268+
269+
//@TODO check for side server/client, currently a resize is for all
270+
store.putAll(newStore);
271+
store = newStore;
272+
}
273+
230274
/** Returns either an existing session to use or creates a new session. Can
231275
* return null on error case or the case where session could not be created.
232276
* @param ssl WOLFSSL class to set in session
@@ -261,6 +305,8 @@ protected WolfSSLImplementSSLSession getSession(WolfSSLSession ssl,
261305
"session not found in cache table, creating new");
262306
/* not found in stored sessions create a new one */
263307
ses = new WolfSSLImplementSSLSession(ssl, port, host, this);
308+
ses.setValid(true); /* new sessions marked as valid */
309+
ses.setPseudoSessionId(Integer.toString(ssl.hashCode()).getBytes());
264310
}
265311
else {
266312
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
@@ -277,7 +323,12 @@ protected WolfSSLImplementSSLSession getSession(WolfSSLSession ssl,
277323
protected WolfSSLImplementSSLSession getSession(WolfSSLSession ssl) {
278324
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
279325
"creating new session");
280-
return new WolfSSLImplementSSLSession(ssl, this);
326+
WolfSSLImplementSSLSession ses = new WolfSSLImplementSSLSession(ssl, this);
327+
if (ses != null) {
328+
ses.setValid(true);
329+
ses.setPseudoSessionId(Integer.toString(ssl.hashCode()).getBytes());
330+
}
331+
return ses;
281332
}
282333

283334
/**
@@ -287,24 +338,105 @@ protected WolfSSLImplementSSLSession getSession(WolfSSLSession ssl) {
287338
*/
288339
protected int addSession(WolfSSLImplementSSLSession session) {
289340
String toHash;
341+
int hashCode = 0;
290342

291343
if (session.getPeerHost() != null) {
292344
/* register into session table for resumption */
293345
session.fromTable = true;
294346
toHash = session.getPeerHost().concat(Integer.toString(
295347
session.getPeerPort()));
296-
store.put(toHash.hashCode(), session);
297-
348+
hashCode = toHash.hashCode();
349+
}
350+
else {
351+
/* if no peer host is available then create hash key from
352+
* session id */
353+
hashCode = Arrays.toString(session.getId()).hashCode();
354+
}
298355

356+
if (hashCode != 0 && store.containsKey(hashCode) != true) {
299357
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
300358
"stored session in cache table (host: " +
301359
session.getPeerHost() + ", port: " +
302-
session.getPeerPort() + ")");
360+
session.getPeerPort() + ") " +
361+
"hashCode = " + hashCode + " side = " + session.getSide());
362+
store.put(hashCode, session);
303363
}
304-
305364
return WolfSSL.SSL_SUCCESS;
306365
}
307366

367+
368+
/**
369+
* Internal function to return a list of all session ID's
370+
* @param side server or client side to get list of ID's from
371+
* @return enumerated session IDs
372+
*/
373+
protected Enumeration<byte[]> getAllIDs(int side) {
374+
List<byte[]> ret = new ArrayList<byte[]>();
375+
376+
for (Object obj : store.values()) {
377+
WolfSSLImplementSSLSession current = (WolfSSLImplementSSLSession)obj;
378+
if (current.getSide() == side) {
379+
ret.add(current.getId());
380+
}
381+
}
382+
return Collections.enumeration(ret);
383+
}
384+
385+
386+
/**
387+
* Getter function for session with session id 'ID'
388+
* @param ID the session id to search for
389+
* @param side if the session is expected on the server or client side
390+
* @return session from the store that has session id 'ID'
391+
*/
392+
protected WolfSSLImplementSSLSession getSession(byte[] ID, int side) {
393+
WolfSSLImplementSSLSession ret = null;
394+
395+
for (Object obj : store.values()) {
396+
WolfSSLImplementSSLSession current = (WolfSSLImplementSSLSession)obj;
397+
if (current.getSide() == side &&
398+
java.util.Arrays.equals(ID, current.getId())) {
399+
ret = current;
400+
break;
401+
}
402+
}
403+
return ret;
404+
}
405+
406+
407+
/**
408+
* Goes through the list of sessions and checks for timeouts. If timed out
409+
* then the session is invalidated.
410+
* @param in the updated timeout value to check against
411+
* @param side server or client side getting the timeout update
412+
*/
413+
protected void updateTimeouts(int in, int side) {
414+
Date currentDate = new Date();
415+
long now = currentDate.getTime();
416+
417+
for (Object obj : store.values()) {
418+
long diff;
419+
WolfSSLImplementSSLSession current =
420+
(WolfSSLImplementSSLSession)obj;
421+
422+
if (current.getSide() == side) {
423+
/* difference in seconds */
424+
diff = (now - current.creation.getTime()) / 1000;
425+
426+
if (diff < 0) {
427+
/* session is from the future ... */ //@TODO
428+
429+
}
430+
431+
if (in > 0 && diff > in) {
432+
current.invalidate();
433+
}
434+
current.setNativeTimeout(in);
435+
}
436+
}
437+
}
438+
439+
308440
private class SessionStore<K, V> extends LinkedHashMap<K, V> {
309441
/**
310442
* user defined ID

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

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -437,33 +437,21 @@ protected SSLEngine engineCreateSSLEngine(String host, int port)
437437
/**
438438
* Returns the SSLServerSessionContext associated with this SSLContext.
439439
*
440-
* Not currently supported by wolfJSSE.
441-
*
442440
* @throws UnsupportedOperationException operation not yet supported
443441
*/
444442
@Override
445443
protected SSLSessionContext engineGetServerSessionContext() {
446-
447-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
448-
"entered engineGetServerSessionContext()");
449-
450-
throw new UnsupportedOperationException("Not supported by wolfJSSE");
444+
return authStore.getServerContext();
451445
}
452446

453447
/**
454448
* Returns the SSLClientSessionContext associated with this SSLContext.
455-
*
456-
* Not currently supported by wolfJSSE.
457-
*
449+
*
458450
* @throws UnsupportedOperationException operation not yet supported
459451
*/
460452
@Override
461453
protected SSLSessionContext engineGetClientSessionContext() {
462-
463-
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
464-
"entered engineGetClientSessionContext()");
465-
466-
throw new UnsupportedOperationException("Not supported by wolfJSSE");
454+
return authStore.getClientContext();
467455
}
468456

469457
/**

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

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ protected WolfSSLEngineHelper(WolfSSLSession ssl, WolfSSLAuthStore store,
101101
this.hostname = hostname;
102102
this.authStore = store;
103103
this.session = new WolfSSLImplementSSLSession(store);
104-
105104
WolfSSLDebug.log(getClass(), WolfSSLDebug.INFO,
106105
"created new WolfSSLEngineHelper(port: " + port +
107106
", hostname: " + hostname + ")");
@@ -479,6 +478,15 @@ protected void initHandshake() throws SSLException {
479478
this.session = this.authStore.getSession(ssl, this.port, this.hostname,
480479
this.clientMode);
481480

481+
if (this.session != null && this.clientMode) {
482+
this.session.setSessionContext(authStore.getClientContext());
483+
this.session.setSide(WolfSSL.WOLFSSL_CLIENT_END);
484+
}
485+
else {
486+
this.session.setSessionContext(authStore.getServerContext());
487+
this.session.setSide(WolfSSL.WOLFSSL_SERVER_END);
488+
}
489+
482490
if (this.session != null && this.sessionCreation == false &&
483491
!this.session.fromTable) {
484492
/* new handshakes can not be made in this case. */
@@ -492,8 +500,7 @@ protected void initHandshake() throws SSLException {
492500
throw new SSLHandshakeException("Session creation not allowed");
493501
}
494502

495-
if (this.session != null && this.clientMode == true &&
496-
this.sessionCreation) {
503+
if (this.session != null && this.sessionCreation) {
497504
/* can only add new sessions to the resumption table if session
498505
* creation is allowed */
499506
this.authStore.addSession(this.session);
@@ -507,6 +514,8 @@ protected void initHandshake() throws SSLException {
507514
* isSSLEngine param specifies if this is being called by an SSLEngine
508515
* or not. Should not loop on WANT_READ/WRITE for SSLEngine */
509516
protected int doHandshake(int isSSLEngine) throws SSLException {
517+
int ret, err;
518+
510519
if (!modeSet) {
511520
throw new SSLException("setUseClientMode has not been called");
512521
}
@@ -536,8 +545,6 @@ protected int doHandshake(int isSSLEngine) throws SSLException {
536545
this.session = this.authStore.getSession(ssl);
537546
}
538547

539-
int ret, err;
540-
541548
do {
542549
/* call connect() or accept() to do handshake, looping on
543550
* WANT_READ/WANT_WRITE errors in case underlying Socket is
@@ -565,7 +572,7 @@ protected int doHandshake(int isSSLEngine) throws SSLException {
565572
* Saves session on connection close for resumption
566573
*/
567574
protected void saveSession() {
568-
if (this.session.isValid()) {
575+
if (this.session != null && this.session.isValid()) {
569576
this.session.setResume();
570577
}
571578
}

0 commit comments

Comments
 (0)