/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This file implements the SERVER Session ID cache.
 * NOTE:  The contents of this file are NOT used by the client.
 *
 * 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/. */

/* Note: ssl_FreeSID() in sslnonce.c gets used for both client and server
 * cache sids!
 *
 * About record locking among different server processes:
 *
 * All processes that are part of the same conceptual server (serving on
 * the same address and port) MUST share a common SSL session cache.
 * This code makes the content of the shared cache accessible to all
 * processes on the same "server".  This code works on Unix and Win32 only.
 *
 * We use NSPR anonymous shared memory and move data to & from shared memory.
 * We must do explicit locking of the records for all reads and writes.
 * The set of Cache entries are divided up into "sets" of 128 entries.
 * Each set is protected by a lock.  There may be one or more sets protected
 * by each lock.  That is, locks to sets are 1:N.
 * There is one lock for the entire cert cache.
 * There is one lock for the set of wrapped sym wrap keys.
 *
 * The anonymous shared memory is laid out as if it were declared like this:
 *
 * struct {
 *     cacheDescriptor          desc;
 *     sidCacheLock             sidCacheLocks[ numSIDCacheLocks];
 *     sidCacheLock             keyCacheLock;
 *     sidCacheLock             certCacheLock;
 *     sidCacheSet              sidCacheSets[ numSIDCacheSets ];
 *     sidCacheEntry            sidCacheData[ numSIDCacheEntries];
 *     certCacheEntry           certCacheData[numCertCacheEntries];
 *     SSLWrappedSymWrappingKey keyCacheData[SSL_NUM_WRAP_KEYS][SSL_NUM_WRAP_MECHS];
 *     PRUint8                  keyNameSuffix[SELF_ENCRYPT_KEY_VAR_NAME_LEN]
 *     encKeyCacheEntry         ticketEncKey; // Wrapped
 *     encKeyCacheEntry         ticketMacKey; // Wrapped
 *     PRBool                   ticketKeysValid;
 *     sidCacheLock             srvNameCacheLock;
 *     srvNameCacheEntry        srvNameData[ numSrvNameCacheEntries ];
 * } cacheMemCacheData;
 */
#include "seccomon.h"

#if defined(XP_UNIX) || defined(XP_WIN32) || defined(XP_OS2) || defined(XP_BEOS)

#include "cert.h"
#include "ssl.h"
#include "sslimpl.h"
#include "sslproto.h"
#include "pk11func.h"
#include "base64.h"
#include "keyhi.h"
#include "blapit.h"
#include "nss.h" /* for NSS_RegisterShutdown */
#include "sechash.h"
#include "selfencrypt.h"
#include <stdio.h>

#if defined(XP_UNIX) || defined(XP_BEOS)

#include <syslog.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include "unix_err.h"

#else

#ifdef XP_WIN32
#include <wtypes.h>
#include "win32err.h"
#endif

#endif
#include <sys/types.h>

#include "nspr.h"
#include "sslmutex.h"

/*
** Format of a cache entry in the shared memory.
*/
PR_STATIC_ASSERT(sizeof(PRTime) == 8);
struct sidCacheEntryStr {
    /* 16 */ PRIPv6Addr addr; /* client's IP address */
    /*  8 */ PRTime creationTime;
    /*  8 */ PRTime lastAccessTime;
    /*  8 */ PRTime expirationTime;
    /*  2 */ PRUint16 version;
    /*  1 */ PRUint8 valid;
    /*  1 */ PRUint8 sessionIDLength;
    /* 32 */ PRUint8 sessionID[SSL3_SESSIONID_BYTES];
    /*  2 */ PRUint16 authType;
    /*  2 */ PRUint16 authKeyBits;
    /*  2 */ PRUint16 keaType;
    /*  2 */ PRUint16 keaKeyBits;
    /*  4 */ PRUint32 signatureScheme;
    /*  4 */ PRUint32 keaGroup;
    /* 92  - common header total */

    union {
        struct {
            /*  2 */ ssl3CipherSuite cipherSuite;
            /* 52 */ ssl3SidKeys keys; /* keys, wrapped as needed. */

            /*  4 */ PRUint32 masterWrapMech;
            /*  4 */ PRInt32 certIndex;
            /*  4 */ PRInt32 srvNameIndex;
            /* 32 */ PRUint8 srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
            /*  2 */ PRUint16 namedCurve;
/*100 */} ssl3;

/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
struct {
    /*116 */ PRUint8 filler[116]; /* 92+116==208, a multiple of 16 */
} forceSize;
    } u;
};
typedef struct sidCacheEntryStr sidCacheEntry;

/* The length of this struct is supposed to be a power of 2, e.g. 4KB */
struct certCacheEntryStr {
    PRUint16 certLength;                     /*    2 */
    PRUint16 sessionIDLength;                /*    2 */
    PRUint8 sessionID[SSL3_SESSIONID_BYTES]; /*   32 */
    PRUint8 cert[SSL_MAX_CACHED_CERT_LEN];   /* 4060 */
};                                           /* total   4096 */
typedef struct certCacheEntryStr certCacheEntry;

struct sidCacheLockStr {
    PRUint32 timeStamp;
    sslMutex mutex;
    sslPID pid;
};
typedef struct sidCacheLockStr sidCacheLock;

struct sidCacheSetStr {
    PRIntn next;
};
typedef struct sidCacheSetStr sidCacheSet;

struct encKeyCacheEntryStr {
    PRUint8 bytes[512];
    PRInt32 length;
};
typedef struct encKeyCacheEntryStr encKeyCacheEntry;

#define SSL_MAX_DNS_HOST_NAME 1024

struct srvNameCacheEntryStr {
    PRUint16 type;                            /*    2 */
    PRUint16 nameLen;                         /*    2 */
    PRUint8 name[SSL_MAX_DNS_HOST_NAME + 12]; /* 1034 */
    PRUint8 nameHash[SHA256_LENGTH];          /*   32 */
                                              /* 1072 */
};
typedef struct srvNameCacheEntryStr srvNameCacheEntry;

struct cacheDescStr {

    PRUint32 cacheMemSize;

    PRUint32 numSIDCacheLocks;
    PRUint32 numSIDCacheSets;
    PRUint32 numSIDCacheSetsPerLock;

    PRUint32 numSIDCacheEntries;
    PRUint32 sidCacheSize;

    PRUint32 numCertCacheEntries;
    PRUint32 certCacheSize;

    PRUint32 numKeyCacheEntries;
    PRUint32 keyCacheSize;

    PRUint32 numSrvNameCacheEntries;
    PRUint32 srvNameCacheSize;

    PRUint32 ssl3Timeout;

    PRUint32 numSIDCacheLocksInitialized;

    /* These values are volatile, and are accessed through sharedCache-> */
    PRUint32 nextCertCacheEntry; /* certCacheLock protects */
    PRBool stopPolling;
    PRBool everInherited;

    /* The private copies of these values are pointers into shared mem */
    /* The copies of these values in shared memory are merely offsets */
    sidCacheLock *sidCacheLocks;
    sidCacheLock *keyCacheLock;
    sidCacheLock *certCacheLock;
    sidCacheLock *srvNameCacheLock;
    sidCacheSet *sidCacheSets;
    sidCacheEntry *sidCacheData;
    certCacheEntry *certCacheData;
    SSLWrappedSymWrappingKey *keyCacheData;
    PRUint8 *ticketKeyNameSuffix;
    encKeyCacheEntry *ticketEncKey;
    encKeyCacheEntry *ticketMacKey;
    PRUint32 *ticketKeysValid;
    srvNameCacheEntry *srvNameCacheData;

    /* Only the private copies of these pointers are valid */
    char *cacheMem;
    struct cacheDescStr *sharedCache; /* shared copy of this struct */
    PRFileMap *cacheMemMap;
    PRThread *poller;
    PRUint32 mutexTimeout;
    PRBool shared;
};
typedef struct cacheDescStr cacheDesc;

static cacheDesc globalCache;

static const char envVarName[] = { SSL_ENV_VAR_NAME };

static PRBool isMultiProcess = PR_FALSE;

#define DEF_SID_CACHE_ENTRIES 10000
#define DEF_CERT_CACHE_ENTRIES 250
#define MIN_CERT_CACHE_ENTRIES 125 /* the effective size in old releases. */
#define DEF_KEY_CACHE_ENTRIES 250
#define DEF_NAME_CACHE_ENTRIES 1000

#define SID_CACHE_ENTRIES_PER_SET 128
#define SID_ALIGNMENT 16

#define DEF_SSL3_TIMEOUT 86400L /* 24 hours */
#define MAX_SSL3_TIMEOUT 86400L /* 24 hours */
#define MIN_SSL3_TIMEOUT 5      /* seconds  */

#if defined(AIX) || defined(LINUX) || defined(NETBSD) || defined(OPENBSD)
#define MAX_SID_CACHE_LOCKS 8 /* two FDs per lock */
#elif defined(OSF1)
#define MAX_SID_CACHE_LOCKS 16 /* one FD per lock */
#else
#define MAX_SID_CACHE_LOCKS 256
#endif

#define SID_HOWMANY(val, size) (((val) + ((size)-1)) / (size))
#define SID_ROUNDUP(val, size) ((size)*SID_HOWMANY((val), (size)))

static sslPID myPid;
static PRUint32 ssl_max_sid_cache_locks = MAX_SID_CACHE_LOCKS;

/* forward static function declarations */
static PRUint32 SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s,
                         unsigned nl);
static SECStatus LaunchLockPoller(cacheDesc *cache);
static SECStatus StopLockPoller(cacheDesc *cache);

struct inheritanceStr {
    PRUint32 cacheMemSize;
    PRUint32 fmStrLen;
};

typedef struct inheritanceStr inheritance;

#if defined(_WIN32) || defined(XP_OS2)

#define DEFAULT_CACHE_DIRECTORY "\\temp"

#endif /* _win32 */

#if defined(XP_UNIX) || defined(XP_BEOS)

#define DEFAULT_CACHE_DIRECTORY "/tmp"

