/* 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[kt_kea_size][SSL_NUM_WRAP_MECHS];
 *     PRUint8                  keyNameSuffix[SESS_TICKET_KEY_VAR_NAME_LEN]
 *     encKeyCacheEntry         ticketEncKey; // Wrapped in non-bypass mode
 *     encKeyCacheEntry         ticketMacKey; // Wrapped in non-bypass mode
 *     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"
#ifdef NO_PKCS11_BYPASS
#include "blapit.h"
#include "sechash.h"
#else
#include "blapi.h"
#endif

#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>

#define SET_ERROR_CODE /* reminder */

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

/*
** Format of a cache entry in the shared memory.
*/ 
struct sidCacheEntryStr {
/* 16 */    PRIPv6Addr  addr;	/* client's IP address */
/*  4 */    PRUint32    creationTime;
/*  4 */    PRUint32    lastAccessTime;	
/*  4 */    PRUint32    expirationTime;
/*  2 */    PRUint16	version;
/*  1 */    PRUint8	valid;
/*  1 */    PRUint8     sessionIDLength;
/* 32 */    PRUint8     sessionID[SSL3_SESSIONID_BYTES];
/*  2 */    PRUint16    authAlgorithm;
/*  2 */    PRUint16    authKeyBits;
/*  2 */    PRUint16    keaType;
/*  2 */    PRUint16    keaKeyBits;
/* 72  - common header total */

    union {
	struct {
/* 64 */    PRUint8	masterKey[SSL_MAX_MASTER_KEY_BYTES];
/* 32 */    PRUint8	cipherArg[SSL_MAX_CYPHER_ARG_BYTES];

/*  1 */    PRUint8	cipherType;
/*  1 */    PRUint8	masterKeyLen;
/*  1 */    PRUint8	keyBits;
/*  1 */    PRUint8	secretKeyBits;
/*  1 */    PRUint8	cipherArgLen;
/*101 */} ssl2;

	struct {
/*  2 */    ssl3CipherSuite  cipherSuite;
/*  2 */    PRUint16    compression; 	/* SSLCompressionMethod */

/* 52 */    ssl3SidKeys keys;	/* keys, wrapped as needed. */

/*  4 */    PRUint32    masterWrapMech; 
/*  4 */    SSL3KEAType exchKeyType;
/*  4 */    PRInt32     certIndex;
/*  4 */    PRInt32     srvNameIndex;
/* 32 */    PRUint8     srvNameHash[SHA256_LENGTH]; /* SHA256 name hash */
/*104 */} ssl3;
/* force sizeof(sidCacheEntry) to be a multiple of cache line size */
        struct {
/*120 */    PRUint8     filler[120]; /* 72+120==192, 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		ssl2Timeout;
    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_SSL2_TIMEOUT	100   /* seconds */
#define MAX_SSL2_TIMEOUT	100   /* seconds */
#define MIN_SSL2_TIMEOUT	  5   /* seconds */

#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_Time();
    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_Time 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);
#ifdef NO_PKCS11_BYPASS
    HASH_HashBuf(HASH_AlgSHA256, snce.nameHash, name->data, name->len);
#else
    SHA256_HashBuf(snce.nameHash, (unsigned char*)name->data,
                   name->len);
#endif
    /* 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->authAlgorithm	= from->authAlgorithm;
    to->authKeyBits	= from->authKeyBits;
    to->keaType		= from->keaType;
    to->keaKeyBits	= from->keaKeyBits;

    if (from->version < SSL_LIBRARY_VERSION_3_0) {
	if ((from->u.ssl2.masterKey.len > SSL_MAX_MASTER_KEY_BYTES) ||
	    (from->u.ssl2.cipherArg.len > SSL_MAX_CYPHER_ARG_BYTES)) {
	    SSL_DBG(("%d: SSL: masterKeyLen=%d cipherArgLen=%d",
		     myPid, from->u.ssl2.masterKey.len,
		     from->u.ssl2.cipherArg.len));
	    to->valid = 0;
	    return;
	}

	to->u.ssl2.cipherType    = from->u.ssl2.cipherType;
	to->u.ssl2.masterKeyLen  = from->u.ssl2.masterKey.len;
	to->u.ssl2.cipherArgLen  = from->u.ssl2.cipherArg.len;
	to->u.ssl2.keyBits       = from->u.ssl2.keyBits;
	to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
	to->sessionIDLength      = SSL2_SESSIONID_BYTES;
	PORT_Memcpy(to->sessionID, from->u.ssl2.sessionID, SSL2_SESSIONID_BYTES);
	PORT_Memcpy(to->u.ssl2.masterKey, from->u.ssl2.masterKey.data,
		  from->u.ssl2.masterKey.len);
	PORT_Memcpy(to->u.ssl2.cipherArg, from->u.ssl2.cipherArg.data,
		  from->u.ssl2.cipherArg.len);
#ifdef DEBUG
	PORT_Memset(to->u.ssl2.masterKey+from->u.ssl2.masterKey.len, 0,
		  sizeof(to->u.ssl2.masterKey) - from->u.ssl2.masterKey.len);
	PORT_Memset(to->u.ssl2.cipherArg+from->u.ssl2.cipherArg.len, 0,
		  sizeof(to->u.ssl2.cipherArg) - from->u.ssl2.cipherArg.len);
#endif
	SSL_TRC(8, ("%d: SSL: ConvertSID: masterKeyLen=%d cipherArgLen=%d "
		    "time=%d addr=0x%08x%08x%08x%08x cipherType=%d", myPid,
		    to->u.ssl2.masterKeyLen, to->u.ssl2.cipherArgLen,
		    to->creationTime, 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.ssl2.cipherType));
    } else {
	/* This is an SSL v3 session */

