/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file implements the CLIENT Session ID cache.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "cert.h"
#include "pk11pub.h"
#include "secitem.h"
#include "ssl.h"
#include "nss.h"

#include "sslimpl.h"
#include "sslproto.h"
#include "nssilock.h"
#include "sslencode.h"
#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
#include <time.h>
#endif

static sslSessionID *cache = NULL;
static PZLock *cacheLock = NULL;

/* sids can be in one of 5 states:
 *
 * never_cached,        created, but not yet put into cache.
 * in_client_cache,     in the client cache's linked list.
 * in_server_cache,     entry came from the server's cache file.
 * invalid_cache        has been removed from the cache.
 * in_external_cache    sid comes from an external cache.
 */

#define LOCK_CACHE lock_cache()
#define UNLOCK_CACHE PZ_Unlock(cacheLock)

static SECStatus
ssl_InitClientSessionCacheLock(void)
{
    cacheLock = PZ_NewLock(nssILockCache);
    return cacheLock ? SECSuccess : SECFailure;
}

static SECStatus
ssl_FreeClientSessionCacheLock(void)
{
    if (cacheLock) {
        PZ_DestroyLock(cacheLock);
        cacheLock = NULL;
        return SECSuccess;
    }
    PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
    return SECFailure;
}

static PRBool LocksInitializedEarly = PR_FALSE;

static SECStatus
FreeSessionCacheLocks()
{
    SECStatus rv1, rv2;
    rv1 = ssl_FreeSymWrapKeysLock();
    rv2 = ssl_FreeClientSessionCacheLock();
    if ((SECSuccess == rv1) && (SECSuccess == rv2)) {
        return SECSuccess;
    }
    return SECFailure;
}

static SECStatus
InitSessionCacheLocks(void)
{
    SECStatus rv1, rv2;
    PRErrorCode rc;
    rv1 = ssl_InitSymWrapKeysLock();
    rv2 = ssl_InitClientSessionCacheLock();
    if ((SECSuccess == rv1) && (SECSuccess == rv2)) {
        return SECSuccess;
    }
    rc = PORT_GetError();
    FreeSessionCacheLocks();
    PORT_SetError(rc);
    return SECFailure;
}

/* free the session cache locks if they were initialized early */
SECStatus
ssl_FreeSessionCacheLocks()
{
    PORT_Assert(PR_TRUE == LocksInitializedEarly);
    if (!LocksInitializedEarly) {
        PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
        return SECFailure;
    }
    FreeSessionCacheLocks();
    LocksInitializedEarly = PR_FALSE;
    return SECSuccess;
}

static PRCallOnceType lockOnce;

/* free the session cache locks if they were initialized lazily */
static SECStatus
ssl_ShutdownLocks(void *appData, void *nssData)
{
    PORT_Assert(PR_FALSE == LocksInitializedEarly);
    if (LocksInitializedEarly) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    FreeSessionCacheLocks();
    memset(&lockOnce, 0, sizeof(lockOnce));
    return SECSuccess;
}

static PRStatus
initSessionCacheLocksLazily(void)
{
    SECStatus rv = InitSessionCacheLocks();
    if (SECSuccess != rv) {
        return PR_FAILURE;
    }
    rv = NSS_RegisterShutdown(ssl_ShutdownLocks, NULL);
    PORT_Assert(SECSuccess == rv);
    if (SECSuccess != rv) {
        return PR_FAILURE;
    }
    return PR_SUCCESS;
}

/* lazyInit means that the call is not happening during a 1-time
 * initialization function, but rather during dynamic, lazy initialization
 */
SECStatus
ssl_InitSessionCacheLocks(PRBool lazyInit)
{
    if (LocksInitializedEarly) {
        return SECSuccess;
    }

    if (lazyInit) {
        return (PR_SUCCESS ==
                PR_CallOnce(&lockOnce, initSessionCacheLocksLazily))
                   ? SECSuccess
                   : SECFailure;
    }

    if (SECSuccess == InitSessionCacheLocks()) {
        LocksInitializedEarly = PR_TRUE;
        return SECSuccess;
    }

    return SECFailure;
}