#endif /* XP_UNIX || XP_BEOS */

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

/* SSL Session Cache has a smaller set of functions to initialize than 
 * ssl does. some ssl_functions can't be initialized before NSS has been
 * initialized, and the cache may be configured before NSS is initialized
 * so thus the special init function */
static SECStatus
ssl_InitSessionCache()
{
    /* currently only one function, which is itself idempotent */
    return ssl_InitializePRErrorTable();
}

/* This is used to set locking times for the cache.  It is not used to set the
 * PRTime attributes of sessions, which are driven by ss->now(). */
static PRUint32
ssl_CacheNow()
{
    return PR_Now() / PR_USEC_PER_SEC;
}

static PRUint32
LockSidCacheLock(sidCacheLock *lock, PRUint32 now)
{
    SECStatus rv = sslMutex_Lock(&lock->mutex);
    if (rv != SECSuccess)
        return 0;
    if (!now) {
        now = ssl_CacheNow();
    }

    lock->timeStamp = now;
    lock->pid = myPid;
    return now;
}

static SECStatus
UnlockSidCacheLock(sidCacheLock *lock)
{
    SECStatus rv;

    lock->pid = 0;
    rv = sslMutex_Unlock(&lock->mutex);
    return rv;
}

/* Returns non-zero |now| or ssl_CacheNow() on success, zero on failure. */
static PRUint32
LockSet(cacheDesc *cache, PRUint32 set, PRUint32 now)
{
    PRUint32 lockNum = set % cache->numSIDCacheLocks;
    sidCacheLock *lock = cache->sidCacheLocks + lockNum;

    return LockSidCacheLock(lock, now);
}

static SECStatus
UnlockSet(cacheDesc *cache, PRUint32 set)
{
    PRUint32 lockNum = set % cache->numSIDCacheLocks;
    sidCacheLock *lock = cache->sidCacheLocks + lockNum;

    return UnlockSidCacheLock(lock);
}

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

/* Put a certificate in the cache.  Update the cert index in the sce.
*/
static PRUint32
CacheCert(cacheDesc *cache, CERTCertificate *cert, sidCacheEntry *sce)
{
    PRUint32 now;
    certCacheEntry cce;

    if ((cert->derCert.len > SSL_MAX_CACHED_CERT_LEN) ||
        (cert->derCert.len <= 0) ||
        (cert->derCert.data == NULL)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return 0;
    }

    cce.sessionIDLength = sce->sessionIDLength;
    PORT_Memcpy(cce.sessionID, sce->sessionID, cce.sessionIDLength);

    cce.certLength = cert->derCert.len;
    PORT_Memcpy(cce.cert, cert->derCert.data, cce.certLength);

    /* get lock on cert cache */
    now = LockSidCacheLock(cache->certCacheLock, 0);
    if (now) {

        /* Find where to place the next cert cache entry. */
        cacheDesc *sharedCache = cache->sharedCache;
        PRUint32 ndx = sharedCache->nextCertCacheEntry;

        /* write the entry */
        cache->certCacheData[ndx] = cce;

        /* remember where we put it. */
        sce->u.ssl3.certIndex = ndx;

        /* update the "next" cache entry index */
        sharedCache->nextCertCacheEntry =
            (ndx + 1) % cache->numCertCacheEntries;

        UnlockSidCacheLock(cache->certCacheLock);
    }
    return now;
}

/* Server configuration hash tables need to account the SECITEM.type
 * field as well. These functions accomplish that. */
static PLHashNumber
Get32BitNameHash(const SECItem *name)
{
    PLHashNumber rv = SECITEM_Hash(name);

    PRUint8 *rvc = (PRUint8 *)&rv;
    rvc[name->len % sizeof(rv)] ^= name->type;

    return rv;
}

/* Put a name in the cache.  Update the cert index in the sce.
*/
static PRUint32
CacheSrvName(cacheDesc *cache, SECItem *name, sidCacheEntry *sce)
{
    PRUint32 now;
    PRUint32 ndx;
    srvNameCacheEntry snce;

    if (!name || name->len <= 0 ||
        name->len > SSL_MAX_DNS_HOST_NAME) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return 0;
    }

    snce.type = name->type;
    snce.nameLen = name->len;
    PORT_Memcpy(snce.name, name->data, snce.nameLen);
    HASH_HashBuf(HASH_AlgSHA256, snce.nameHash, name->data, name->len);

    /* get index of the next name */
    ndx = Get32BitNameHash(name);
    /* get lock on cert cache */
    now = LockSidCacheLock(cache->srvNameCacheLock, 0);
    if (now) {
        if (cache->numSrvNameCacheEntries > 0) {
            /* Fit the index into array */
            ndx %= cache->numSrvNameCacheEntries;
            /* write the entry */
            cache->srvNameCacheData[ndx] = snce;
            /* remember where we put it. */
            sce->u.ssl3.srvNameIndex = ndx;
            /* Copy hash into sid hash */
            PORT_Memcpy(sce->u.ssl3.srvNameHash, snce.nameHash, SHA256_LENGTH);
        }
        UnlockSidCacheLock(cache->srvNameCacheLock);
    }
    return now;
}

/*
** Convert local SID to shared memory one
*/
static void
ConvertFromSID(sidCacheEntry *to, sslSessionID *from)
{
    to->valid = 1;
    to->version = from->version;
    to->addr = from->addr;
    to->creationTime = from->creationTime;
    to->lastAccessTime = from->lastAccessTime;
    to->expirationTime = from->expirationTime;
    to->authType = from->authType;
    to->authKeyBits = from->authKeyBits;
    to->keaType = from->keaType;
    to->keaKeyBits = from->keaKeyBits;
    to->keaGroup = from->keaGroup;
    to->signatureScheme = from->sigScheme;

    to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
    to->u.ssl3.keys = from->u.ssl3.keys;
    to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
    to->sessionIDLength = from->u.ssl3.sessionIDLength;
    to->u.ssl3.certIndex = -1;
    to->u.ssl3.srvNameIndex = -1;
    PORT_Memcpy(to->sessionID, from->u.ssl3.sessionID,
                to->sessionIDLength);
    to->u.ssl3.namedCurve = 0U;
    if (from->authType == ssl_auth_ecdsa ||
        from->authType == ssl_auth_ecdh_rsa ||
        from->authType == ssl_auth_ecdh_ecdsa) {
        PORT_Assert(from->namedCurve);
        to->u.ssl3.namedCurve = (PRUint16)from->namedCurve->name;
    }

    SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
                "cipherSuite=%d",
                myPid, to->creationTime / PR_USEC_PER_SEC,
                to->addr.pr_s6_addr32[0], to->addr.pr_s6_addr32[1],
                to->addr.pr_s6_addr32[2], to->addr.pr_s6_addr32[3],
                to->u.ssl3.cipherSuite));
}

/*
** Convert shared memory cache-entry to local memory based one
** This is only called from ServerSessionIDLookup().
*/
static sslSessionID *
ConvertToSID(sidCacheEntry *from,
             certCacheEntry *pcce,
             srvNameCacheEntry *psnce,
             CERTCertDBHandle *dbHandle)
{
    sslSessionID *to;

    to = PORT_ZNew(sslSessionID);
    if (!to) {
        return 0;
    }

    to->u.ssl3.sessionIDLength = from->sessionIDLength;
    to->u.ssl3.cipherSuite = from->u.ssl3.cipherSuite;
    to->u.ssl3.keys = from->u.ssl3.keys;
    to->u.ssl3.masterWrapMech = from->u.ssl3.masterWrapMech;
    if (from->u.ssl3.srvNameIndex != -1 && psnce) {
        SECItem name;
        SECStatus rv;
        name.type = psnce->type;
        name.len = psnce->nameLen;
        name.data = psnce->name;
        rv = SECITEM_CopyItem(NULL, &to->u.ssl3.srvName, &name);
        if (rv != SECSuccess) {
            goto loser;
        }
    }

    PORT_Memcpy(to->u.ssl3.sessionID, from->sessionID, from->sessionIDLength);

    to->urlSvrName = NULL;

    to->u.ssl3.masterModuleID = (SECMODModuleID)-1; /* invalid value */
    to->u.ssl3.masterSlotID = (CK_SLOT_ID)-1;       /* invalid value */
    to->u.ssl3.masterWrapIndex = 0;
    to->u.ssl3.masterWrapSeries = 0;
    to->u.ssl3.masterValid = PR_FALSE;

    to->u.ssl3.clAuthModuleID = (SECMODModuleID)-1; /* invalid value */
    to->u.ssl3.clAuthSlotID = (CK_SLOT_ID)-1;       /* invalid value */
    to->u.ssl3.clAuthSeries = 0;
    to->u.ssl3.clAuthValid = PR_FALSE;

    if (from->u.ssl3.certIndex != -1 && pcce) {
        SECItem derCert;

        derCert.len = pcce->certLength;
        derCert.data = pcce->cert;

        to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
                                               PR_FALSE, PR_TRUE);
        if (to->peerCert == NULL)
            goto loser;
    }
    if (from->authType == ssl_auth_ecdsa ||
        from->authType == ssl_auth_ecdh_rsa ||
        from->authType == ssl_auth_ecdh_ecdsa) {
        to->namedCurve =
            ssl_LookupNamedGroup((SSLNamedGroup)from->u.ssl3.namedCurve);
    }

    to->version = from->version;
    to->creationTime = from->creationTime;
    to->lastAccessTime = from->lastAccessTime;
    to->expirationTime = from->expirationTime;
    to->cached = in_server_cache;
    to->addr = from->addr;
    to->references = 1;
    to->authType = from->authType;
    to->authKeyBits = from->authKeyBits;
    to->keaType = from->keaType;
    to->keaKeyBits = from->keaKeyBits;
    to->keaGroup = from->keaGroup;
    to->sigScheme = from->signatureScheme;

    return to;

loser:
    if (to) {
        SECITEM_FreeItem(&to->u.ssl3.srvName, PR_FALSE);
        PORT_Free(to);
    }
    return NULL;
}

