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

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

static PRUint32
LockSidCacheLock(sidCacheLock *lock, PRUint32 now)
{
    SECStatus rv = sslMutex_Lock(&lock->mutex);
    if (rv != SECSuccess)
        return 0;
    if (!now)
        now = ssl_TimeSec();
    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 the value of ssl_TimeSec 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.
 */
static sslSessionID *
ServerSessionIDLookup(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_Assert(!("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_Assert(!("Didn't get name Cache Lock!"));
                psce = 0;
                psnce = 0;
            }
        }
        if (psce) {
            psce->lastAccessTime = now;
            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)
{
    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 = ssl_TimeUsec();
        /* 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_TimeSec();
    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_Init();
    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_Init();

    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_TimeSec();
        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;
    SECKEYPrivateKey *privKeyCopy;

    PORT_Assert(ssl_self_encrypt_key_pair.lock);

    pubKeyCopy = SECKEY_CopyPublicKey(pubKey);
    if (!pubKeyCopy) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    privKeyCopy = SECKEY_CopyPrivateKey(privKey);
    if (!privKeyCopy) {
        SECKEY_DestroyPublicKey(pubKeyCopy);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return SECFailure;
    }

    PR_RWLock_Wlock(ssl_self_encrypt_key_pair.lock);
    ssl_CleanupSelfEncryptKeyPair();
    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);
    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;
    }

    PR_RWLock_Rlock(ssl_self_encrypt_key_pair.lock);
    *pubKey = ssl_self_encrypt_key_pair.pubKey;
    *privKey = ssl_self_encrypt_key_pair.privKey;
    PR_RWLock_Unlock(ssl_self_encrypt_key_pair.lock);
    if (!*pubKey) {
        PORT_Assert(!*privKey);
        PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
        return SECFailure;
    }
    PORT_Assert(*privKey);
    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;
    SECKEYPublicKey *svrPubKey;
    PRUint32 now;
    SECStatus rv;
    cacheDesc *cache = &globalCache;

    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. */
        return GenerateSelfEncryptKeys(pwArg, keyName, encKey, macKey);
    }

    now = LockSidCacheLock(cache->keyCacheLock, 0);
    if (!now)
        return SECFailure;

    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);
    return rv;
}

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