static void
lock_cache(void)
{
    ssl_InitSessionCacheLocks(PR_TRUE);
    PZ_Lock(cacheLock);
}

/* BEWARE: This function gets called for both client and server SIDs !!
 * If the unreferenced sid is not in the cache, Free sid and its contents.
 */
void
ssl_DestroySID(sslSessionID *sid, PRBool freeIt)
{
    SSL_TRC(8, ("SSL: destroy sid: sid=0x%x cached=%d", sid, sid->cached));
    PORT_Assert(sid->references == 0);
    PORT_Assert(sid->cached != in_client_cache);

    if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
        SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
                         PR_FALSE);
    }
    if (sid->u.ssl3.srvName.data) {
        SECITEM_FreeItem(&sid->u.ssl3.srvName, PR_FALSE);
    }
    if (sid->u.ssl3.signedCertTimestamps.data) {
        SECITEM_FreeItem(&sid->u.ssl3.signedCertTimestamps, PR_FALSE);
    }

    if (sid->u.ssl3.lock) {
        PR_DestroyRWLock(sid->u.ssl3.lock);
    }

    PORT_Free((void *)sid->peerID);
    PORT_Free((void *)sid->urlSvrName);

    if (sid->peerCert) {
        CERT_DestroyCertificate(sid->peerCert);
    }
    if (sid->peerCertStatus.items) {
        SECITEM_FreeArray(&sid->peerCertStatus, PR_FALSE);
    }

    if (sid->localCert) {
        CERT_DestroyCertificate(sid->localCert);
    }

    SECITEM_FreeItem(&sid->u.ssl3.alpnSelection, PR_FALSE);

    if (freeIt) {
        PORT_ZFree(sid, sizeof(sslSessionID));
    }
}

/* BEWARE: This function gets called for both client and server SIDs !!
 * Decrement reference count, and
 *    free sid if ref count is zero, and sid is not in the cache.
 * Does NOT remove from the cache first.
 * If the sid is still in the cache, it is left there until next time
 * the cache list is traversed.
 */
static void
ssl_FreeLockedSID(sslSessionID *sid)
{
    PORT_Assert(sid->references >= 1);
    if (--sid->references == 0) {
        ssl_DestroySID(sid, PR_TRUE);
    }
}

/* BEWARE: This function gets called for both client and server SIDs !!
 * Decrement reference count, and
 *    free sid if ref count is zero, and sid is not in the cache.
 * Does NOT remove from the cache first.
 * These locks are necessary because the sid _might_ be in the cache list.
 */
void
ssl_FreeSID(sslSessionID *sid)
{
    if (sid) {
        LOCK_CACHE;
        ssl_FreeLockedSID(sid);
        UNLOCK_CACHE;
    }
}

sslSessionID *
ssl_ReferenceSID(sslSessionID *sid)
{
    LOCK_CACHE;
    sid->references++;
    UNLOCK_CACHE;
    return sid;
}

/************************************************************************/

/*
**  Lookup sid entry in cache by Address, port, and peerID string.
**  If found, Increment reference count, and return pointer to caller.
**  If it has timed out or ref count is zero, remove from list and free it.
*/