/*
** Perform some mumbo jumbo on the ip-address and the session-id value to
** compute a hash value.
*/
static PRUint32
SIDindex(cacheDesc *cache, const PRIPv6Addr *addr, PRUint8 *s, unsigned nl)
{
    PRUint32 rv;
    PRUint32 x[8];

    memset(x, 0, sizeof x);
    if (nl > sizeof x)
        nl = sizeof x;
    memcpy(x, s, nl);

    rv = (addr->pr_s6_addr32[0] ^ addr->pr_s6_addr32[1] ^
          addr->pr_s6_addr32[2] ^ addr->pr_s6_addr32[3] ^
          x[0] ^ x[1] ^ x[2] ^ x[3] ^ x[4] ^ x[5] ^ x[6] ^ x[7]) %
         cache->numSIDCacheSets;
    return rv;
}

/*
** Look something up in the cache. This will invalidate old entries
** in the process. Caller has locked the cache set!
** Returns PR_TRUE if found a valid match.  PR_FALSE otherwise.
*/
static sidCacheEntry *
FindSID(cacheDesc *cache, PRUint32 setNum, PRUint32 now,
        const PRIPv6Addr *addr, unsigned char *sessionID,
        unsigned sessionIDLength)
{
    PRUint32 ndx = cache->sidCacheSets[setNum].next;
    int i;

    sidCacheEntry *set = cache->sidCacheData +
                         (setNum * SID_CACHE_ENTRIES_PER_SET);

    for (i = SID_CACHE_ENTRIES_PER_SET; i > 0; --i) {
        sidCacheEntry *sce;

        ndx = (ndx - 1) % SID_CACHE_ENTRIES_PER_SET;
        sce = set + ndx;

        if (!sce->valid)
            continue;

        if (now > sce->expirationTime) {
            /* SessionID has timed out. Invalidate the entry. */
            SSL_TRC(7, ("%d: timed out sid entry addr=%08x%08x%08x%08x now=%x "
                        "time+=%x",
                        myPid, sce->addr.pr_s6_addr32[0],
                        sce->addr.pr_s6_addr32[1], sce->addr.pr_s6_addr32[2],
                        sce->addr.pr_s6_addr32[3], now,
                        sce->expirationTime));
            sce->valid = 0;
            continue;
        }

        /*
        ** Next, examine specific session-id/addr data to see if the cache
        ** entry matches our addr+session-id value
        */
        if (sessionIDLength == sce->sessionIDLength &&
            !memcmp(&sce->addr, addr, sizeof(PRIPv6Addr)) &&
            !memcmp(sce->sessionID, sessionID, sessionIDLength)) {
            /* Found it */
            return sce;
        }
    }

    PORT_SetError(SSL_ERROR_SESSION_NOT_FOUND);
    return NULL;
}

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

/* This is the primary function for finding entries in the server's sid cache.
 * Although it is static, this function is called via the global function
 * pointer ssl_sid_lookup.
 *
 * sslNow is the time that the calling socket understands, which might be
 * different than what the cache uses to maintain its locks.
 */
static sslSessionID *
ServerSessionIDLookup(PRTime sslNow, const PRIPv6Addr *addr,
                      unsigned char *sessionID,
                      unsigned int sessionIDLength,
                      CERTCertDBHandle *dbHandle)
{
    sslSessionID *sid = 0;
    sidCacheEntry *psce;
    certCacheEntry *pcce = 0;
    srvNameCacheEntry *psnce = 0;
    cacheDesc *cache = &globalCache;
    PRUint32 now;
    PRUint32 set;
    PRInt32 cndx;
    sidCacheEntry sce;
    certCacheEntry cce;
    srvNameCacheEntry snce;

    set = SIDindex(cache, addr, sessionID, sessionIDLength);
    now = LockSet(cache, set, 0);
    if (!now)
        return NULL;

    psce = FindSID(cache, set, now, addr, sessionID, sessionIDLength);
    if (psce) {
        if ((cndx = psce->u.ssl3.certIndex) != -1) {
            PRUint32 gotLock = LockSidCacheLock(cache->certCacheLock, now);
            if (gotLock) {
                pcce = &cache->certCacheData[cndx];

                /* See if the cert's session ID matches the sce cache. */
                if ((pcce->sessionIDLength == psce->sessionIDLength) &&
                    !PORT_Memcmp(pcce->sessionID, psce->sessionID,
                                 pcce->sessionIDLength)) {
                    cce = *pcce;
                } else {
                    /* The cert doesen't match the SID cache entry,
                    ** so invalidate the SID cache entry.
                    */
                    psce->valid = 0;
                    psce = 0;
                    pcce = 0;
                }
                UnlockSidCacheLock(cache->certCacheLock);
            } else {
                /* what the ??.  Didn't get the cert cache lock.
                ** Don't invalidate the SID cache entry, but don't find it.
                */
                PORT_AssertNotReached("Didn't get cert Cache Lock!");
                psce = 0;
                pcce = 0;
            }
        }
        if (psce && ((cndx = psce->u.ssl3.srvNameIndex) != -1)) {
            PRUint32 gotLock = LockSidCacheLock(cache->srvNameCacheLock,
                                                now);
            if (gotLock) {
                psnce = &cache->srvNameCacheData[cndx];

                if (!PORT_Memcmp(psnce->nameHash, psce->u.ssl3.srvNameHash,
                                 SHA256_LENGTH)) {
                    snce = *psnce;
                } else {
                    /* The name doesen't match the SID cache entry,
                    ** so invalidate the SID cache entry.
                    */
                    psce->valid = 0;
                    psce = 0;
                    psnce = 0;
                }
                UnlockSidCacheLock(cache->srvNameCacheLock);
            } else {
                /* what the ??.  Didn't get the cert cache lock.
                ** Don't invalidate the SID cache entry, but don't find it.
                */
                PORT_AssertNotReached("Didn't get name Cache Lock!");
                psce = 0;
                psnce = 0;
            }
        }
        if (psce) {
            psce->lastAccessTime = sslNow;
            sce = *psce; /* grab a copy while holding the lock */
        }
    }
    UnlockSet(cache, set);
    if (psce) {
        /* sce conains a copy of the cache entry.
        ** Convert shared memory format to local format
        */
        sid = ConvertToSID(&sce, pcce ? &cce : 0, psnce ? &snce : 0, dbHandle);
    }
    return sid;
}

/*
** Place a sid into the cache, if it isn't already there.
*/
void
ssl_ServerCacheSessionID(sslSessionID *sid, PRTime creationTime)
{
    PORT_Assert(sid);

    sidCacheEntry sce;
    PRUint32 now = 0;
    cacheDesc *cache = &globalCache;

    if (sid->u.ssl3.sessionIDLength == 0) {
        return;
    }

    if (sid->cached == never_cached || sid->cached == invalid_cache) {
        PRUint32 set;
        SECItem *name;

        PORT_Assert(sid->creationTime != 0);
        if (!sid->creationTime)
            sid->lastAccessTime = sid->creationTime = creationTime;
        /* override caller's expiration time, which uses client timeout
         * duration, not server timeout duration.
         */
        sid->expirationTime =
            sid->creationTime + cache->ssl3Timeout * PR_USEC_PER_SEC;
        SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
                    "cipherSuite=%d",
                    myPid, 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->creationTime / PR_USEC_PER_SEC,
                    sid->u.ssl3.cipherSuite));
        PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
                      sid->u.ssl3.sessionIDLength));

        ConvertFromSID(&sce, sid);

        name = &sid->u.ssl3.srvName;
        if (name->len && name->data) {
            now = CacheSrvName(cache, name, &sce);
        }
        if (sid->peerCert != NULL) {
            now = CacheCert(cache, sid->peerCert, &sce);
        }

        set = SIDindex(cache, &sce.addr, sce.sessionID, sce.sessionIDLength);
        now = LockSet(cache, set, now);
        if (now) {
            PRUint32 next = cache->sidCacheSets[set].next;
            PRUint32 ndx = set * SID_CACHE_ENTRIES_PER_SET + next;

            /* Write out new cache entry */
            cache->sidCacheData[ndx] = sce;

            cache->sidCacheSets[set].next =
                (next + 1) % SID_CACHE_ENTRIES_PER_SET;

            UnlockSet(cache, set);
            sid->cached = in_server_cache;
        }
    }
}

/*
** Although this is static, it is called from ssl via global function pointer
**  ssl_sid_uncache.  This invalidates the referenced cache entry.
*/
void
ssl_ServerUncacheSessionID(sslSessionID *sid)
{
    cacheDesc *cache = &globalCache;
    PRUint8 *sessionID;
    unsigned int sessionIDLength;
    PRErrorCode err;
    PRUint32 set;
    PRUint32 now;
    sidCacheEntry *psce;

    if (sid == NULL)
        return;

    /* Uncaching a SID should never change the error code.
    ** So save it here and restore it before exiting.
    */
    err = PR_GetError();

    sessionID = sid->u.ssl3.sessionID;
    sessionIDLength = sid->u.ssl3.sessionIDLength;
    SSL_TRC(8, ("%d: SSL3: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
                "cipherSuite=%d",
                myPid, 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->creationTime / PR_USEC_PER_SEC,
                sid->u.ssl3.cipherSuite));
    PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
    set = SIDindex(cache, &sid->addr, sessionID, sessionIDLength);
    now = LockSet(cache, set, 0);
    if (now) {
        psce = FindSID(cache, set, now, &sid->addr, sessionID, sessionIDLength);
        if (psce) {
            psce->valid = 0;
        }
        UnlockSet(cache, set);
    }
    sid->cached = invalid_cache;
    PORT_SetError(err);
}

#ifdef XP_OS2

#define INCL_DOSPROCESS
#include <os2.h>

long
gettid(void)
{
    PTIB ptib;
    PPIB ppib;
    DosGetInfoBlocks(&ptib, &ppib);
    return ((long)ptib->tib_ordinal); /* thread id */
}
#endif

