/* -*- 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

PRUint32 ssl3_sid_timeout = 86400L; /* 24 hours */

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(const PRIPv6Addr *addr, PRUint16 port, const char *peerID,
              const char *urlSvrName)
{
    sslSessionID **sidp;
    sslSessionID *sid;
    PRUint32 now;

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

        SSL_TRC(8, ("SSL: Lookup1: 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: lookup1, 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)
{
    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 && sid->expirationTime != 0);
    if (!sid->creationTime)
        sid->lastAccessTime = sid->creationTime = ssl_TimeUsec();
    if (!sid->expirationTime)
        sid->expirationTime = sid->creationTime + ssl3_sid_timeout * 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);
        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_TimeUsec()) {
            return PR_FALSE;
        }
    }

    // Check that the session entry didn't expire.
    if (sid->expirationTime < ssl_TimeUsec()) {
        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_TimeUsec();
    }
    if (!sid->expirationTime) {
        sid->expirationTime = sid->creationTime + ssl3_sid_timeout;
    }

    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);

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

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

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

    CacheSID(sec->ci.sid);
}

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;
}

/* returns an unsigned int containing the number of seconds in PR_Now() */
PRUint32
ssl_TimeSec(void)
{
#ifdef UNSAFE_FUZZER_MODE
    return 1234;
#endif

    PRUint32 myTime;
#if defined(XP_UNIX) || defined(XP_WIN) || defined(_WINDOWS) || defined(XP_BEOS)
    myTime = time(NULL); /* accurate until the year 2038. */
#else
    /* portable, but possibly slower */
    PRTime now;
    PRInt64 ll;

    now = PR_Now();
    LL_I2L(ll, 1000000L);
    LL_DIV(now, now, ll);
    LL_L2UI(myTime, now);
#endif
    return myTime;
}

PRBool
ssl_TicketTimeValid(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_TimeUsec();
}

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) {
        PORT_Assert(sid->cached == in_client_cache);
        PR_RWLock_Wlock(sid->u.ssl3.lock);
    }
    /* 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 == in_client_cache ||
                    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);
    }
}