sslSessionID *
ssl_LookupSID(PRTime now, const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
              const char *urlSvrName)
{
    sslSessionID **sidp;
    sslSessionID *sid;

    if (!urlSvrName)
        return NULL;
    LOCK_CACHE;
    sidp = &cache;
    while ((sid = *sidp) != 0) {
        PORT_Assert(sid->cached == in_client_cache);
        PORT_Assert(sid->references >= 1);

        SSL_TRC(8, ("SSL: lookup: sid=0x%x", sid));

        if (sid->expirationTime < now) {
            /*
            ** This session-id timed out.
            ** Don't even care who it belongs to, blow it out of our cache.
            */
            SSL_TRC(7, ("SSL: lookup, throwing sid out, age=%d refs=%d",
                        now - sid->creationTime, sid->references));

            *sidp = sid->next;                                      /* delink it from the list. */
            sid->cached = invalid_cache;                            /* mark not on list. */
            ssl_FreeLockedSID(sid);                                 /* drop ref count, free. */
        } else if (!memcmp(&sid->addr, addr, sizeof(PRIPv6Addr)) && /* server IP addr matches */
                   (sid->port == port) &&                           /* server port matches */
                   /* proxy (peerID) matches */
                   (((peerID == NULL) && (sid->peerID == NULL)) ||
                    ((peerID != NULL) && (sid->peerID != NULL) &&
                     PORT_Strcmp(sid->peerID, peerID) == 0)) &&
                   /* is cacheable */
                   (sid->u.ssl3.keys.resumable) &&
                   /* server hostname matches. */
                   (sid->urlSvrName != NULL) &&
                   (0 == PORT_Strcmp(urlSvrName, sid->urlSvrName))) {
            /* Hit */
            sid->lastAccessTime = now;
            sid->references++;
            break;
        } else {
            sidp = &sid->next;
        }
    }
    UNLOCK_CACHE;
    return sid;
}

/*
** Add an sid to the cache or return a previously cached entry to the cache.
** Although this is static, it is called via ss->sec.cache().
*/
static void
CacheSID(sslSessionID *sid, PRTime creationTime)
{
    PORT_Assert(sid);
    PORT_Assert(sid->cached == never_cached);

    SSL_TRC(8, ("SSL: Cache: sid=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
                "time=%x cached=%d",
                sid, sid->cached, sid->addr.pr_s6_addr32[0],
                sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2],
                sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime,
                sid->cached));

    if (!sid->urlSvrName) {
        /* don't cache this SID because it can never be matched */
        return;
    }

    if (sid->u.ssl3.sessionIDLength == 0 &&
        sid->u.ssl3.locked.sessionTicket.ticket.data == NULL)
        return;

    /* Client generates the SessionID if this was a stateless resume. */
    if (sid->u.ssl3.sessionIDLength == 0) {
        SECStatus rv;
        rv = PK11_GenerateRandom(sid->u.ssl3.sessionID,
                                 SSL3_SESSIONID_BYTES);
        if (rv != SECSuccess)
            return;
        sid->u.ssl3.sessionIDLength = SSL3_SESSIONID_BYTES;
    }
    PRINT_BUF(8, (0, "sessionID:",
                  sid->u.ssl3.sessionID, sid->u.ssl3.sessionIDLength));

    sid->u.ssl3.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
    if (!sid->u.ssl3.lock) {
        return;
    }
    PORT_Assert(sid->creationTime != 0);
    if (!sid->creationTime) {
        sid->lastAccessTime = sid->creationTime = creationTime;
    }
    PORT_Assert(sid->expirationTime != 0);
    if (!sid->expirationTime) {
        sid->expirationTime = sid->creationTime + (PR_MIN(ssl_ticket_lifetime,
                                                          sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint) *
                                                   PR_USEC_PER_SEC);
    }

    /*
     * Put sid into the cache.  Bump reference count to indicate that
     * cache is holding a reference. Uncache will reduce the cache
     * reference.
     */
    LOCK_CACHE;
    sid->references++;
    sid->cached = in_client_cache;
    sid->next = cache;
    cache = sid;
    UNLOCK_CACHE;
}

/*
 * If sid "zap" is in the cache,
 *    removes sid from cache, and decrements reference count.
 * Caller must hold cache lock.
 */
