Skip to content

Commit a2b8f76

Browse files
committed
BCJSSE: Only update session lastAccessedTime at resumption
1 parent ba462e2 commit a2b8f76

File tree

5 files changed

+44
-32
lines changed

5 files changed

+44
-32
lines changed

tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSession.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.util.List;
44
import java.util.concurrent.ConcurrentHashMap;
5+
import java.util.concurrent.atomic.AtomicLong;
56

67
import org.bouncycastle.jsse.BCSNIServerName;
78
import org.bouncycastle.tls.CipherSuite;
@@ -15,6 +16,7 @@ class ProvSSLSession
1516
protected final TlsSession tlsSession;
1617
protected final SessionParameters sessionParameters;
1718
protected final JsseSessionParameters jsseSessionParameters;
19+
protected final AtomicLong lastAccessedTime;
1820

1921
ProvSSLSession(ProvSSLSessionContext sslSessionContext, ConcurrentHashMap<String, Object> valueMap, String peerHost,
2022
int peerPort, long creationTime, TlsSession tlsSession, JsseSessionParameters jsseSessionParameters)
@@ -24,6 +26,18 @@ class ProvSSLSession
2426
this.tlsSession = tlsSession;
2527
this.sessionParameters = tlsSession == null ? null : tlsSession.exportSessionParameters();
2628
this.jsseSessionParameters = jsseSessionParameters;
29+
this.lastAccessedTime = new AtomicLong(creationTime);
30+
}
31+
32+
long access()
33+
{
34+
long accessTime = getCurrentTime(), previous;
35+
do
36+
{
37+
previous = lastAccessedTime.get();
38+
}
39+
while (accessTime > previous && !lastAccessedTime.compareAndSet(previous, accessTime));
40+
return accessTime;
2741
}
2842

2943
@Override
@@ -50,6 +64,11 @@ protected JsseSessionParameters getJsseSessionParameters()
5064
return jsseSessionParameters;
5165
}
5266

67+
public long getLastAccessedTime()
68+
{
69+
return lastAccessedTime.get();
70+
}
71+
5372
@Override
5473
protected org.bouncycastle.tls.Certificate getLocalCertificateTLS()
5574
{
@@ -110,7 +129,7 @@ public boolean isValid()
110129
static final ProvSSLSession createDummySession()
111130
{
112131
// NB: Allow session value binding on failed connections for SunJSSE compatibility
113-
return new ProvSSLSession(null, createValueMap(), null, -1, createCreationTime(), null,
132+
return new ProvSSLSession(null, createValueMap(), null, -1, getCurrentTime(), null,
114133
new JsseSessionParameters(null, null));
115134
}
116135
}

tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionBase.java

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.security.cert.Certificate;
55
import java.security.cert.X509Certificate;
66
import java.util.concurrent.ConcurrentHashMap;
7-
import java.util.concurrent.atomic.AtomicLong;
87
import java.util.concurrent.atomic.AtomicReference;
98

109
import javax.net.ssl.SSLPeerUnverifiedException;
@@ -33,7 +32,6 @@ abstract class ProvSSLSessionBase
3332
protected final int peerPort;
3433
protected final long creationTime;
3534
protected final SSLSession exportSSLSession;
36-
protected final AtomicLong lastAccessedTime;
3735

3836
ProvSSLSessionBase(ProvSSLSessionContext sslSessionContext, ConcurrentHashMap<String, Object> valueMap,
3937
String peerHost, int peerPort, long creationTime)
@@ -46,7 +44,6 @@ abstract class ProvSSLSessionBase
4644
this.peerPort = peerPort;
4745
this.creationTime = creationTime;
4846
this.exportSSLSession = SSLSessionUtil.exportSSLSession(this);
49-
this.lastAccessedTime = new AtomicLong(creationTime);
5047
}
5148

5249
protected abstract int getCipherSuiteTLS();
@@ -70,15 +67,6 @@ SSLSession getExportSSLSession()
7067
return exportSSLSession;
7168
}
7269

73-
void accessedAt(long accessTime)
74-
{
75-
long current = lastAccessedTime.get();
76-
if (accessTime > current)
77-
{
78-
lastAccessedTime.compareAndSet(current, accessTime);
79-
}
80-
}
81-
8270
@Override
8371
public boolean equals(Object obj)
8472
{
@@ -117,11 +105,6 @@ public byte[] getId()
117105
return TlsUtils.isNullOrEmpty(id) ? TlsUtils.EMPTY_BYTES : id.clone();
118106
}
119107

120-
public long getLastAccessedTime()
121-
{
122-
return lastAccessedTime.get();
123-
}
124-
125108
public Certificate[] getLocalCertificates()
126109
{
127110
if (null != crypto)
@@ -358,13 +341,13 @@ private void implInvalidate(boolean removeFromSessionContext)
358341
invalidateTLS();
359342
}
360343

361-
protected static long createCreationTime()
344+
protected static ConcurrentHashMap<String, Object> createValueMap()
362345
{
363-
return System.currentTimeMillis();
346+
return new ConcurrentHashMap<String, Object>();
364347
}
365348

366-
protected static ConcurrentHashMap<String, Object> createValueMap()
349+
protected static long getCurrentTime()
367350
{
368-
return new ConcurrentHashMap<String, Object>();
351+
return System.currentTimeMillis();
369352
}
370353
}

tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionContext.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,15 @@ synchronized ProvSSLSession getSessionImpl(byte[] sessionID)
6363
{
6464
processQueue();
6565

66-
return accessSession(mapGet(sessionsByID, makeSessionID(sessionID)));
66+
return getSessionImpl(mapGet(sessionsByID, makeSessionID(sessionID)));
6767
}
6868

6969
synchronized ProvSSLSession getSessionImpl(String hostName, int port)
7070
{
7171
processQueue();
7272

7373
SessionEntry sessionEntry = mapGet(sessionsByPeer, makePeerKey(hostName, port));
74-
ProvSSLSession session = accessSession(sessionEntry);
74+
ProvSSLSession session = getSessionImpl(sessionEntry);
7575
if (session != null)
7676
{
7777
// NOTE: For the current simple cache implementation, need to 'access' the sessionByIDs entry
@@ -207,17 +207,15 @@ public synchronized void setSessionTimeout(int seconds) throws IllegalArgumentEx
207207
removeAllExpiredSessions();
208208
}
209209

210-
private ProvSSLSession accessSession(SessionEntry sessionEntry)
210+
private ProvSSLSession getSessionImpl(SessionEntry sessionEntry)
211211
{
212212
if (sessionEntry != null)
213213
{
214214
ProvSSLSession session = sessionEntry.get();
215215
if (session != null)
216216
{
217-
long currentTimeMillis = System.currentTimeMillis();
218-
if (!invalidateIfCreatedBefore(sessionEntry, getCreationTimeLimit(currentTimeMillis)))
217+
if (!invalidateIfCreatedBefore(sessionEntry, getCreationTimeLimit()))
219218
{
220-
session.accessedAt(currentTimeMillis);
221219
return session;
222220
}
223221
}
@@ -227,9 +225,9 @@ private ProvSSLSession accessSession(SessionEntry sessionEntry)
227225
return null;
228226
}
229227

230-
private long getCreationTimeLimit(long expiryTimeMillis)
228+
private long getCreationTimeLimit()
231229
{
232-
return sessionTimeoutSeconds < 1 ? Long.MIN_VALUE : (expiryTimeMillis - 1000L * sessionTimeoutSeconds);
230+
return sessionTimeoutSeconds < 1 ? Long.MIN_VALUE : (System.currentTimeMillis() - 1000L * sessionTimeoutSeconds);
233231
}
234232

235233
private boolean invalidateIfCreatedBefore(SessionEntry sessionEntry, long creationTimeLimit)
@@ -267,7 +265,7 @@ private void removeAllExpiredSessions()
267265
{
268266
processQueue();
269267

270-
long creationTimeLimit = getCreationTimeLimit(System.currentTimeMillis());
268+
long creationTimeLimit = getCreationTimeLimit();
271269

272270
Iterator<SessionEntry> iter = sessionsByID.values().iterator();
273271
while (iter.hasNext())

tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionHandshake.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class ProvSSLSessionHandshake
2020
ProvSSLSessionHandshake(ProvSSLSessionContext sslSessionContext, String peerHost, int peerPort,
2121
SecurityParameters securityParameters, JsseSecurityParameters jsseSecurityParameters)
2222
{
23-
this(sslSessionContext, createValueMap(), peerHost, peerPort, createCreationTime(), securityParameters,
23+
this(sslSessionContext, createValueMap(), peerHost, peerPort, getCurrentTime(), securityParameters,
2424
jsseSecurityParameters);
2525
}
2626

@@ -63,6 +63,11 @@ protected JsseSessionParameters getJsseSessionParameters()
6363
return null;
6464
}
6565

66+
public long getLastAccessedTime()
67+
{
68+
return getCreationTime();
69+
}
70+
6671
@Override
6772
protected org.bouncycastle.tls.Certificate getLocalCertificateTLS()
6873
{

tls/src/main/java/org/bouncycastle/jsse/provider/ProvSSLSessionResumed.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class ProvSSLSessionResumed
1111
protected final TlsSession tlsSession;
1212
protected final SessionParameters sessionParameters;
1313
protected final JsseSessionParameters jsseSessionParameters;
14+
protected final long lastAccessedTime;
1415

1516
ProvSSLSessionResumed(ProvSSLSessionContext sslSessionContext, String peerHost, int peerPort,
1617
SecurityParameters securityParameters, JsseSecurityParameters jsseSecurityParameters,
@@ -22,6 +23,7 @@ class ProvSSLSessionResumed
2223
this.tlsSession = resumedSession.getTlsSession();
2324
this.sessionParameters = tlsSession.exportSessionParameters();
2425
this.jsseSessionParameters = resumedSession.getJsseSessionParameters();
26+
this.lastAccessedTime = resumedSession.access();
2527
}
2628

2729
@Override
@@ -36,6 +38,11 @@ protected byte[] getIDArray()
3638
return tlsSession.getSessionID();
3739
}
3840

41+
public long getLastAccessedTime()
42+
{
43+
return lastAccessedTime;
44+
}
45+
3946
@Override
4047
protected JsseSessionParameters getJsseSessionParameters()
4148
{

0 commit comments

Comments
 (0)