static void
CloseCache(cacheDesc *cache)
{
    int locks_initialized = cache->numSIDCacheLocksInitialized;

    if (cache->cacheMem) {
        if (cache->sharedCache) {
            sidCacheLock *pLock = cache->sidCacheLocks;
            for (; locks_initialized > 0; --locks_initialized, ++pLock) {
                /* If everInherited is true, this shared cache was (and may
                ** still be) in use by multiple processes.  We do not wish to
                ** destroy the mutexes while they are still in use, but we do
                ** want to free mutex resources associated with this process.
                */
                sslMutex_Destroy(&pLock->mutex,
                                 cache->sharedCache->everInherited);
            }
        }
        if (cache->shared) {
            PR_MemUnmap(cache->cacheMem, cache->cacheMemSize);
        } else {
            PORT_Free(cache->cacheMem);
        }
        cache->cacheMem = NULL;
    }
    if (cache->cacheMemMap) {
        PR_CloseFileMap(cache->cacheMemMap);
        cache->cacheMemMap = NULL;
    }
    memset(cache, 0, sizeof *cache);
}

static SECStatus
InitCache(cacheDesc *cache, int maxCacheEntries, int maxCertCacheEntries,
          int maxSrvNameCacheEntries, PRUint32 ssl3_timeout,
          const char *directory, PRBool shared)
{
    ptrdiff_t ptr;
    sidCacheLock *pLock;
    char *cacheMem;
    PRFileMap *cacheMemMap;
    char *cfn = NULL; /* cache file name */
    int locks_initialized = 0;
    int locks_to_initialize = 0;
    PRUint32 init_time;

    if ((!cache) || (maxCacheEntries < 0) || (!directory)) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (cache->cacheMem) {
        /* Already done */
        return SECSuccess;
    }

    /* make sure loser can clean up properly */
    cache->shared = shared;
    cache->cacheMem = cacheMem = NULL;
    cache->cacheMemMap = cacheMemMap = NULL;
    cache->sharedCache = (cacheDesc *)0;

    cache->numSIDCacheLocksInitialized = 0;
    cache->nextCertCacheEntry = 0;
    cache->stopPolling = PR_FALSE;
    cache->everInherited = PR_FALSE;
    cache->poller = NULL;
    cache->mutexTimeout = 0;

    cache->numSIDCacheEntries = maxCacheEntries ? maxCacheEntries
                                                : DEF_SID_CACHE_ENTRIES;
    cache->numSIDCacheSets =
        SID_HOWMANY(cache->numSIDCacheEntries, SID_CACHE_ENTRIES_PER_SET);

    cache->numSIDCacheEntries =
        cache->numSIDCacheSets * SID_CACHE_ENTRIES_PER_SET;

    cache->numSIDCacheLocks =
        PR_MIN(cache->numSIDCacheSets, ssl_max_sid_cache_locks);

    cache->numSIDCacheSetsPerLock =
        SID_HOWMANY(cache->numSIDCacheSets, cache->numSIDCacheLocks);

    cache->numCertCacheEntries = (maxCertCacheEntries > 0) ? maxCertCacheEntries
                                                           : 0;
    cache->numSrvNameCacheEntries = (maxSrvNameCacheEntries >= 0) ? maxSrvNameCacheEntries
                                                                  : DEF_NAME_CACHE_ENTRIES;

    /* compute size of shared memory, and offsets of all pointers */
    ptr = 0;
    cache->cacheMem = (char *)ptr;
    ptr += SID_ROUNDUP(sizeof(cacheDesc), SID_ALIGNMENT);

    cache->sidCacheLocks = (sidCacheLock *)ptr;
    cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks;
    cache->certCacheLock = cache->keyCacheLock + 1;
    cache->srvNameCacheLock = cache->certCacheLock + 1;
    ptr = (ptrdiff_t)(cache->srvNameCacheLock + 1);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->sidCacheSets = (sidCacheSet *)ptr;
    ptr = (ptrdiff_t)(cache->sidCacheSets + cache->numSIDCacheSets);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->sidCacheData = (sidCacheEntry *)ptr;
    ptr = (ptrdiff_t)(cache->sidCacheData + cache->numSIDCacheEntries);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->certCacheData = (certCacheEntry *)ptr;
    cache->sidCacheSize =
        (char *)cache->certCacheData - (char *)cache->sidCacheData;

    if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES) {
        /* This is really a poor way to computer this! */
        cache->numCertCacheEntries = cache->sidCacheSize / sizeof(certCacheEntry);
        if (cache->numCertCacheEntries < MIN_CERT_CACHE_ENTRIES)
            cache->numCertCacheEntries = MIN_CERT_CACHE_ENTRIES;
    }
    ptr = (ptrdiff_t)(cache->certCacheData + cache->numCertCacheEntries);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->keyCacheData = (SSLWrappedSymWrappingKey *)ptr;
    cache->certCacheSize =
        (char *)cache->keyCacheData - (char *)cache->certCacheData;

    cache->numKeyCacheEntries = SSL_NUM_WRAP_KEYS * SSL_NUM_WRAP_MECHS;
    ptr = (ptrdiff_t)(cache->keyCacheData + cache->numKeyCacheEntries);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->keyCacheSize = (char *)ptr - (char *)cache->keyCacheData;

    cache->ticketKeyNameSuffix = (PRUint8 *)ptr;
    ptr = (ptrdiff_t)(cache->ticketKeyNameSuffix +
                      SELF_ENCRYPT_KEY_VAR_NAME_LEN);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->ticketEncKey = (encKeyCacheEntry *)ptr;
    ptr = (ptrdiff_t)(cache->ticketEncKey + 1);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->ticketMacKey = (encKeyCacheEntry *)ptr;
    ptr = (ptrdiff_t)(cache->ticketMacKey + 1);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->ticketKeysValid = (PRUint32 *)ptr;
    ptr = (ptrdiff_t)(cache->ticketKeysValid + 1);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->srvNameCacheData = (srvNameCacheEntry *)ptr;
    cache->srvNameCacheSize =
        cache->numSrvNameCacheEntries * sizeof(srvNameCacheEntry);
    ptr = (ptrdiff_t)(cache->srvNameCacheData + cache->numSrvNameCacheEntries);
    ptr = SID_ROUNDUP(ptr, SID_ALIGNMENT);

    cache->cacheMemSize = ptr;

    if (ssl3_timeout) {
        if (ssl3_timeout > MAX_SSL3_TIMEOUT) {
            ssl3_timeout = MAX_SSL3_TIMEOUT;
        }
        if (ssl3_timeout < MIN_SSL3_TIMEOUT) {
            ssl3_timeout = MIN_SSL3_TIMEOUT;
        }
        cache->ssl3Timeout = ssl3_timeout;
    } else {
        cache->ssl3Timeout = DEF_SSL3_TIMEOUT;
    }

    if (shared) {
/* Create file names */
#if defined(XP_UNIX) || defined(XP_BEOS)
        /* there's some confusion here about whether PR_OpenAnonFileMap wants
        ** a directory name or a file name for its first argument.
        cfn = PR_smprintf("%s/.sslsvrcache.%d", directory, myPid);
        */
        cfn = PR_smprintf("%s", directory);
#elif defined(XP_WIN32)
        cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid,
                          GetCurrentThreadId());
#elif defined(XP_OS2)
        cfn = PR_smprintf("%s/svrcache_%d_%x.ssl", directory, myPid,
                          gettid());
#else
#error "Don't know how to create file name for this platform!"
#endif
        if (!cfn) {
            goto loser;
        }

        /* Create cache */
        cacheMemMap = PR_OpenAnonFileMap(cfn, cache->cacheMemSize,
                                         PR_PROT_READWRITE);

        PR_smprintf_free(cfn);
        if (!cacheMemMap) {
            goto loser;
        }

        cacheMem = PR_MemMap(cacheMemMap, 0, cache->cacheMemSize);
    } else {
        cacheMem = PORT_Alloc(cache->cacheMemSize);
    }

    if (!cacheMem) {
        goto loser;
    }

    /* Initialize shared memory. This may not be necessary on all platforms */
    memset(cacheMem, 0, cache->cacheMemSize);

    /* Copy cache descriptor header into shared memory */
    memcpy(cacheMem, cache, sizeof *cache);

    /* save private copies of these values */
    cache->cacheMemMap = cacheMemMap;
    cache->cacheMem = cacheMem;
    cache->sharedCache = (cacheDesc *)cacheMem;

    /* Fix pointers in our private copy of cache descriptor to point to
    ** spaces in shared memory
    */
    cache->sidCacheLocks = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->sidCacheLocks);
    cache->keyCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->keyCacheLock);
    cache->certCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->certCacheLock);
    cache->srvNameCacheLock = (sidCacheLock *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
    cache->sidCacheSets = (sidCacheSet *)(cache->cacheMem + (ptrdiff_t)cache->sidCacheSets);
    cache->sidCacheData = (sidCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->sidCacheData);
    cache->certCacheData = (certCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->certCacheData);
    cache->keyCacheData = (SSLWrappedSymWrappingKey *)(cache->cacheMem + (ptrdiff_t)cache->keyCacheData);
    cache->ticketKeyNameSuffix = (PRUint8 *)(cache->cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
    cache->ticketEncKey = (encKeyCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->ticketEncKey);
    cache->ticketMacKey = (encKeyCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->ticketMacKey);
    cache->ticketKeysValid = (PRUint32 *)(cache->cacheMem + (ptrdiff_t)cache->ticketKeysValid);
    cache->srvNameCacheData = (srvNameCacheEntry *)(cache->cacheMem + (ptrdiff_t)cache->srvNameCacheData);

    /* initialize the locks */
    init_time = ssl_CacheNow();
    pLock = cache->sidCacheLocks;
    for (locks_to_initialize = cache->numSIDCacheLocks + 3;
         locks_initialized < locks_to_initialize;
         ++locks_initialized, ++pLock) {

        SECStatus err = sslMutex_Init(&pLock->mutex, shared);
        if (err) {
            cache->numSIDCacheLocksInitialized = locks_initialized;
            goto loser;
        }
        pLock->timeStamp = init_time;
        pLock->pid = 0;
    }
    cache->numSIDCacheLocksInitialized = locks_initialized;

    return SECSuccess;

loser:
    CloseCache(cache);
    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    return SECFailure;
}

PRUint32
SSL_GetMaxServerCacheLocks(void)
{
    return ssl_max_sid_cache_locks + 2;
    /* The extra two are the cert cache lock and the key cache lock. */
}

SECStatus
SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
{
    /* Minimum is 1 sid cache lock, 1 cert cache lock and 1 key cache lock.
    ** We'd like to test for a maximum value, but not all platforms' header
    ** files provide a symbol or function or other means of determining
    ** the maximum, other than trial and error.
    */
    if (maxLocks < 3) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    ssl_max_sid_cache_locks = maxLocks - 2;
    /* The extra two are the cert cache lock and the key cache lock. */
    return SECSuccess;
}

PR_STATIC_ASSERT(sizeof(sidCacheEntry) % 16 == 0);
PR_STATIC_ASSERT(sizeof(certCacheEntry) == 4096);
PR_STATIC_ASSERT(sizeof(srvNameCacheEntry) == 1072);

static SECStatus
ssl_ConfigServerSessionIDCacheInstanceWithOpt(cacheDesc *cache,
                                              PRUint32 ssl3_timeout,
                                              const char *directory,
                                              PRBool shared,
                                              int maxCacheEntries,
                                              int maxCertCacheEntries,
                                              int maxSrvNameCacheEntries)
{
    SECStatus rv;

    rv = ssl_InitSessionCache();
    if (rv != SECSuccess) {
        return rv;
    }

    myPid = SSL_GETPID();
    if (!directory) {
        directory = DEFAULT_CACHE_DIRECTORY;
    }
    rv = InitCache(cache, maxCacheEntries, maxCertCacheEntries,
                   maxSrvNameCacheEntries, ssl3_timeout, directory, shared);
    if (rv) {
        return SECFailure;
    }

    ssl_sid_lookup = ServerSessionIDLookup;
    return SECSuccess;
}

SECStatus
SSL_ConfigServerSessionIDCacheInstance(cacheDesc *cache,
                                       int maxCacheEntries,
                                       PRUint32 ssl2_timeout,
                                       PRUint32 ssl3_timeout,
                                       const char *directory, PRBool shared)
{
    return ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
                                                         ssl3_timeout,
                                                         directory,
                                                         shared,
                                                         maxCacheEntries,
                                                         -1, -1);
}

