Time out TLS/SSL sessions after 8 hours by default.

Prior to this change TLS/SSL sessions did not time out.

(cherry picked from commit e5992c842c07c472f7ea3efbcc7f133fcc022592)

Bug: 18369043
Bug: 18370076
Change-Id: I596423b9c56bfc5f337a17aba02fbb9a9f2ded36
diff --git a/src/main/java/org/conscrypt/AbstractSessionContext.java b/src/main/java/org/conscrypt/AbstractSessionContext.java
index 0ba06ea..9eb2f7f 100644
--- a/src/main/java/org/conscrypt/AbstractSessionContext.java
+++ b/src/main/java/org/conscrypt/AbstractSessionContext.java
@@ -38,8 +38,14 @@
  */
 abstract class AbstractSessionContext implements SSLSessionContext {
 
+    /**
+     * Maximum lifetime of a session (in seconds) after which it's considered invalid and should not
+     * be used to for new connections.
+     */
+    private static final int DEFAULT_SESSION_TIMEOUT_SECONDS = 8 * 60 * 60;
+
     volatile int maximumSize;
-    volatile int timeout;
+    volatile int timeout = DEFAULT_SESSION_TIMEOUT_SECONDS;
 
     final long sslCtxNativePointer = NativeCrypto.SSL_CTX_new();
 
@@ -64,11 +70,9 @@
      * Constructs a new session context.
      *
      * @param maximumSize of cache
-     * @param timeout for cache entries
      */
-    AbstractSessionContext(int maximumSize, int timeout) {
+    AbstractSessionContext(int maximumSize) {
         this.maximumSize = maximumSize;
-        this.timeout = timeout;
     }
 
     /**
diff --git a/src/main/java/org/conscrypt/ClientSessionContext.java b/src/main/java/org/conscrypt/ClientSessionContext.java
index d2e23c9..62dd8dd 100644
--- a/src/main/java/org/conscrypt/ClientSessionContext.java
+++ b/src/main/java/org/conscrypt/ClientSessionContext.java
@@ -36,7 +36,7 @@
     private SSLClientSessionCache persistentCache;
 
     public ClientSessionContext() {
-        super(10, 0);
+        super(10);
     }
 
     public int size() {
diff --git a/src/main/java/org/conscrypt/OpenSSLSessionImpl.java b/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
index ef95ee6..c69c27a 100644
--- a/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
+++ b/src/main/java/org/conscrypt/OpenSSLSessionImpl.java
@@ -358,15 +358,35 @@
      */
     @Override
     public boolean isValid() {
-        SSLSessionContext context = sessionContext;
-        if (isValid
-                && context != null
-                && context.getSessionTimeout() != 0
-                && getCreationTime() + (context.getSessionTimeout() * 1000)
-                    < System.currentTimeMillis()) {
-            isValid = false;
+        if (!isValid) {
+            return false;
         }
-        return isValid;
+        // The session has't yet been invalidated -- check whether it timed out.
+
+        SSLSessionContext context = sessionContext;
+        if (context == null) {
+            // Session not associated with a context -- no way to tell what its timeout should be.
+            return true;
+        }
+
+        int timeoutSeconds = context.getSessionTimeout();
+        if (timeoutSeconds == 0) {
+            // Infinite timeout -- session still valid
+            return true;
+        }
+
+        long creationTimestampMillis = getCreationTime();
+        long ageSeconds = (System.currentTimeMillis() - creationTimestampMillis) / 1000;
+        // NOTE: The age might be negative if something was/is wrong with the system clock. We time
+        // out such sessions to be safe.
+        if ((ageSeconds >= timeoutSeconds) || (ageSeconds < 0)) {
+            // Session timed out -- no longer valid
+            isValid = false;
+            return false;
+        }
+
+        // Session still valid
+        return true;
     }
 
     /**
diff --git a/src/main/java/org/conscrypt/ServerSessionContext.java b/src/main/java/org/conscrypt/ServerSessionContext.java
index 3136431..75ba098 100644
--- a/src/main/java/org/conscrypt/ServerSessionContext.java
+++ b/src/main/java/org/conscrypt/ServerSessionContext.java
@@ -27,7 +27,7 @@
     private SSLServerSessionCache persistentCache;
 
     public ServerSessionContext() {
-        super(100, 0);
+        super(100);
 
         // TODO make sure SSL_CTX does not automaticaly clear sessions we want it to cache
         // SSL_CTX_set_session_cache_mode(sslCtxNativePointer, SSL_SESS_CACHE_NO_AUTO_CLEAR);