Add tests for session-ID-based resumption.

This implements session IDs in client and server in runner.go.

Change-Id: I26655f996b7b44c7eb56340ef6a415d3f2ac3503
Reviewed-on: https://boringssl-review.googlesource.com/2350
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go
index 01b7581..476a2a4 100644
--- a/ssl/test/runner/common.go
+++ b/ssl/test/runner/common.go
@@ -203,6 +203,7 @@
 // ClientSessionState contains the state needed by clients to resume TLS
 // sessions.
 type ClientSessionState struct {
+	sessionId            []uint8             // Session ID supplied by the server. nil if the session has a ticket.
 	sessionTicket        []uint8             // Encrypted ticket used for session resumption with server
 	vers                 uint16              // SSL/TLS version negotiated for the session
 	cipherSuite          uint16              // Ciphersuite negotiated for the session
@@ -225,6 +226,19 @@
 	Put(sessionKey string, cs *ClientSessionState)
 }
 
+// ServerSessionCache is a cache of sessionState objects that can be used by a
+// client to resume a TLS session with a given server. ServerSessionCache
+// implementations should expect to be called concurrently from different
+// goroutines.
+type ServerSessionCache interface {
+	// Get searches for a sessionState associated with the given session
+	// ID. On return, ok is true if one was found.
+	Get(sessionId string) (session *sessionState, ok bool)
+
+	// Put adds the sessionState to the cache with the given session ID.
+	Put(sessionId string, session *sessionState)
+}
+
 // A Config structure is used to configure a TLS client or server.
 // After one has been passed to a TLS function it must not be
 // modified. A Config may be reused; the tls package will also not
@@ -311,10 +325,14 @@
 	// connections using that key are compromised.
 	SessionTicketKey [32]byte
 
-	// SessionCache is a cache of ClientSessionState entries for TLS session
-	// resumption.
+	// ClientSessionCache is a cache of ClientSessionState entries
+	// for TLS session resumption.
 	ClientSessionCache ClientSessionCache
 
+	// ServerSessionCache is a cache of sessionState entries for TLS session
+	// resumption.
+	ServerSessionCache ServerSessionCache
+
 	// MinVersion contains the minimum SSL/TLS version that is acceptable.
 	// If zero, then SSLv3 is taken as the minimum.
 	MinVersion uint16
@@ -732,8 +750,8 @@
 	unmarshal([]byte) bool
 }
 
-// lruSessionCache is a ClientSessionCache implementation that uses an LRU
-// caching strategy.
+// lruSessionCache is a client or server session cache implementation
+// that uses an LRU caching strategy.
 type lruSessionCache struct {
 	sync.Mutex
 
@@ -744,27 +762,11 @@
 
 type lruSessionCacheEntry struct {
 	sessionKey string
-	state      *ClientSessionState
-}
-
-// NewLRUClientSessionCache returns a ClientSessionCache with the given
-// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
-// is used instead.
-func NewLRUClientSessionCache(capacity int) ClientSessionCache {
-	const defaultSessionCacheCapacity = 64
-
-	if capacity < 1 {
-		capacity = defaultSessionCacheCapacity
-	}
-	return &lruSessionCache{
-		m:        make(map[string]*list.Element),
-		q:        list.New(),
-		capacity: capacity,
-	}
+	state      interface{}
 }
 
 // Put adds the provided (sessionKey, cs) pair to the cache.
-func (c *lruSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+func (c *lruSessionCache) Put(sessionKey string, cs interface{}) {
 	c.Lock()
 	defer c.Unlock()
 
@@ -790,9 +792,9 @@
 	c.m[sessionKey] = elem
 }
 
-// Get returns the ClientSessionState value associated with a given key. It
-// returns (nil, false) if no value is found.
-func (c *lruSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+// Get returns the value associated with a given key. It returns (nil,
+// false) if no value is found.
+func (c *lruSessionCache) Get(sessionKey string) (interface{}, bool) {
 	c.Lock()
 	defer c.Unlock()
 
@@ -803,6 +805,78 @@
 	return nil, false
 }
 
+// lruClientSessionCache is a ClientSessionCache implementation that
+// uses an LRU caching strategy.
+type lruClientSessionCache struct {
+	lruSessionCache
+}
+
+func (c *lruClientSessionCache) Put(sessionKey string, cs *ClientSessionState) {
+	c.lruSessionCache.Put(sessionKey, cs)
+}
+
+func (c *lruClientSessionCache) Get(sessionKey string) (*ClientSessionState, bool) {
+	cs, ok := c.lruSessionCache.Get(sessionKey)
+	if !ok {
+		return nil, false
+	}
+	return cs.(*ClientSessionState), true
+}
+
+// lruServerSessionCache is a ServerSessionCache implementation that
+// uses an LRU caching strategy.
+type lruServerSessionCache struct {
+	lruSessionCache
+}
+
+func (c *lruServerSessionCache) Put(sessionId string, session *sessionState) {
+	c.lruSessionCache.Put(sessionId, session)
+}
+
+func (c *lruServerSessionCache) Get(sessionId string) (*sessionState, bool) {
+	cs, ok := c.lruSessionCache.Get(sessionId)
+	if !ok {
+		return nil, false
+	}
+	return cs.(*sessionState), true
+}
+
+// NewLRUClientSessionCache returns a ClientSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUClientSessionCache(capacity int) ClientSessionCache {
+	const defaultSessionCacheCapacity = 64
+
+	if capacity < 1 {
+		capacity = defaultSessionCacheCapacity
+	}
+	return &lruClientSessionCache{
+		lruSessionCache{
+			m:        make(map[string]*list.Element),
+			q:        list.New(),
+			capacity: capacity,
+		},
+	}
+}
+
+// NewLRUServerSessionCache returns a ServerSessionCache with the given
+// capacity that uses an LRU strategy. If capacity is < 1, a default capacity
+// is used instead.
+func NewLRUServerSessionCache(capacity int) ServerSessionCache {
+	const defaultSessionCacheCapacity = 64
+
+	if capacity < 1 {
+		capacity = defaultSessionCacheCapacity
+	}
+	return &lruServerSessionCache{
+		lruSessionCache{
+			m:        make(map[string]*list.Element),
+			q:        list.New(),
+			capacity: capacity,
+		},
+	}
+}
+
 // TODO(jsing): Make these available to both crypto/x509 and crypto/tls.
 type dsaSignature struct {
 	R, S *big.Int