static void
UncacheSID(sslSessionID *zap)
{
    sslSessionID **sidp = &cache;
    sslSessionID *sid;

    if (zap->cached != in_client_cache) {
        return;
    }

    SSL_TRC(8, ("SSL: Uncache: zap=0x%x cached=%d addr=0x%08x%08x%08x%08x port=0x%04x "
                "time=%x cipherSuite=%d",
                zap, zap->cached, zap->addr.pr_s6_addr32[0],
                zap->addr.pr_s6_addr32[1], zap->addr.pr_s6_addr32[2],
                zap->addr.pr_s6_addr32[3], zap->port, zap->creationTime,
                zap->u.ssl3.cipherSuite));

    /* See if it's in the cache, if so nuke it */
    while ((sid = *sidp) != 0) {
        if (sid == zap) {
            /*
            ** Bingo. Reduce reference count by one so that when
            ** everyone is done with the sid we can free it up.
            */
            *sidp = zap->next;
            zap->cached = invalid_cache;
            ssl_FreeLockedSID(zap);
            return;
        }
        sidp = &sid->next;
    }
}

/* If sid "zap" is in the cache,
 *    removes sid from cache, and decrements reference count.
 * Although this function is static, it is called externally via
 *    ssl_UncacheSessionID.
 */
static void
LockAndUncacheSID(sslSessionID *zap)
{
    LOCK_CACHE;
    UncacheSID(zap);
    UNLOCK_CACHE;
}

SECStatus
ReadVariableFromBuffer(sslReader *reader, sslReadBuffer *readerBuffer,
                       uint8_t lenBytes, SECItem *dest)
{
    if (sslRead_ReadVariable(reader, lenBytes, readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer->len) {
        SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer->buf,
                             readerBuffer->len };
        SECStatus rv = SECITEM_CopyItem(NULL, dest, &tempItem);
        if (rv != SECSuccess) {
            return rv;
        }
    }
    return SECSuccess;
}

/* Fill sid with the values from the encoded resumption token.
 * sid has to be allocated.
 * We don't care about locks here as this cache entry is externally stored.
 */