SECStatus
SSL_ConfigServerSessionIDCache(int maxCacheEntries,
                               PRUint32 ssl2_timeout,
                               PRUint32 ssl3_timeout,
                               const char *directory)
{
    ssl_InitSessionCacheLocks(PR_FALSE);
    return SSL_ConfigServerSessionIDCacheInstance(&globalCache,
                                                  maxCacheEntries, ssl2_timeout, ssl3_timeout, directory, PR_FALSE);
}

SECStatus
SSL_ShutdownServerSessionIDCacheInstance(cacheDesc *cache)
{
    CloseCache(cache);
    return SECSuccess;
}

SECStatus
SSL_ShutdownServerSessionIDCache(void)
{
#if defined(XP_UNIX) || defined(XP_BEOS)
    /* Stop the thread that polls cache for expired locks on Unix */
    StopLockPoller(&globalCache);
#endif
    SSL3_ShutdownServerCache();
    return SSL_ShutdownServerSessionIDCacheInstance(&globalCache);
}

/* Use this function, instead of SSL_ConfigServerSessionIDCache,
 * if the cache will be shared by multiple processes.
 */
static SECStatus
ssl_ConfigMPServerSIDCacheWithOpt(PRUint32 ssl3_timeout,
                                  const char *directory,
                                  int maxCacheEntries,
                                  int maxCertCacheEntries,
                                  int maxSrvNameCacheEntries)
{
    char *envValue;
    char *inhValue;
    cacheDesc *cache = &globalCache;
    PRUint32 fmStrLen;
    SECStatus result;
    PRStatus prStatus;
    SECStatus putEnvFailed;
    inheritance inherit;
    char fmString[PR_FILEMAP_STRING_BUFSIZE];

    isMultiProcess = PR_TRUE;
    result = ssl_ConfigServerSessionIDCacheInstanceWithOpt(cache,
                                                           ssl3_timeout, directory, PR_TRUE,
                                                           maxCacheEntries, maxCacheEntries, maxSrvNameCacheEntries);
    if (result != SECSuccess)
        return result;

    prStatus = PR_ExportFileMapAsString(cache->cacheMemMap,
                                        sizeof fmString, fmString);
    if ((prStatus != PR_SUCCESS) || !(fmStrLen = strlen(fmString))) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    inherit.cacheMemSize = cache->cacheMemSize;
    inherit.fmStrLen = fmStrLen;

    inhValue = BTOA_DataToAscii((unsigned char *)&inherit, sizeof inherit);
    if (!inhValue || !strlen(inhValue)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    envValue = PR_smprintf("%s,%s", inhValue, fmString);
    if (!envValue || !strlen(envValue)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    PORT_Free(inhValue);

    putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue);
    PR_smprintf_free(envValue);
    if (putEnvFailed) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        result = SECFailure;
    }

#if defined(XP_UNIX) || defined(XP_BEOS)
    /* Launch thread to poll cache for expired locks on Unix */
    LaunchLockPoller(cache);
#endif
    return result;
}

/* Use this function, instead of SSL_ConfigServerSessionIDCache,
 * if the cache will be shared by multiple processes.
 */
SECStatus
SSL_ConfigMPServerSIDCache(int maxCacheEntries,
                           PRUint32 ssl2_timeout,
                           PRUint32 ssl3_timeout,
                           const char *directory)
{
    return ssl_ConfigMPServerSIDCacheWithOpt(ssl3_timeout,
                                             directory,
                                             maxCacheEntries,
                                             -1, -1);
}

SECStatus
SSL_ConfigServerSessionIDCacheWithOpt(
    PRUint32 ssl2_timeout,
    PRUint32 ssl3_timeout,
    const char *directory,
    int maxCacheEntries,
    int maxCertCacheEntries,
    int maxSrvNameCacheEntries,
    PRBool enableMPCache)
{
    if (!enableMPCache) {
        ssl_InitSessionCacheLocks(PR_FALSE);
        return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache,
                                                             ssl3_timeout, directory, PR_FALSE,
                                                             maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
    } else {
        return ssl_ConfigMPServerSIDCacheWithOpt(ssl3_timeout, directory,
                                                 maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
    }
}

SECStatus
SSL_InheritMPServerSIDCacheInstance(cacheDesc *cache, const char *envString)
{
    unsigned char *decoString = NULL;
    char *fmString = NULL;
    char *myEnvString = NULL;
    unsigned int decoLen;
    inheritance inherit;
    cacheDesc my;
#ifdef WINNT
    sidCacheLock *newLocks;
    int locks_initialized = 0;
    int locks_to_initialize = 0;
#endif
    SECStatus status = ssl_InitSessionCache();

    if (status != SECSuccess) {
        return status;
    }

    myPid = SSL_GETPID();

    /* If this child was created by fork(), and not by exec() on unix,
    ** then isMultiProcess will already be set.
    ** If not, we'll set it below.
    */
    if (isMultiProcess) {
        if (cache && cache->sharedCache) {
            cache->sharedCache->everInherited = PR_TRUE;
        }
        return SECSuccess; /* already done. */
    }

    ssl_InitSessionCacheLocks(PR_FALSE);

    ssl_sid_lookup = ServerSessionIDLookup;

    if (!envString) {
        envString = PR_GetEnvSecure(envVarName);
        if (!envString) {
            PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
            return SECFailure;
        }
    }
    myEnvString = PORT_Strdup(envString);
    if (!myEnvString)
        return SECFailure;
    fmString = strchr(myEnvString, ',');
    if (!fmString)
        goto loser;
    *fmString++ = 0;

    decoString = ATOB_AsciiToData(myEnvString, &decoLen);
    if (!decoString) {
        goto loser;
    }
    if (decoLen != sizeof inherit) {
        goto loser;
    }

    PORT_Memcpy(&inherit, decoString, sizeof inherit);

    if (strlen(fmString) != inherit.fmStrLen) {
        goto loser;
    }

    memset(cache, 0, sizeof *cache);
    cache->cacheMemSize = inherit.cacheMemSize;

    /* Create cache */
    cache->cacheMemMap = PR_ImportFileMapFromString(fmString);
    if (!cache->cacheMemMap) {
        goto loser;
    }
    cache->cacheMem = PR_MemMap(cache->cacheMemMap, 0, cache->cacheMemSize);
    if (!cache->cacheMem) {
        goto loser;
    }
    cache->sharedCache = (cacheDesc *)cache->cacheMem;

    if (cache->sharedCache->cacheMemSize != cache->cacheMemSize) {
        goto loser;
    }

    /* We're now going to overwrite the local cache instance with the
    ** shared copy of the cache struct, then update several values in
    ** the local cache using the values for cache->cacheMemMap and
    ** cache->cacheMem computed just above.  So, we copy cache into
    ** the automatic variable "my", to preserve the variables while
    ** cache is overwritten.
    */
    my = *cache;                                      /* save values computed above. */
    memcpy(cache, cache->sharedCache, sizeof *cache); /* overwrite */

    /* Fix pointers in our private copy of cache descriptor to point to
    ** spaces in shared memory, whose address is now in "my".
    */
    cache->sidCacheLocks = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->sidCacheLocks);
    cache->keyCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->keyCacheLock);
    cache->certCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->certCacheLock);
    cache->srvNameCacheLock = (sidCacheLock *)(my.cacheMem + (ptrdiff_t)cache->srvNameCacheLock);
    cache->sidCacheSets = (sidCacheSet *)(my.cacheMem + (ptrdiff_t)cache->sidCacheSets);
    cache->sidCacheData = (sidCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->sidCacheData);
    cache->certCacheData = (certCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->certCacheData);
    cache->keyCacheData = (SSLWrappedSymWrappingKey *)(my.cacheMem + (ptrdiff_t)cache->keyCacheData);
    cache->ticketKeyNameSuffix = (PRUint8 *)(my.cacheMem + (ptrdiff_t)cache->ticketKeyNameSuffix);
    cache->ticketEncKey = (encKeyCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->ticketEncKey);
    cache->ticketMacKey = (encKeyCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->ticketMacKey);
    cache->ticketKeysValid = (PRUint32 *)(my.cacheMem + (ptrdiff_t)cache->ticketKeysValid);
    cache->srvNameCacheData = (srvNameCacheEntry *)(my.cacheMem + (ptrdiff_t)cache->srvNameCacheData);

    cache->cacheMemMap = my.cacheMemMap;
    cache->cacheMem = my.cacheMem;
    cache->sharedCache = (cacheDesc *)cache->cacheMem;