	to->u.ssl3.cipherSuite      = from->u.ssl3.cipherSuite;
	to->u.ssl3.compression      = (PRUint16)from->u.ssl3.compression;
	to->u.ssl3.keys             = from->u.ssl3.keys;
	to->u.ssl3.masterWrapMech   = from->u.ssl3.masterWrapMech;
	to->u.ssl3.exchKeyType      = from->u.ssl3.exchKeyType;
	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);

	SSL_TRC(8, ("%d: SSL3: ConvertSID: time=%d addr=0x%08x%08x%08x%08x "
	            "cipherSuite=%d",
		    myPid, to->creationTime, 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;
    PRUint16 version = from->version;

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

    if (version < SSL_LIBRARY_VERSION_3_0) {
	/* This is an SSL v2 session */
	to->u.ssl2.masterKey.data =
	    (unsigned char*) PORT_Alloc(from->u.ssl2.masterKeyLen);
	if (!to->u.ssl2.masterKey.data) {
	    goto loser;
	}
	if (from->u.ssl2.cipherArgLen) {
	    to->u.ssl2.cipherArg.data = 
	    	(unsigned char*)PORT_Alloc(from->u.ssl2.cipherArgLen);
	    if (!to->u.ssl2.cipherArg.data) {
		goto loser;
	    }
	    PORT_Memcpy(to->u.ssl2.cipherArg.data, from->u.ssl2.cipherArg,
		        from->u.ssl2.cipherArgLen);
	}

	to->u.ssl2.cipherType    = from->u.ssl2.cipherType;
	to->u.ssl2.masterKey.len = from->u.ssl2.masterKeyLen;
	to->u.ssl2.cipherArg.len = from->u.ssl2.cipherArgLen;
	to->u.ssl2.keyBits       = from->u.ssl2.keyBits;
	to->u.ssl2.secretKeyBits = from->u.ssl2.secretKeyBits;
/*	to->sessionIDLength      = SSL2_SESSIONID_BYTES; */
	PORT_Memcpy(to->u.ssl2.sessionID, from->sessionID, SSL2_SESSIONID_BYTES);
	PORT_Memcpy(to->u.ssl2.masterKey.data, from->u.ssl2.masterKey,
		    from->u.ssl2.masterKeyLen);

	SSL_TRC(8, ("%d: SSL: ConvertToSID: masterKeyLen=%d cipherArgLen=%d "
		    "time=%d addr=0x%08x%08x%08x%08x cipherType=%d",
		    myPid, to->u.ssl2.masterKey.len,
		    to->u.ssl2.cipherArg.len, to->creationTime,
		    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.ssl2.cipherType));
    } else {
	/* This is an SSL v3 session */

	to->u.ssl3.sessionIDLength  = from->sessionIDLength;
	to->u.ssl3.cipherSuite      = from->u.ssl3.cipherSuite;
	to->u.ssl3.compression      = (SSLCompressionMethod)from->u.ssl3.compression;
	to->u.ssl3.keys             = from->u.ssl3.keys;
	to->u.ssl3.masterWrapMech   = from->u.ssl3.masterWrapMech;
	to->u.ssl3.exchKeyType      = from->u.ssl3.exchKeyType;
	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);

	/* the portions of the SID that are only restored on the client
	 * are set to invalid values on the server.
	 */
	to->u.ssl3.clientWriteKey   = NULL;
	to->u.ssl3.serverWriteKey   = NULL;

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

    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->authAlgorithm	= from->authAlgorithm;
    to->authKeyBits	= from->authKeyBits;
    to->keaType		= from->keaType;
    to->keaKeyBits	= from->keaKeyBits;
    
    return to;

  loser:
    if (to) {
	if (version < SSL_LIBRARY_VERSION_3_0) {
	    if (to->u.ssl2.masterKey.data)
		PORT_Free(to->u.ssl2.masterKey.data);
	    if (to->u.ssl2.cipherArg.data)
		PORT_Free(to->u.ssl2.cipherArg.data);
	} else {
            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 (psce->version >= SSL_LIBRARY_VERSION_3_0) {
	    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. 
*/
static void 
ServerSessionIDCache(sslSessionID *sid)
{
    sidCacheEntry sce;
    PRUint32      now     = 0;
    PRUint16      version = sid->version;
    cacheDesc *   cache   = &globalCache;

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

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

	PORT_Assert(sid->creationTime != 0);
	if (!sid->creationTime)
	    sid->lastAccessTime = sid->creationTime = ssl_Time();
	if (version < SSL_LIBRARY_VERSION_3_0) {
	    /* override caller's expiration time, which uses client timeout
	     * duration, not server timeout duration.
	     */
	    sid->expirationTime = sid->creationTime + cache->ssl2Timeout;
	    SSL_TRC(8, ("%d: SSL: CacheMT: cached=%d addr=0x%08x%08x%08x%08x time=%x "
			"cipher=%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, sid->u.ssl2.cipherType));
	    PRINT_BUF(8, (0, "sessionID:", sid->u.ssl2.sessionID,
			  SSL2_SESSIONID_BYTES));
	    PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
			  sid->u.ssl2.masterKey.len));
	    PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
			  sid->u.ssl2.cipherArg.len));

	} else {
	    /* override caller's expiration time, which uses client timeout
	     * duration, not server timeout duration.
	     */
	    sid->expirationTime = sid->creationTime + cache->ssl3Timeout;
	    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, sid->u.ssl3.cipherSuite));
	    PRINT_BUF(8, (0, "sessionID:", sid->u.ssl3.sessionID,
			  sid->u.ssl3.sessionIDLength));
	}

	ConvertFromSID(&sce, sid);

	if (version >= SSL_LIBRARY_VERSION_3_0) {
            SECItem *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.
*/
static void 
ServerSessionIDUncache(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();

    if (sid->version < SSL_LIBRARY_VERSION_3_0) {
	sessionID       = sid->u.ssl2.sessionID;
	sessionIDLength = SSL2_SESSIONID_BYTES;
	SSL_TRC(8, ("%d: SSL: UncacheMT: valid=%d addr=0x%08x%08x%08x%08x time=%x "
		    "cipher=%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, sid->u.ssl2.cipherType));
	PRINT_BUF(8, (0, "sessionID:", sessionID, sessionIDLength));
	PRINT_BUF(8, (0, "masterKey:", sid->u.ssl2.masterKey.data,
		      sid->u.ssl2.masterKey.len));
	PRINT_BUF(8, (0, "cipherArg:", sid->u.ssl2.cipherArg.data,
		      sid->u.ssl2.cipherArg.len));
    } else {
	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, 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 ssl2_timeout, 
          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 = kt_kea_size * 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 +
	SESS_TICKET_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 (ssl2_timeout) {   
	if (ssl2_timeout > MAX_SSL2_TIMEOUT) {
	    ssl2_timeout = MAX_SSL2_TIMEOUT;
	}
	if (ssl2_timeout < MIN_SSL2_TIMEOUT) {
	    ssl2_timeout = MIN_SSL2_TIMEOUT;
	}
	cache->ssl2Timeout = ssl2_timeout;
    } else {
	cache->ssl2Timeout = DEF_SSL2_TIMEOUT;
    }

    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 
    */
    ptr = (ptrdiff_t)cache->cacheMem;
    *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
    *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
    *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
    *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
    *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
    *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
    *(ptrdiff_t *)(&cache->certCacheData) += ptr;
    *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
    *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
    *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
    *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
    *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
    *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;

    /* initialize the locks */
    init_time = ssl_Time();
    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);
    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;
}

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

    PORT_Assert(sizeof(sidCacheEntry) == 192);
    PORT_Assert(sizeof(certCacheEntry) == 4096);
    PORT_Assert(sizeof(srvNameCacheEntry) == 1072);

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

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

    ssl_sid_lookup  = ServerSessionIDLookup;
    ssl_sid_cache   = ServerSessionIDCache;
    ssl_sid_uncache = ServerSessionIDUncache;
    return SECSuccess;
}

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

SECStatus
SSL_ConfigServerSessionIDCache(	int      maxCacheEntries, 
				PRUint32 ssl2_timeout,
			       	PRUint32 ssl3_timeout, 
			  const char *   directory)
{
    ssl_InitSessionCacheLocks();
    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 ssl2_timeout,
                                        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,
                  ssl2_timeout, 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))) {
	SET_ERROR_CODE
	return SECFailure;
    }

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

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

    putEnvFailed = (SECStatus)NSS_PutEnv(envVarName, envValue);
    PR_smprintf_free(envValue);
    if (putEnvFailed) {
        SET_ERROR_CODE
        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(ssl2_timeout,
                                             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();
        return ssl_ConfigServerSessionIDCacheInstanceWithOpt(&globalCache, 
           ssl2_timeout, ssl3_timeout, directory, PR_FALSE,
           maxCacheEntries, maxCertCacheEntries, maxSrvNameCacheEntries);
    } else {
        return ssl_ConfigMPServerSIDCacheWithOpt(ssl2_timeout, 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;
    ptrdiff_t       ptr;
    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();

    ssl_sid_lookup  = ServerSessionIDLookup;
    ssl_sid_cache   = ServerSessionIDCache;
    ssl_sid_uncache = ServerSessionIDUncache;

    if (!envString) {
    	envString  = getenv(envVarName);
	if (!envString) {
	    SET_ERROR_CODE
	    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) {
    	SET_ERROR_CODE
	goto loser;
    }
    if (decoLen != sizeof inherit) {
    	SET_ERROR_CODE
    	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) {
	SET_ERROR_CODE
    	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".
    */
    ptr = (ptrdiff_t)my.cacheMem;
    *(ptrdiff_t *)(&cache->sidCacheLocks) += ptr;
    *(ptrdiff_t *)(&cache->keyCacheLock ) += ptr;
    *(ptrdiff_t *)(&cache->certCacheLock) += ptr;
    *(ptrdiff_t *)(&cache->srvNameCacheLock) += ptr;
    *(ptrdiff_t *)(&cache->sidCacheSets ) += ptr;
    *(ptrdiff_t *)(&cache->sidCacheData ) += ptr;
    *(ptrdiff_t *)(&cache->certCacheData) += ptr;
    *(ptrdiff_t *)(&cache->keyCacheData ) += ptr;
    *(ptrdiff_t *)(&cache->ticketKeyNameSuffix) += ptr;
    *(ptrdiff_t *)(&cache->ticketEncKey ) += ptr;
    *(ptrdiff_t *)(&cache->ticketMacKey ) += ptr;
    *(ptrdiff_t *)(&cache->ticketKeysValid) += ptr;
    *(ptrdiff_t *)(&cache->srvNameCacheData) += ptr;

    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);
    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_Time();
	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       = getenv("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      *
 ************************************************************************/

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

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

PRBool
ssl_GetWrappingKey( PRInt32                   symWrapMechIndex,
                    SSL3KEAType               exchKeyType, 
		    SSLWrappedSymWrappingKey *wswk)
{
    PRBool rv;

    PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
    PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
    if ((unsigned)exchKeyType < kt_kea_size &&
        (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS) {
	rv = getSvrWrappingKey(symWrapMechIndex, exchKeyType, wswk, 
	                       &globalCache, 0);
    } else {
    	rv = PR_FALSE;
    }

    return rv;
}

/* Wrap and cache a session ticket key. */
static PRBool
WrapTicketKey(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 session ticket %s.",
		    SSL_GETPID(), "unknown", keyName));
	return PR_FALSE;
    }
    cacheEntry->length = wrappedKey.len;
    return PR_TRUE;
}

static PRBool
GenerateTicketKeys(void *pwArg, unsigned char *keyName, PK11SymKey **aesKey,
                   PK11SymKey **macKey)
{
    PK11SlotInfo *slot;
    CK_MECHANISM_TYPE mechanismArray[2];
    PK11SymKey *aesKeyTmp = NULL;
    PK11SymKey *macKeyTmp = NULL;
    cacheDesc *cache = &globalCache;
    PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_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,
	    SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess) {
	SSL_DBG(("%d: SSL[%s]: Unable to generate random key name bytes.",
		    SSL_GETPID(), "unknown"));
	goto loser;
    }

    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, SESS_TICKET_KEY_VAR_NAME_LEN);
    *aesKey = aesKeyTmp;
    *macKey = macKeyTmp;
    return PR_TRUE;

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

static PRBool
GenerateAndWrapTicketKeys(SECKEYPublicKey *svrPubKey, void *pwArg,
                          unsigned char *keyName, PK11SymKey **aesKey,
                          PK11SymKey **macKey)
{
    PK11SymKey *aesKeyTmp = NULL;
    PK11SymKey *macKeyTmp = NULL;
    cacheDesc *cache = &globalCache;

    if (!GenerateTicketKeys(pwArg, keyName, &aesKeyTmp, &macKeyTmp)) {
        goto loser;
    }

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

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

static PRBool
UnwrapCachedTicketKeys(SECKEYPrivateKey *svrPrivKey, unsigned char *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,
	SESS_TICKET_KEY_VAR_NAME_LEN);
    *aesKey = aesKeyTmp;
    *macKey = macKeyTmp;
    return PR_TRUE;

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

PRBool
ssl_GetSessionTicketKeysPKCS11(SECKEYPrivateKey *svrPrivKey,
                               SECKEYPublicKey *svrPubKey, void *pwArg,
                               unsigned char *keyName, PK11SymKey **aesKey,
                               PK11SymKey **macKey)
{
    PRUint32 now = 0;
    PRBool rv = PR_FALSE;
    PRBool keysGenerated = PR_FALSE;
    cacheDesc *cache = &globalCache;

    if (!cache->cacheMem) {
        /* cache is uninitialized. Generate keys and return them
         * without caching. */
        return GenerateTicketKeys(pwArg, keyName, aesKey, macKey);
    }

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

    if (!*(cache->ticketKeysValid)) {
	/* Keys do not exist, create them. */
	if (!GenerateAndWrapTicketKeys(svrPubKey, pwArg, keyName,
		aesKey, macKey))
	    goto loser;
	keysGenerated = PR_TRUE;
	*(cache->ticketKeysValid) = 1;
    }

    rv = PR_TRUE;

 loser:
    UnlockSidCacheLock(cache->keyCacheLock);
    if (rv && !keysGenerated)
	rv = UnwrapCachedTicketKeys(svrPrivKey, keyName, aesKey, macKey);
    return rv;
}

PRBool
ssl_GetSessionTicketKeys(unsigned char *keyName, unsigned char *encKey,
                         unsigned char *macKey)
{
    PRBool rv = PR_FALSE;
    PRUint32 now = 0;
    cacheDesc *cache = &globalCache;
    PRUint8 ticketMacKey[SHA256_LENGTH], ticketEncKey[AES_256_KEY_LENGTH];
    PRUint8 ticketKeyNameSuffixLocal[SESS_TICKET_KEY_VAR_NAME_LEN];
    PRUint8 *ticketMacKeyPtr, *ticketEncKeyPtr, *ticketKeyNameSuffix;
    PRBool cacheIsEnabled = PR_TRUE;

    if (!cache->cacheMem) { /* cache is uninitialized */
        cacheIsEnabled = PR_FALSE;
        ticketKeyNameSuffix = ticketKeyNameSuffixLocal;
        ticketEncKeyPtr = ticketEncKey;
        ticketMacKeyPtr = ticketMacKey;
    } else {
        /* these values have constant memory locations in the cache.
         * Ok to reference them without holding the lock. */
        ticketKeyNameSuffix = cache->ticketKeyNameSuffix;
        ticketEncKeyPtr = cache->ticketEncKey->bytes;
        ticketMacKeyPtr = cache->ticketMacKey->bytes;
    }

    if (cacheIsEnabled) {
        /* Grab lock if initialized. */
        now = LockSidCacheLock(cache->keyCacheLock, now);
        if (!now)
            return rv;
    }
    /* Going to regenerate keys on every call if cache was not
     * initialized. */
    if (!cacheIsEnabled || !*(cache->ticketKeysValid)) {
	if (PK11_GenerateRandom(ticketKeyNameSuffix,
		SESS_TICKET_KEY_VAR_NAME_LEN) != SECSuccess)
	    goto loser;
	if (PK11_GenerateRandom(ticketEncKeyPtr,
                                AES_256_KEY_LENGTH) != SECSuccess)
	    goto loser;
	if (PK11_GenerateRandom(ticketMacKeyPtr,
                                SHA256_LENGTH) != SECSuccess)
	    goto loser;
        if (cacheIsEnabled) {
            *(cache->ticketKeysValid) = 1;
        }
    }

    rv = PR_TRUE;

 loser:
    if (cacheIsEnabled) {
        UnlockSidCacheLock(cache->keyCacheLock);
    }
    if (rv) {
	PORT_Memcpy(keyName, ticketKeyNameSuffix,
                    SESS_TICKET_KEY_VAR_NAME_LEN);
	PORT_Memcpy(encKey, ticketEncKeyPtr, AES_256_KEY_LENGTH);
	PORT_Memcpy(macKey, ticketMacKeyPtr, SHA256_LENGTH);
    }
    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.
 */
PRBool
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
{
    cacheDesc *   cache            = &globalCache;
    PRBool        rv               = PR_FALSE;
    SSL3KEAType   exchKeyType      = wswk->exchKeyType;   
                                /* type of keys used to wrap SymWrapKey*/
    PRInt32       symWrapMechIndex = wswk->symWrapMechIndex;
    PRUint32      ndx;
    PRUint32      now = 0;
    SSLWrappedSymWrappingKey myWswk;

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

    PORT_Assert( (unsigned)exchKeyType < kt_kea_size);
    if ((unsigned)exchKeyType >= kt_kea_size)
    	return 0;

    PORT_Assert( (unsigned)symWrapMechIndex < SSL_NUM_WRAP_MECHS);
    if ((unsigned)symWrapMechIndex >=  SSL_NUM_WRAP_MECHS)
    	return 0;

    ndx = (exchKeyType * SSL_NUM_WRAP_MECHS) + symWrapMechIndex;
    PORT_Memset(&myWswk, 0, sizeof myWswk);	/* eliminate UMRs. */

    now = LockSidCacheLock(cache->keyCacheLock, now);
    if (now) {
	rv = getSvrWrappingKey(wswk->symWrapMechIndex, wswk->exchKeyType, 
	                       &myWswk, cache, now);
	if (rv) {
	    /* 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;
}

PRBool
ssl_GetWrappingKey( PRInt32                   symWrapMechIndex,
                    SSL3KEAType               exchKeyType, 
		    SSLWrappedSymWrappingKey *wswk)
{
    PRBool rv = PR_FALSE;
    PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_GetWrappingKey)");    
    return rv;
}

/* 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.
 */
PRBool
ssl_SetWrappingKey(SSLWrappedSymWrappingKey *wswk)
{
    PRBool        rv = PR_FALSE;
    PR_ASSERT(!"SSL servers are not supported on this platform. (ssl_SetWrappingKey)");
    return rv;
}

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