SECStatus
ssl_DecodeResumptionToken(sslSessionID *sid, const PRUint8 *encodedToken,
                          PRUint32 encodedTokenLen)
{
    PORT_Assert(encodedTokenLen);
    PORT_Assert(encodedToken);
    PORT_Assert(sid);
    if (!sid || !encodedToken || !encodedTokenLen) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (encodedToken[0] != SSLResumptionTokenVersion) {
        /* Unknown token format version. */
        PORT_SetError(SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR);
        return SECFailure;
    }

    /* These variables are used across macros. Don't use them outside. */
    sslReader reader = SSL_READER(encodedToken, encodedTokenLen);
    reader.offset += 1; // We read the version already. Skip the first byte.
    sslReadBuffer readerBuffer = { 0 };
    PRUint64 tmpInt = 0;

    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->lastAccessTime = (PRTime)tmpInt;
    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->expirationTime = (PRTime)tmpInt;
    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.locked.sessionTicket.received_timestamp = (PRTime)tmpInt;

    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint = (PRUint32)tmpInt;
    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.locked.sessionTicket.flags = (PRUint32)tmpInt;
    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.locked.sessionTicket.ticket_age_add = (PRUint32)tmpInt;
    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.locked.sessionTicket.max_early_data_size = (PRUint32)tmpInt;

    if (sslRead_ReadVariable(&reader, 3, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer.len) {
        PORT_Assert(!sid->peerCert);
        SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer.buf,
                             readerBuffer.len };
        sid->peerCert = CERT_NewTempCertificate(NULL, /* dbHandle */
                                                &tempItem,
                                                NULL, PR_FALSE, PR_TRUE);
        if (!sid->peerCert) {
            return SECFailure;
        }
    }

    if (sslRead_ReadVariable(&reader, 2, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer.len) {
        SECITEM_AllocArray(NULL, &sid->peerCertStatus, 1);
        if (!sid->peerCertStatus.items) {
            return SECFailure;
        }
        SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer.buf,
                             readerBuffer.len };
        SECITEM_CopyItem(NULL, &sid->peerCertStatus.items[0], &tempItem);
    }

    if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer.len) {
        PORT_Assert(readerBuffer.buf);
        if (sid->peerID) {
            PORT_Free((void *)sid->peerID);
        }
        sid->peerID = PORT_Strdup((const char *)readerBuffer.buf);
    }

    if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer.len) {
        if (sid->urlSvrName) {
            PORT_Free((void *)sid->urlSvrName);
        }
        PORT_Assert(readerBuffer.buf);
        sid->urlSvrName = PORT_Strdup((const char *)readerBuffer.buf);
    }

    if (sslRead_ReadVariable(&reader, 3, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer.len) {
        PORT_Assert(!sid->localCert);
        SECItem tempItem = { siBuffer, (unsigned char *)readerBuffer.buf,
                             readerBuffer.len };
        sid->localCert = CERT_NewTempCertificate(NULL, /* dbHandle */
                                                 &tempItem,
                                                 NULL, PR_FALSE, PR_TRUE);
    }

    if (sslRead_ReadNumber(&reader, 8, &sid->addr.pr_s6_addr64[0]) != SECSuccess) {
        return SECFailure;
    }
    if (sslRead_ReadNumber(&reader, 8, &sid->addr.pr_s6_addr64[1]) != SECSuccess) {
        return SECFailure;
    }

    if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->port = (PRUint16)tmpInt;
    if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->version = (PRUint16)tmpInt;

    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->creationTime = (PRTime)tmpInt;

    if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->authType = (SSLAuthType)tmpInt;
    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->authKeyBits = (PRUint32)tmpInt;
    if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->keaType = (SSLKEAType)tmpInt;
    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->keaKeyBits = (PRUint32)tmpInt;
    if (sslRead_ReadNumber(&reader, 3, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->keaGroup = (SSLNamedGroup)tmpInt;

    if (sslRead_ReadNumber(&reader, 3, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->sigScheme = (SSLSignatureScheme)tmpInt;

    if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.sessionIDLength = (PRUint8)tmpInt;

    if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (readerBuffer.len) {
        PORT_Assert(readerBuffer.buf);
        PORT_Memcpy(sid->u.ssl3.sessionID, readerBuffer.buf, readerBuffer.len);
    }

    if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.cipherSuite = (PRUint16)tmpInt;
    if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.policy = (PRUint8)tmpInt;

    if (sslRead_ReadVariable(&reader, 1, &readerBuffer) != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    PORT_Assert(readerBuffer.len == WRAPPED_MASTER_SECRET_SIZE);
    if (readerBuffer.len != WRAPPED_MASTER_SECRET_SIZE) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    PORT_Assert(readerBuffer.buf);
    PORT_Memcpy(sid->u.ssl3.keys.wrapped_master_secret, readerBuffer.buf,
                readerBuffer.len);

    if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.keys.wrapped_master_secret_len = (PRUint8)tmpInt;
    if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.keys.extendedMasterSecretUsed = (PRUint8)tmpInt;

    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.masterWrapMech = (unsigned long)tmpInt;
    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.masterModuleID = (unsigned long)tmpInt;
    if (sslRead_ReadNumber(&reader, 8, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.masterSlotID = (unsigned long)tmpInt;

    if (sslRead_ReadNumber(&reader, 4, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.masterWrapIndex = (PRUint32)tmpInt;
    if (sslRead_ReadNumber(&reader, 2, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.masterWrapSeries = (PRUint16)tmpInt;

    if (sslRead_ReadNumber(&reader, 1, &tmpInt) != SECSuccess) {
        return SECFailure;
    }
    sid->u.ssl3.masterValid = (char)tmpInt;

    if (ReadVariableFromBuffer(&reader, &readerBuffer, 1,
                               &sid->u.ssl3.srvName) != SECSuccess) {
        return SECFailure;
    }
    if (ReadVariableFromBuffer(&reader, &readerBuffer, 2,
                               &sid->u.ssl3.signedCertTimestamps) != SECSuccess) {
        return SECFailure;
    }
    if (ReadVariableFromBuffer(&reader, &readerBuffer, 1,
                               &sid->u.ssl3.alpnSelection) != SECSuccess) {
        return SECFailure;
    }
    if (ReadVariableFromBuffer(&reader, &readerBuffer, 2,
                               &sid->u.ssl3.locked.sessionTicket.ticket) != SECSuccess) {
        return SECFailure;
    }
    if (!sid->u.ssl3.locked.sessionTicket.ticket.len) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* At this point we must have read everything. */
    PORT_Assert(reader.offset == reader.buf.len);
    if (reader.offset != reader.buf.len) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    return SECSuccess;
}

PRBool
ssl_IsResumptionTokenUsable(sslSocket *ss, sslSessionID *sid)
{
    PORT_Assert(ss);
    PORT_Assert(sid);

    // Check that the ticket didn't expire.
    PRTime endTime = 0;
    NewSessionTicket *ticket = &sid->u.ssl3.locked.sessionTicket;
    if (ticket->ticket_lifetime_hint != 0) {
        endTime = ticket->received_timestamp +
                  (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC);
        if (endTime <= ssl_Time(ss)) {
            return PR_FALSE;
        }
    }

    // Check that the session entry didn't expire.
    if (sid->expirationTime < ssl_Time(ss)) {
        return PR_FALSE;
    }

    // Check that the server name (SNI) matches the one set for this session.
    // Don't use the token if there's no server name.
    if (sid->urlSvrName == NULL || PORT_Strcmp(ss->url, sid->urlSvrName) != 0) {
        return PR_FALSE;
    }

    // This shouldn't be false, but let's check it anyway.
    if (!sid->u.ssl3.keys.resumable) {
        return PR_FALSE;
    }

    return PR_TRUE;
}

/* Encode a session ticket into a byte array that can be handed out to a cache.
 * Needed memory in encodedToken has to be allocated according to
 * *encodedTokenLen. */
static SECStatus
ssl_EncodeResumptionToken(sslSessionID *sid, sslBuffer *encodedTokenBuf)
{
    PORT_Assert(encodedTokenBuf);
    PORT_Assert(sid);
    if (!sid || !sid->u.ssl3.locked.sessionTicket.ticket.len ||
        !encodedTokenBuf || !sid->u.ssl3.keys.resumable || !sid->urlSvrName) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    /* Encoding format:
     * 0-byte: version
     * Integers are encoded according to their length.
     * SECItems are prepended with a 64-bit length field followed by the bytes.
     * Optional bytes are encoded as a 0-length item if not present.
     */
    SECStatus rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                          SSLResumptionTokenVersion, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->lastAccessTime, 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->expirationTime, 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    // session ticket
    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.locked.sessionTicket.received_timestamp,
                                8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint,
                                4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.locked.sessionTicket.flags,
                                4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.locked.sessionTicket.ticket_age_add,
                                4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.locked.sessionTicket.max_early_data_size,
                                4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sslBuffer_AppendVariable(encodedTokenBuf, sid->peerCert->derCert.data,
                                  sid->peerCert->derCert.len, 3);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (sid->peerCertStatus.len > 1) {
        /* This is not implemented so it shouldn't happen.
         * If it gets implemented, this has to change.
         */
        PORT_Assert(0);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (sid->peerCertStatus.len == 1 && sid->peerCertStatus.items[0].len) {
        rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                      sid->peerCertStatus.items[0].data,
                                      sid->peerCertStatus.items[0].len, 2);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    } else {
        rv = sslBuffer_AppendVariable(encodedTokenBuf, NULL, 0, 2);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    PRUint64 len = sid->peerID ? strlen(sid->peerID) : 0;
    if (len > PR_UINT8_MAX) {
        // This string really shouldn't be that long.
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                  (const unsigned char *)sid->peerID, len, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    len = sid->urlSvrName ? strlen(sid->urlSvrName) : 0;
    if (!len) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    if (len > PR_UINT8_MAX) {
        // This string really shouldn't be that long.
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                  (const unsigned char *)sid->urlSvrName,
                                  len, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (sid->localCert) {
        rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                      sid->localCert->derCert.data,
                                      sid->localCert->derCert.len, 3);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    } else {
        rv = sslBuffer_AppendVariable(encodedTokenBuf, NULL, 0, 3);
        if (rv != SECSuccess) {
            return SECFailure;
        }
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->addr.pr_s6_addr64[0], 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->addr.pr_s6_addr64[1], 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->port, 2);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->version, 2);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->creationTime, 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->authType, 2);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->authKeyBits, 4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->keaType, 2);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->keaKeyBits, 4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->keaGroup, 3);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->sigScheme, 3);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.sessionIDLength, 1);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendVariable(encodedTokenBuf, sid->u.ssl3.sessionID,
                                  SSL3_SESSIONID_BYTES, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.cipherSuite, 2);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.policy, 1);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                  sid->u.ssl3.keys.wrapped_master_secret,
                                  WRAPPED_MASTER_SECRET_SIZE, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.keys.wrapped_master_secret_len,
                                1);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf,
                                sid->u.ssl3.keys.extendedMasterSecretUsed,
                                1);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterWrapMech, 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterModuleID, 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterSlotID, 8);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterWrapIndex, 4);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterWrapSeries, 2);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sslBuffer_AppendNumber(encodedTokenBuf, sid->u.ssl3.masterValid, 1);
    if (rv != SECSuccess) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    rv = sslBuffer_AppendVariable(encodedTokenBuf, sid->u.ssl3.srvName.data,
                                  sid->u.ssl3.srvName.len, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                  sid->u.ssl3.signedCertTimestamps.data,
                                  sid->u.ssl3.signedCertTimestamps.len, 2);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                  sid->u.ssl3.alpnSelection.data,
                                  sid->u.ssl3.alpnSelection.len, 1);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    PORT_Assert(sid->u.ssl3.locked.sessionTicket.ticket.len > 1);
    rv = sslBuffer_AppendVariable(encodedTokenBuf,
                                  sid->u.ssl3.locked.sessionTicket.ticket.data,
                                  sid->u.ssl3.locked.sessionTicket.ticket.len,
                                  2);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    return SECSuccess;
}