#ifdef WINNT
    /*  On Windows NT we need to "fix" the sidCacheLocks here to support fibers
    **  When NT fibers are used in a multi-process server, a second level of
    **  locking is needed to prevent a deadlock, in case a fiber acquires the
    **  cross-process mutex, yields, and another fiber is later scheduled on
    **  the same native thread and tries to acquire the cross-process mutex.
    **  We do this by using a PRLock in the sslMutex. However, it is stored in
    **  shared memory as part of sidCacheLocks, and we don't want to overwrite
    **  the PRLock of the parent process. So we need to make new, private
    **  copies of sidCacheLocks before modifying the sslMutex with our own
    **  PRLock
    */

    /* note from jpierre : this should be free'd in child processes when
    ** a function is added to delete the SSL session cache in the future.
    */
    locks_to_initialize = cache->numSIDCacheLocks + 3;
    newLocks = PORT_NewArray(sidCacheLock, locks_to_initialize);
    if (!newLocks)
        goto loser;
    /* copy the old locks */
    memcpy(newLocks, cache->sidCacheLocks,
           locks_to_initialize * sizeof(sidCacheLock));
    cache->sidCacheLocks = newLocks;
    /* fix the locks */
    for (; locks_initialized < locks_to_initialize; ++locks_initialized) {
        /* now, make a local PRLock in this sslMutex for this child process */
        SECStatus err;
        err = sslMutex_2LevelInit(&newLocks[locks_initialized].mutex);
        if (err != SECSuccess) {
            cache->numSIDCacheLocksInitialized = locks_initialized;
            goto loser;
        }
    }
    cache->numSIDCacheLocksInitialized = locks_initialized;

    /* also fix the key and cert cache which use the last 2 lock entries */
    cache->keyCacheLock = cache->sidCacheLocks + cache->numSIDCacheLocks;
    cache->certCacheLock = cache->keyCacheLock + 1;
    cache->srvNameCacheLock = cache->certCacheLock + 1;
#endif

    PORT_Free(myEnvString);
    PORT_Free(decoString);

    /* mark that we have inherited this. */
    cache->sharedCache->everInherited = PR_TRUE;
    isMultiProcess = PR_TRUE;

    return SECSuccess;

loser:
    PORT_Free(myEnvString);
    if (decoString)
        PORT_Free(decoString);
    CloseCache(cache);
    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
    return SECFailure;
}

SECStatus
SSL_InheritMPServerSIDCache(const char *envString)
{
    return SSL_InheritMPServerSIDCacheInstance(&globalCache, envString);
}

#if defined(XP_UNIX) || defined(XP_BEOS)

#define SID_LOCK_EXPIRATION_TIMEOUT 30 /* seconds */

static void
LockPoller(void *arg)
{
    cacheDesc *cache = (cacheDesc *)arg;
    cacheDesc *sharedCache = cache->sharedCache;
    sidCacheLock *pLock;
    PRIntervalTime timeout;
    PRUint32 now;
    PRUint32 then;
    int locks_polled = 0;
    int locks_to_poll = cache->numSIDCacheLocks + 2;
    PRUint32 expiration = cache->mutexTimeout;

    timeout = PR_SecondsToInterval(expiration);
    while (!sharedCache->stopPolling) {
        PR_Sleep(timeout);
        if (sharedCache->stopPolling)
            break;

        now = ssl_CacheNow();
        then = now - expiration;
        for (pLock = cache->sidCacheLocks, locks_polled = 0;
             locks_to_poll > locks_polled && !sharedCache->stopPolling;
             ++locks_polled, ++pLock) {
            pid_t pid;

            if (pLock->timeStamp < then &&
                pLock->timeStamp != 0 &&
                (pid = pLock->pid) != 0) {

                /* maybe we should try the lock? */
                int result = kill(pid, 0);
                if (result < 0 && errno == ESRCH) {
                    SECStatus rv;
                    /* No process exists by that pid any more.
                    ** Treat this mutex as abandoned.
                    */
                    pLock->timeStamp = now;
                    pLock->pid = 0;
                    rv = sslMutex_Unlock(&pLock->mutex);
                    if (rv != SECSuccess) {
                        /* Now what? */
                    }
                }
            }
        } /* end of loop over locks */
    }     /* end of entire polling loop */
}

/* Launch thread to poll cache for expired locks */
static SECStatus
LaunchLockPoller(cacheDesc *cache)
{
    const char *timeoutString;
    PRThread *pollerThread;

    cache->mutexTimeout = SID_LOCK_EXPIRATION_TIMEOUT;
    timeoutString = PR_GetEnvSecure("NSS_SSL_SERVER_CACHE_MUTEX_TIMEOUT");
    if (timeoutString) {
        long newTime = strtol(timeoutString, 0, 0);
        if (newTime == 0)
            return SECSuccess; /* application doesn't want poller thread */
        if (newTime > 0)
            cache->mutexTimeout = (PRUint32)newTime;
        /* if error (newTime < 0) ignore it and use default */
    }

    pollerThread =
        PR_CreateThread(PR_USER_THREAD, LockPoller, cache, PR_PRIORITY_NORMAL,
                        PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
    if (!pollerThread) {
        return SECFailure;
    }
    cache->poller = pollerThread;
    return SECSuccess;
}

/* Stop the thread that polls cache for expired locks */
static SECStatus
StopLockPoller(cacheDesc *cache)
{
    if (!cache->poller) {
        return SECSuccess;
    }
    cache->sharedCache->stopPolling = PR_TRUE;
    if (PR_Interrupt(cache->poller) != PR_SUCCESS) {
        return SECFailure;
    }
    if (PR_JoinThread(cache->poller) != PR_SUCCESS) {
        return SECFailure;
    }
    cache->poller = NULL;
    return SECSuccess;
}
#endif

/************************************************************************
 *  Code dealing with shared wrapped symmetric wrapping keys below      *
 ************************************************************************/

/* The asymmetric key we use for wrapping the self-encryption keys. This is a
 * global structure that can be initialized without a socket. Access is
 * synchronized on the reader-writer lock. This is setup either by calling
 * SSL_SetSessionTicketKeyPair() or by configuring a certificate of the
 * ssl_auth_rsa_decrypt type. */
static struct {
    PRCallOnceType setup;
    PRRWLock *lock;
    SECKEYPublicKey *pubKey;
    SECKEYPrivateKey *privKey;
    PRBool configured;
} ssl_self_encrypt_key_pair;

/* The symmetric self-encryption keys. This requires a socket to construct
 * and requires that the global structure be initialized before use.
 */
static sslSelfEncryptKeys ssl_self_encrypt_keys;

/* Externalize the self encrypt keys. Purely used for testing. */
sslSelfEncryptKeys *
ssl_GetSelfEncryptKeysInt()
{
    return &ssl_self_encrypt_keys;
}

static void
ssl_CleanupSelfEncryptKeyPair()
{
    if (ssl_self_encrypt_key_pair.pubKey) {
        PORT_Assert(ssl_self_encrypt_key_pair.privKey);
        SECKEY_DestroyPublicKey(ssl_self_encrypt_key_pair.pubKey);
        SECKEY_DestroyPrivateKey(ssl_self_encrypt_key_pair.privKey);
    }
}

void
ssl_ResetSelfEncryptKeys()
{
    if (ssl_self_encrypt_keys.encKey) {
        PORT_Assert(ssl_self_encrypt_keys.macKey);
        PK11_FreeSymKey(ssl_self_encrypt_keys.encKey);
        PK11_FreeSymKey(ssl_self_encrypt_keys.macKey);
    }
    PORT_Memset(&ssl_self_encrypt_keys, 0,
                sizeof(ssl_self_encrypt_keys));
}

static SECStatus
ssl_SelfEncryptShutdown(void *appData, void *nssData)
{
    ssl_CleanupSelfEncryptKeyPair();
    PR_DestroyRWLock(ssl_self_encrypt_key_pair.lock);
    PORT_Memset(&ssl_self_encrypt_key_pair, 0,
                sizeof(ssl_self_encrypt_key_pair));

    ssl_ResetSelfEncryptKeys();
    return SECSuccess;
}

static PRStatus
ssl_SelfEncryptSetup(void)
{
    SECStatus rv = NSS_RegisterShutdown(ssl_SelfEncryptShutdown, NULL);
    if (rv != SECSuccess) {
        return PR_FAILURE;
    }
    ssl_self_encrypt_key_pair.lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, NULL);
    if (!ssl_self_encrypt_key_pair.lock) {
        return PR_FAILURE;
    }
    return PR_SUCCESS;
}

/* Configure a self encryption key pair.  |explicitConfig| is set to true for
 * calls to SSL_SetSessionTicketKeyPair(), false for implicit configuration.
 * This assumes that the setup has been run. */