void
ssl_CacheExternalToken(sslSocket *ss)
{
    PORT_Assert(ss);
    sslSessionID *sid = ss->sec.ci.sid;
    PORT_Assert(sid);
    PORT_Assert(sid->cached == never_cached);
    PORT_Assert(ss->resumptionTokenCallback);

    SSL_TRC(8, ("SSL [%d]: Cache External: sid=0x%x cached=%d "
                "addr=0x%08x%08x%08x%08x port=0x%04x time=%x cached=%d",
                ss->fd,
                sid, sid->cached, sid->addr.pr_s6_addr32[0],
                sid->addr.pr_s6_addr32[1], sid->addr.pr_s6_addr32[2],
                sid->addr.pr_s6_addr32[3], sid->port, sid->creationTime,
                sid->cached));

    /* This is only available for stateless resumption. */
    if (sid->u.ssl3.locked.sessionTicket.ticket.data == NULL) {
        return;
    }

    /* Don't export token if the session used client authentication. */
    if (sid->u.ssl3.clAuthValid) {
        return;
    }

    if (!sid->creationTime) {
        sid->lastAccessTime = sid->creationTime = ssl_Time(ss);
    }
    if (!sid->expirationTime) {
        sid->expirationTime = sid->creationTime + (PR_MIN(ssl_ticket_lifetime,
                                                          sid->u.ssl3.locked.sessionTicket.ticket_lifetime_hint) *
                                                   PR_USEC_PER_SEC);
    }

    sslBuffer encodedToken = SSL_BUFFER_EMPTY;

    if (ssl_EncodeResumptionToken(sid, &encodedToken) != SECSuccess) {
        SSL_TRC(3, ("SSL [%d]: encoding resumption token failed", ss->fd));
        return;
    }
    PORT_Assert(SSL_BUFFER_LEN(&encodedToken) > 0);
    PRINT_BUF(40, (ss, "SSL: encoded resumption token",
                   SSL_BUFFER_BASE(&encodedToken),
                   SSL_BUFFER_LEN(&encodedToken)));
    SECStatus rv = ss->resumptionTokenCallback(
        ss->fd, SSL_BUFFER_BASE(&encodedToken), SSL_BUFFER_LEN(&encodedToken),
        ss->resumptionTokenContext);
    if (rv == SECSuccess) {
        sid->cached = in_external_cache;
    }
    sslBuffer_Clear(&encodedToken);
}

void
ssl_CacheSessionID(sslSocket *ss)
{
    sslSecurityInfo *sec = &ss->sec;
    PORT_Assert(sec);
    PORT_Assert(sec->ci.sid->cached == never_cached);

    if (sec->ci.sid && !sec->ci.sid->u.ssl3.keys.resumable) {
        return;
    }

    if (!sec->isServer && ss->resumptionTokenCallback) {
        ssl_CacheExternalToken(ss);
        return;
    }

    PORT_Assert(!ss->resumptionTokenCallback);
    if (sec->isServer) {
        ssl_ServerCacheSessionID(sec->ci.sid, ssl_Time(ss));
        return;
    }

    CacheSID(sec->ci.sid, ssl_Time(ss));
}

void
ssl_UncacheSessionID(sslSocket *ss)
{
    if (ss->opt.noCache) {
        return;
    }

    sslSecurityInfo *sec = &ss->sec;
    PORT_Assert(sec);

    if (sec->ci.sid) {
        if (sec->isServer) {
            ssl_ServerUncacheSessionID(sec->ci.sid);
        } else if (!ss->resumptionTokenCallback) {
            LockAndUncacheSID(sec->ci.sid);
        }
    }
}

/* wipe out the entire client session cache. */
void
SSL_ClearSessionCache(void)
{
    LOCK_CACHE;
    while (cache != NULL)
        UncacheSID(cache);
    UNLOCK_CACHE;
}