static SECStatus
ssl_SetSelfEncryptKeyPair(SECKEYPublicKey *pubKey,
                          SECKEYPrivateKey *privKey,
                          PRBool explicitConfig)
{
    SECKEYPublicKey *pubKeyCopy, *oldPubKey;
    SECKEYPrivateKey *privKeyCopy, *oldPrivKey;

    PORT_Assert(ssl_self_encrypt_key_pair.lock);
    pubKeyCopy = SECKEY_CopyPublicKey(pubKey);
    privKeyCopy = SECKEY_CopyPrivateKey(privKey);

    if (!pubKeyCopy || !privKeyCopy) {
        SECKEY_DestroyPublicKey(pubKeyCopy);
        SECKEY_DestroyPrivateKey(privKeyCopy);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    PR_RWLock_Wlock(ssl_self_encrypt_key_pair.lock);
    oldPubKey = ssl_self_encrypt_key_pair.pubKey;
    oldPrivKey = ssl_self_encrypt_key_pair.privKey;
    ssl_self_encrypt_key_pair.pubKey = pubKeyCopy;
    ssl_self_encrypt_key_pair.privKey = privKeyCopy;
    ssl_self_encrypt_key_pair.configured = explicitConfig;
    PR_RWLock_Unlock(ssl_self_encrypt_key_pair.lock);

    if (oldPubKey) {
        PORT_Assert(oldPrivKey);
        SECKEY_DestroyPublicKey(oldPubKey);
        SECKEY_DestroyPrivateKey(oldPrivKey);
    }

    return SECSuccess;
}

/* This is really the self-encryption keys but it has the
 * wrong name for historical API stability reasons. */
SECStatus
SSL_SetSessionTicketKeyPair(SECKEYPublicKey *pubKey,
                            SECKEYPrivateKey *privKey)
{
    if (SECKEY_GetPublicKeyType(pubKey) != rsaKey ||
        SECKEY_GetPrivateKeyType(privKey) != rsaKey) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    if (PR_SUCCESS != PR_CallOnce(&ssl_self_encrypt_key_pair.setup,
                                  &ssl_SelfEncryptSetup)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    return ssl_SetSelfEncryptKeyPair(pubKey, privKey, PR_TRUE);
}

/* When configuring a server cert, we should save the RSA key in case it is
 * needed for self-encryption. This saves the latest copy, unless there has
 * been an explicit call to SSL_SetSessionTicketKeyPair(). */
SECStatus
ssl_MaybeSetSelfEncryptKeyPair(const sslKeyPair *keyPair)
{
    PRBool configured;

    if (PR_SUCCESS != PR_CallOnce(&ssl_self_encrypt_key_pair.setup,
                                  &ssl_SelfEncryptSetup)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    PR_RWLock_Rlock(ssl_self_encrypt_key_pair.lock);
    configured = ssl_self_encrypt_key_pair.configured;
    PR_RWLock_Unlock(ssl_self_encrypt_key_pair.lock);
    if (configured) {
        return SECSuccess;
    }
    return ssl_SetSelfEncryptKeyPair(keyPair->pubKey,
                                     keyPair->privKey, PR_FALSE);
}

static SECStatus
ssl_GetSelfEncryptKeyPair(SECKEYPublicKey **pubKey,
                          SECKEYPrivateKey **privKey)
{
    if (PR_SUCCESS != PR_CallOnce(&ssl_self_encrypt_key_pair.setup,
                                  &ssl_SelfEncryptSetup)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    SECKEYPublicKey *pubKeyCopy = NULL;
    SECKEYPrivateKey *privKeyCopy = NULL;
    PRBool noKey = PR_FALSE;

    PR_RWLock_Rlock(ssl_self_encrypt_key_pair.lock);
    if (ssl_self_encrypt_key_pair.pubKey && ssl_self_encrypt_key_pair.privKey) {
        pubKeyCopy = SECKEY_CopyPublicKey(ssl_self_encrypt_key_pair.pubKey);
        privKeyCopy = SECKEY_CopyPrivateKey(ssl_self_encrypt_key_pair.privKey);
    } else {
        noKey = PR_TRUE;
    }
    PR_RWLock_Unlock(ssl_self_encrypt_key_pair.lock);

    if (noKey) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (!pubKeyCopy || !privKeyCopy) {
        SECKEY_DestroyPublicKey(pubKeyCopy);
        SECKEY_DestroyPrivateKey(privKeyCopy);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    *pubKey = pubKeyCopy;
    *privKey = privKeyCopy;
    return SECSuccess;
}

static PRBool
ssl_GenerateSelfEncryptKeys(void *pwArg, PRUint8 *keyName,
                            PK11SymKey **aesKey, PK11SymKey **macKey);

static PRStatus
ssl_GenerateSelfEncryptKeysOnce(void *arg)
{
    SECStatus rv;

    /* Get a copy of the session keys from shared memory. */
    PORT_Memcpy(ssl_self_encrypt_keys.keyName,
                SELF_ENCRYPT_KEY_NAME_PREFIX,
                sizeof(SELF_ENCRYPT_KEY_NAME_PREFIX));
    /* This function calls ssl_GetSelfEncryptKeyPair(), which initializes the
     * key pair stuff.  That allows this to use the same shutdown function. */
    rv = ssl_GenerateSelfEncryptKeys(arg, ssl_self_encrypt_keys.keyName,
                                     &ssl_self_encrypt_keys.encKey,
                                     &ssl_self_encrypt_keys.macKey);
    if (rv != SECSuccess) {
        return PR_FAILURE;
    }

    return PR_SUCCESS;
}

SECStatus
ssl_GetSelfEncryptKeys(sslSocket *ss, PRUint8 *keyName,
                       PK11SymKey **encKey, PK11SymKey **macKey)
{
    if (PR_SUCCESS != PR_CallOnceWithArg(&ssl_self_encrypt_keys.setup,
                                         &ssl_GenerateSelfEncryptKeysOnce,
                                         ss->pkcs11PinArg)) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    if (!ssl_self_encrypt_keys.encKey || !ssl_self_encrypt_keys.macKey) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    PORT_Memcpy(keyName, ssl_self_encrypt_keys.keyName,
                sizeof(ssl_self_encrypt_keys.keyName));
    *encKey = ssl_self_encrypt_keys.encKey;
    *macKey = ssl_self_encrypt_keys.macKey;
    return SECSuccess;
}

/* If lockTime is zero, it implies that the lock is not held, and must be
 * aquired here.
 */
static SECStatus
getSvrWrappingKey(unsigned int symWrapMechIndex,
                  unsigned int wrapKeyIndex,
                  SSLWrappedSymWrappingKey *wswk,
                  cacheDesc *cache,
                  PRUint32 lockTime)
{
    PRUint32 ndx = (wrapKeyIndex * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
    SSLWrappedSymWrappingKey *pwswk = cache->keyCacheData + ndx;
    PRUint32 now = 0;
    PRBool rv = SECFailure;

    if (!cache->cacheMem) { /* cache is uninitialized */
        PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
        return SECFailure;
    }
    if (!lockTime) {
        now = LockSidCacheLock(cache->keyCacheLock, 0);
        if (!now) {
            return SECFailure;
        }
    }
    if (pwswk->wrapKeyIndex == wrapKeyIndex &&
        pwswk->wrapMechIndex == symWrapMechIndex &&
        pwswk->wrappedSymKeyLen != 0) {
        *wswk = *pwswk;
        rv = SECSuccess;
    }
    if (now) {
        UnlockSidCacheLock(cache->keyCacheLock);
    }
    return rv;
}

SECStatus
ssl_GetWrappingKey(unsigned int wrapMechIndex,
                   unsigned int wrapKeyIndex,
                   SSLWrappedSymWrappingKey *wswk)
{
    PORT_Assert(wrapMechIndex < SSL_NUM_WRAP_MECHS);
    PORT_Assert(wrapKeyIndex < SSL_NUM_WRAP_KEYS);
    if (wrapMechIndex >= SSL_NUM_WRAP_MECHS ||
        wrapKeyIndex >= SSL_NUM_WRAP_KEYS) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    return getSvrWrappingKey(wrapMechIndex, wrapKeyIndex, wswk,
                             &globalCache, 0);
}

/* Wrap and cache a session ticket key. */
static SECStatus
WrapSelfEncryptKey(SECKEYPublicKey *svrPubKey, PK11SymKey *symKey,
                   const char *keyName, encKeyCacheEntry *cacheEntry)
{
    SECItem wrappedKey = { siBuffer, NULL, 0 };

    wrappedKey.len = SECKEY_PublicKeyStrength(svrPubKey);
    PORT_Assert(wrappedKey.len <= sizeof(cacheEntry->bytes));
    if (wrappedKey.len > sizeof(cacheEntry->bytes))
        return PR_FALSE;
    wrappedKey.data = cacheEntry->bytes;

    if (PK11_PubWrapSymKey(CKM_RSA_PKCS, svrPubKey, symKey, &wrappedKey) !=
        SECSuccess) {
        SSL_DBG(("%d: SSL[%s]: Unable to wrap self encrypt key %s.",
                 SSL_GETPID(), "unknown", keyName));
        return SECFailure;
    }
    cacheEntry->length = wrappedKey.len;
    return SECSuccess;
}

static SECStatus
GenerateSelfEncryptKeys(void *pwArg, PRUint8 *keyName, PK11SymKey **aesKey,
                        PK11SymKey **macKey)
{
    PK11SlotInfo *slot;
    CK_MECHANISM_TYPE mechanismArray[2];
    PK11SymKey *aesKeyTmp = NULL;
    PK11SymKey *macKeyTmp = NULL;
    cacheDesc *cache = &globalCache;
    PRUint8 ticketKeyNameSuffixLocal[SELF_ENCRYPT_KEY_VAR_NAME_LEN];
    PRUint8 *ticketKeyNameSuffix;

    if (!cache->cacheMem) {
        /* cache is not initalized. Use stack buffer */
        ticketKeyNameSuffix = ticketKeyNameSuffixLocal;
    } else {
        ticketKeyNameSuffix = cache->ticketKeyNameSuffix;
    }

    if (PK11_GenerateRandom(ticketKeyNameSuffix,
                            SELF_ENCRYPT_KEY_VAR_NAME_LEN) !=
        SECSuccess) {
        SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.",
                 SSL_GETPID(), "unknown"));
        return SECFailure;
    }

    mechanismArray[0] = CKM_AES_CBC;
    mechanismArray[1] = CKM_SHA256_HMAC;

    slot = PK11_GetBestSlotMultiple(mechanismArray, 2, pwArg);
    if (slot) {
        aesKeyTmp = PK11_KeyGen(slot, mechanismArray[0], NULL,
                                AES_256_KEY_LENGTH, pwArg);
        macKeyTmp = PK11_KeyGen(slot, mechanismArray[1], NULL,
                                SHA256_LENGTH, pwArg);
        PK11_FreeSlot(slot);
    }

    if (aesKeyTmp == NULL || macKeyTmp == NULL) {
        SSL_DBG(("%d: SSL[%s]: Unable to generate session ticket keys.",
                 SSL_GETPID(), "unknown"));
        goto loser;
    }
    PORT_Memcpy(keyName, ticketKeyNameSuffix, SELF_ENCRYPT_KEY_VAR_NAME_LEN);
    *aesKey = aesKeyTmp;
    *macKey = macKeyTmp;
    return SECSuccess;

loser:
    if (aesKeyTmp)
        PK11_FreeSymKey(aesKeyTmp);
    if (macKeyTmp)
        PK11_FreeSymKey(macKeyTmp);
    return SECFailure;
}

static SECStatus
GenerateAndWrapSelfEncryptKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
                               PRUint8 *keyName, PK11SymKey **aesKey,
                               PK11SymKey **macKey)
{
    PK11SymKey *aesKeyTmp = NULL;
    PK11SymKey *macKeyTmp = NULL;
    cacheDesc *cache = &globalCache;
    SECStatus rv;

    rv = GenerateSelfEncryptKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp);
    if (rv != SECSuccess) {
        return SECFailure;
    }

    if (cache->cacheMem) {
        /* Export the keys to the shared cache in wrapped form. */
        rv = WrapSelfEncryptKey(svrPubKey, aesKeyTmp, "enc key", cache->ticketEncKey);
        if (rv != SECSuccess) {
            goto loser;
        }
        rv = WrapSelfEncryptKey(svrPubKey, macKeyTmp, "mac key", cache->ticketMacKey);
        if (rv != SECSuccess) {
            goto loser;
        }
    }
    *aesKey = aesKeyTmp;
    *macKey = macKeyTmp;
    return SECSuccess;

loser:
    PK11_FreeSymKey(aesKeyTmp);
    PK11_FreeSymKey(macKeyTmp);
    return SECFailure;
}

static SECStatus
UnwrapCachedSelfEncryptKeys(SECKEYPrivateKey *svrPrivKey, PRUint8 *keyName,
                            PK11SymKey **aesKey, PK11SymKey **macKey)
{
    SECItem wrappedKey = { siBuffer, NULL, 0 };
    PK11SymKey *aesKeyTmp = NULL;
    PK11SymKey *macKeyTmp = NULL;
    cacheDesc *cache = &globalCache;

    wrappedKey.data = cache->ticketEncKey->bytes;
    wrappedKey.len = cache->ticketEncKey->length;
    PORT_Assert(wrappedKey.len <= sizeof(cache->ticketEncKey->bytes));
    aesKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
                                     CKM_AES_CBC, CKA_DECRYPT, 0);

    wrappedKey.data = cache->ticketMacKey->bytes;
    wrappedKey.len = cache->ticketMacKey->length;
    PORT_Assert(wrappedKey.len <= sizeof(cache->ticketMacKey->bytes));
    macKeyTmp = PK11_PubUnwrapSymKey(svrPrivKey, &wrappedKey,
                                     CKM_SHA256_HMAC, CKA_SIGN, 0);

    if (aesKeyTmp == NULL || macKeyTmp == NULL) {
        SSL_DBG(("%d: SSL[%s]: Unable to unwrap session ticket keys.",
                 SSL_GETPID(), "unknown"));
        goto loser;
    }
    SSL_DBG(("%d: SSL[%s]: Successfully unwrapped session ticket keys.",
             SSL_GETPID(), "unknown"));

    PORT_Memcpy(keyName, cache->ticketKeyNameSuffix,
                SELF_ENCRYPT_KEY_VAR_NAME_LEN);
    *aesKey = aesKeyTmp;
    *macKey = macKeyTmp;
    return SECSuccess;

loser:
    if (aesKeyTmp)
        PK11_FreeSymKey(aesKeyTmp);
    if (macKeyTmp)
        PK11_FreeSymKey(macKeyTmp);
    return SECFailure;
}

static SECStatus
ssl_GenerateSelfEncryptKeys(void *pwArg, PRUint8 *keyName,
                            PK11SymKey **encKey, PK11SymKey **macKey)
{
    SECKEYPrivateKey *svrPrivKey = NULL;
    SECKEYPublicKey *svrPubKey = NULL;
    PRUint32 now;
    cacheDesc *cache = &globalCache;

    SECStatus rv = ssl_GetSelfEncryptKeyPair(&svrPubKey, &svrPrivKey);
    if (rv != SECSuccess || !cache->cacheMem) {
        /* No key pair for wrapping, or the cache is uninitialized. Generate
         * keys and return them without caching. */
        rv = GenerateSelfEncryptKeys(pwArg, keyName, encKey, macKey);
    } else {
        now = LockSidCacheLock(cache->keyCacheLock, 0);
        if (!now) {
            goto loser;
        }

        if (*(cache->ticketKeysValid)) {
            rv = UnwrapCachedSelfEncryptKeys(svrPrivKey, keyName, encKey, macKey);
        } else {
            /* Keys do not exist, create them. */
            rv = GenerateAndWrapSelfEncryptKeys(svrPubKey, pwArg, keyName,
                                                encKey, macKey);
            if (rv == SECSuccess) {
                *(cache->ticketKeysValid) = 1;
            }
        }
        UnlockSidCacheLock(cache->keyCacheLock);
    }
    SECKEY_DestroyPublicKey(svrPubKey);
    SECKEY_DestroyPrivateKey(svrPrivKey);
    return rv;

loser:
    UnlockSidCacheLock(cache->keyCacheLock);
    SECKEY_DestroyPublicKey(svrPubKey);
    SECKEY_DestroyPrivateKey(svrPrivKey);
    return SECFailure;
}

/* The caller passes in the new value it wants
 * to set.  This code tests the wrapped sym key entry in the shared memory.
 * If it is uninitialized, this function writes the caller's value into
 * the disk entry, and returns false.
 * Otherwise, it overwrites the caller's wswk with the value obtained from
 * the disk, and returns PR_TRUE.
 * This is all done while holding the locks/mutexes necessary to make
 * the operation atomic.
 */
SECStatus
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
{
    cacheDesc *cache = &globalCache;
    PRBool rv = SECFailure;
    PRUint32 ndx;
    PRUint32 now;
    SSLWrappedSymWrappingKey myWswk;

    if (!cache->cacheMem) { /* cache is uninitialized */
        PORT_SetError(SSL_ERROR_SERVER_CACHE_NOT_CONFIGURED);
        return SECFailure;
    }

    PORT_Assert(wswk->wrapMechIndex < SSL_NUM_WRAP_MECHS);
    PORT_Assert(wswk->wrapKeyIndex < SSL_NUM_WRAP_KEYS);
    if (wswk->wrapMechIndex >= SSL_NUM_WRAP_MECHS ||
        wswk->wrapKeyIndex >= SSL_NUM_WRAP_KEYS) {
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }

    ndx = (wswk->wrapKeyIndex * SSL_NUM_WRAP_MECHS) + wswk->wrapMechIndex;
    PORT_Memset(&myWswk, 0, sizeof myWswk); /* eliminate UMRs. */

    now = LockSidCacheLock(cache->keyCacheLock, 0);
    if (!now) {
        return SECFailure;
    }
    rv = getSvrWrappingKey(wswk->wrapMechIndex, wswk->wrapKeyIndex,
                           &myWswk, cache, now);
    if (rv == SECSuccess) {
        /* we found it on disk, copy it out to the caller. */
        PORT_Memcpy(wswk, &myWswk, sizeof *wswk);
    } else {
        /* Wasn't on disk, and we're still holding the lock, so write it. */
        cache->keyCacheData[ndx] = *wswk;
    }
    UnlockSidCacheLock(cache->keyCacheLock);
    return rv;
}

#else /* MAC version or other platform */

#include "seccomon.h"
#include "cert.h"
#include "ssl.h"
#include "sslimpl.h"

SECStatus
SSL_ConfigServerSessionIDCache(int maxCacheEntries,
                               PRUint32 ssl2_timeout,
                               PRUint32 ssl3_timeout,
                               const char *directory)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigServerSessionIDCache)");
    return SECFailure;
}

SECStatus
SSL_ConfigMPServerSIDCache(int maxCacheEntries,
                           PRUint32 ssl2_timeout,
                           PRUint32 ssl3_timeout,
                           const char *directory)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_ConfigMPServerSIDCache)");
    return SECFailure;
}

SECStatus
SSL_InheritMPServerSIDCache(const char *envString)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_InheritMPServerSIDCache)");
    return SECFailure;
}

SECStatus
ssl_GetWrappingKey(unsigned int wrapMechIndex,
                   unsigned int wrapKeyIndex,
                   SSLWrappedSymWrappingKey *wswk)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)");
    return SECFailure;
}

/* This is a kind of test-and-set.  The caller passes in the new value it wants
 * to set.  This code tests the wrapped sym key entry in the shared memory.
 * If it is uninitialized, this function writes the caller's value into
 * the disk entry, and returns false.
 * Otherwise, it overwrites the caller's wswk with the value obtained from
 * the disk, and returns PR_TRUE.
 * This is all done while holding the locks/mutexes necessary to make
 * the operation atomic.
 */
SECStatus
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)");
    return SECFailure;
}

PRUint32
SSL_GetMaxServerCacheLocks(void)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_GetMaxServerCacheLocks)");
    return -1;
}

SECStatus
SSL_SetMaxServerCacheLocks(PRUint32 maxLocks)
{
    PR_ASSERT(!"SSL servers are not supported on this platform. (SSL_SetMaxServerCacheLocks)");
    return SECFailure;
}

#endif /* XP_UNIX || XP_WIN32 */