PRBool
ssl_TicketTimeValid(const sslSocket *ss, const NewSessionTicket *ticket)
{
    PRTime endTime;

    if (ticket->ticket_lifetime_hint == 0) {
        return PR_TRUE;
    }

    endTime = ticket->received_timestamp +
              (PRTime)(ticket->ticket_lifetime_hint * PR_USEC_PER_SEC);
    return endTime > ssl_Time(ss);
}

void
ssl3_SetSIDSessionTicket(sslSessionID *sid,
                         /*in/out*/ NewSessionTicket *newSessionTicket)
{
    PORT_Assert(sid);
    PORT_Assert(newSessionTicket);
    PORT_Assert(newSessionTicket->ticket.data);
    PORT_Assert(newSessionTicket->ticket.len != 0);

    /* If this is in the client cache, we are updating an existing entry that is
     * already cached or was once cached, so we need to acquire and release the
     * write lock. Otherwise, this is a new session that isn't shared with
     * anything yet, so no locking is needed.
     */
    if (sid->u.ssl3.lock) {
        PR_RWLock_Wlock(sid->u.ssl3.lock);
        /* Another thread may have evicted, or it may be in external cache. */
        PORT_Assert(sid->cached != never_cached);
    }
    /* If this was in the client cache, then we might have to free the old
     * ticket.  In TLS 1.3, we might get a replacement ticket if the server
     * sends more than one ticket. */
    if (sid->u.ssl3.locked.sessionTicket.ticket.data) {
        PORT_Assert(sid->cached != never_cached ||
                    sid->version >= SSL_LIBRARY_VERSION_TLS_1_3);
        SECITEM_FreeItem(&sid->u.ssl3.locked.sessionTicket.ticket,
                         PR_FALSE);
    }

    PORT_Assert(!sid->u.ssl3.locked.sessionTicket.ticket.data);

    /* Do a shallow copy, moving the ticket data. */
    sid->u.ssl3.locked.sessionTicket = *newSessionTicket;
    newSessionTicket->ticket.data = NULL;
    newSessionTicket->ticket.len = 0;

    if (sid->u.ssl3.lock) {
        PR_RWLock_Unlock(sid->u.ssl3.lock);
    }
}
